API reference
Gluecron exposes a REST API at /api/v2/. All endpoints return JSON. Authenticated endpoints require a Bearer token in the Authorization header.
Authentication
Generate a personal access token at /settings/tokens. Tokens start with glc_ and are hashed (SHA-256) before storage — the plaintext is shown exactly once.
curl -H "Authorization: Bearer glc_your_token_here" \
https://gluecron.com/api/v2/reposTokens can also authenticate git over HTTPS — use the token as the password with any username.
Rate limits
| Surface | Limit | Window |
|---|---|---|
| API (anonymous) | 1 000 requests | 60 seconds |
| API (authenticated) | 4 000 requests | 60 seconds |
| AI commit message | 60 requests | 60 seconds per token |
| Login / register | 10–20 requests | 60 seconds per IP |
When a limit is exceeded the server returns 429 Too Many Requests with a Retry-After header.
Repositories
List your repos
GET /api/v2/repos
Response 200:
[
{
"id": "...",
"name": "my-project",
"fullName": "you/my-project",
"description": "...",
"isPrivate": false,
"defaultBranch": "main",
"starCount": 12,
"forkCount": 3,
"issueCount": 5,
"createdAt": "2025-01-15T10:00:00Z",
"updatedAt": "2025-06-01T14:30:00Z"
}
]Create a repo
POST /api/v2/repos
Content-Type: application/json
{
"name": "my-project",
"description": "Optional description",
"isPrivate": false,
"initReadme": true,
"defaultBranch": "main"
}
Response 201:
{ "id": "...", "name": "my-project", "fullName": "you/my-project" }Get a repo
GET /api/v2/repos/:owner/:repo
Response 200:
{ /* same shape as list item */ }Delete a repo
DELETE /api/v2/repos/:owner/:repo
Response 204 No ContentIssues
List issues
GET /api/v2/repos/:owner/:repo/issues?state=open&limit=25
Response 200:
[
{
"number": 42,
"title": "Bug in auth flow",
"body": "...",
"state": "open",
"author": "kit",
"createdAt": "2025-05-20T08:00:00Z"
}
]Create an issue
POST /api/v2/repos/:owner/:repo/issues
Content-Type: application/json
{
"title": "Bug in auth flow",
"body": "Steps to reproduce: ..."
}
Response 201:
{ "number": 42, "url": "/you/my-project/issues/42" }Close / reopen an issue
PATCH /api/v2/repos/:owner/:repo/issues/:number
Content-Type: application/json
{ "state": "closed" } // or "open"
Response 200:
{ "state": "closed" }Pull requests
List PRs
GET /api/v2/repos/:owner/:repo/pulls?state=open
Response 200:
[
{
"number": 17,
"title": "Add rate limiter",
"state": "open",
"baseBranch": "main",
"headBranch": "feat/rate-limit",
"isDraft": false,
"author": "kit",
"createdAt": "2025-06-01T09:00:00Z"
}
]Create a PR
POST /api/v2/repos/:owner/:repo/pulls
Content-Type: application/json
{
"title": "Add rate limiter",
"body": "## Summary
- Implements token-bucket rate limiter
## Test plan
- [ ] Run bun test",
"headBranch": "feat/rate-limit",
"baseBranch": "main"
}
Response 201:
{ "number": 17, "url": "/you/my-project/pulls/17" }Merge a PR
POST /api/v2/repos/:owner/:repo/pulls/:number/merge
Response 200:
{ "merged": true, "sha": "a3f9c2d..." }
// If gate checks fail:
Response 422:
{ "merged": false, "reason": "GateTest: leaked secret in src/config.ts" }
// If the pre-merge risk score is critical, the merge soft-blocks:
Response 422:
{ "merged": false, "reason": "risk score is critical (9/10) — ...", "riskScore": { ... } }
// Confirm past the soft-block with an optional JSON body:
{ "confirmHighRisk": true }Deploy keys and deploy tokens
Credentials scoped to one repository, for a build box, a deploy target or a mirror job — read-only unless you ask for write. Repository admin access is required to manage them (Settings → Deploy keys). A deploy token is the HTTPS form and works on every instance; a deploy key is an SSH public key and needs the instance's SSH port to be published. Both record when and from where they were last used.
Create a deploy token and clone with it
POST /api/v2/repos/:owner/:repo/deploy-tokens
Content-Type: application/json
{ "title": "ci runner", "read_only": true, "expires_at": "2027-01-01T00:00:00Z" }
Response 201 (the "token" field is shown here and never again):
{ "id": "...", "title": "ci runner", "token_prefix": "gcdt_1a2b3c4d",
"read_only": true, "token": "gcdt_…", "last_used_at": null }
git clone https://deploy:gcdt_…@gluecron.com/:owner/:repo.git
A push with a read-only token answers 403 naming the token; create one
with "read_only": false for a job that must push.
GET /api/v2/repos/:owner/:repo/deploy-tokens list (never includes the secret)
DELETE /api/v2/repos/:owner/:repo/deploy-tokens/:id revoke — clones stop at the next fetchAdd a deploy key (SSH)
POST /api/v2/repos/:owner/:repo/keys
Content-Type: application/json
{ "title": "prod deploy box", "key": "ssh-ed25519 AAAA… comment", "read_only": true }
Response 201:
{ "id": "...", "fingerprint": "SHA256:…", "read_only": true, "last_used_at": null }
422 when the key is already a deploy key elsewhere or a user's SSH key —
a deploy key attaches to exactly one repository.
GET /api/v2/repos/:owner/:repo/keys list
DELETE /api/v2/repos/:owner/:repo/keys/:id removeRepository tokens (fine-grained)
A token for one repository that works on the REST API (/api/v2 and the GitHub-compatible /api/v3) and on git over HTTPS, with a none / read / write level for each ofcontents, issues, pull_requests,statuses and actions. Admin and settings can never be granted. It also pushes and pulls the repository's container images (docker login, then :owner/:repo) withcontents read or write. An expiry is optional: leave it out for a token that works until revoked, or give 5 minutes to 1 year. The token never does more than the person who made it: its levels are held to that person's current access to the repository on every use, so if they lose access the token does too. Branch protection, rulesets and merge gates apply to it as they apply to that person. Create them at /settings/repo-tokens, over the API below, or with the gluecron_create_repo_token MCP tool.
POST /api/v2/user/repo-tokens
Content-Type: application/json
{ "owner": ":owner", "repo": ":repo", "name": "deploy box",
"permissions": { "actions": "read" } } (add "expires_in": "90d" for an expiry)
Response 201 (the "token" field is shown here and never again):
{ "id": "...", "repository": ":owner/:repo", "tokenPrefix": "gcft_1a2b3c4",
"permissions": { "contents": "none", "issues": "none", "pull_requests": "none",
"statuses": "none", "actions": "read" },
"state": "active", "expiresAt": null, "token": "gcft_…" }
curl -H "Authorization: Bearer gcft_…" https://gluecron.com/api/v2/repos/:owner/:repo/actions/runs
git clone https://x:gcft_…@gluecron.com/:owner/:repo.git (needs contents: read; push needs write)
403 on any other repository, on a route the token's permissions do not cover,
and on every account, admin, settings or MCP route; 401 once it has expired
or been revoked.
GET /api/v2/user/repo-tokens list yours (never the secret)
DELETE /api/v2/user/repo-tokens/:id revoke — the next request with it is refusedWebhooks
Register a webhook
POST /api/v2/repos/:owner/:repo/webhooks
Content-Type: application/json
{
"url": "https://example.com/hooks/gluecron",
"secret": "mysecret",
"events": "push,pr,issue,star,workflow_run"
}
// GitHub-compatible format: GitHub's events, headers and payloads.
{
"url": "https://example.com/github-receiver",
"secret": "mysecret",
"format": "github", // "gluecron" (default) | "github"
"content_type": "json", // "json" (default) | "form"
"events": ["push", "pull_request", "workflow_run", "issue_comment"] // or ["*"]
}
Response 201: the stored webhook row (a github hook is sent "ping" at once)Gluecron format (default)
// push
{ "branch": "main", "oldSha": "<sha>", "newSha": "<sha>" }
// pr / issue
{ "action": "opened" | "closed" | "merged" | "reopened" | "commented", "number": 12 }
X-Gluecron-Event: push
X-Gluecron-Delivery: <uuid>
X-Gluecron-Signature: sha256=<hex> // HMAC-SHA256 of the raw body
X-Gluecron-Timestamp + X-Gluecron-Signature-Timestamped // replay-resistantGitHub format
Events: ping, push, create, delete, pull_request, pull_request_review,
pull_request_review_comment, issue_comment, issues, workflow_run,
workflow_job, status, release, star — GitHub's documented payloads
(repository, sender, ref/before/after/commits/head_commit/forced …).
X-GitHub-Event: push
X-GitHub-Delivery: <uuid>
X-Hub-Signature-256: sha256=<hex> // verify exactly as for GitHub
X-Hub-Signature: sha1=<hex>
User-Agent: Gluecron-Hookshot/1
(plus the X-Gluecron-* headers above)
Ids are Gluecron UUIDs, matching the /api/v3 compatibility API.
No check_suite: Gluecron has no Checks API (CI is workflow_run + status).AI endpoints
Generate a commit message
POST /api/v2/ai/commit-message
Content-Type: application/json
{ "diff": "<git diff output>" }
Response 200:
{
"message": "feat(auth): add token-bucket rate limiter\n\nPrevents brute-force login attempts..."
}Semantic code search
GET /api/v2/repos/:owner/:repo/semantic-search?q=password+hashing&limit=10
Response 200:
[
{
"path": "src/lib/auth.ts",
"startLine": 12,
"endLine": 28,
"snippet": "...",
"score": 0.94
}
]