API
Script against your firm’s boards, issues, and merge requests. Read-only and token-authed.
The API is available on Pro and Team. Read on to see what it offers — the reference below is the whole of it.
See pricing →Quickstart
- Mint an API token in your firm's settings (Settings → API access). Copy it once — it starts with ggb_ and is shown only at creation.
- Send it as a Bearer token on every request; it is scoped to the firm you minted it in.
curl -H "Authorization: Bearer ggb_..." https://gitgumbo.com/api/v1/me
Endpoints
Every endpoint in v1. Generated from the same OpenAPI document served at /api/v1/openapi.json, so this page and the spec can never disagree.
GET/api/v1/me
Current token, firm, and rate-limit status
Returns Me · Errors 401, 402, 429
GET/api/v1/projects
List the firm's monitored projects
| Parameter | In | Type | Required |
|---|---|---|---|
| cursor | query | string | no |
| limit | query | integer | no |
Returns Page<Project> · Errors 401, 402, 429
GET/api/v1/projects/{id}
Get one project
| Parameter | In | Type | Required |
|---|---|---|---|
| id | path | string | yes |
Returns Project · Errors 401, 402, 404, 429
GET/api/v1/projects/{id}/issues
List issues in a project
| Parameter | In | Type | Required |
|---|---|---|---|
| id | path | string | yes |
| cursor | query | string | no |
| limit | query | integer | no |
| state | query | "opened" | "closed" | "all" | no |
| label | query | string | no |
| labelMatch | query | "any" | "all" | no |
| assignee | query | string | no |
| updatedSince | query | string | no |
Returns Page<Issue> · Errors 401, 402, 404, 429
GET/api/v1/projects/{id}/merge-requests
List merge requests in a project
| Parameter | In | Type | Required |
|---|---|---|---|
| id | path | string | yes |
| cursor | query | string | no |
| limit | query | integer | no |
| state | query | string | no |
| draft | query | boolean | no |
| author | query | string | no |
| reviewer | query | string | no |
Returns Page<Mr> · Errors 401, 402, 404, 429
GET/api/v1/projects/{id}/labels
List labels in a project
| Parameter | In | Type | Required |
|---|---|---|---|
| id | path | string | yes |
| cursor | query | string | no |
| limit | query | integer | no |
Returns Page<Label> · Errors 401, 402, 404, 429
GET/api/v1/projects/{id}/board
The derived board — columns and the open issues bucketed into each
Open issues only, capped at 2000 (truncated=true when exceeded). GitLab-derived; board is null for GitHub and custom boards.
| Parameter | In | Type | Required |
|---|---|---|---|
| id | path | string | yes |
| assignee | query | string | no |
| label | query | string | no |
| labelMatch | query | "any" | "all" | no |
| search | query | string | no |
| draft | query | boolean | no |
| hasConflicts | query | boolean | no |
| pipelineFailed | query | boolean | no |
| unresolvedThreads | query | boolean | no |
| board | query | string | no |
Returns BoardResponse · Errors 401, 402, 404, 429
The board
The differentiator: GitGumbo’s derived board — columns and the open issues bucketed into each, filterable, that no provider API exposes. GitLab-derived (null for GitHub / custom boards).
curl -H "Authorization: Bearer ggb_..." "https://gitgumbo.com/api/v1/projects/<id>/board?assignee=me"
A response. Columns carry their bucketed open issues, and each issue carries the merge requests linked to it — the join no provider API gives you in one call.
{
"board": {
"remoteBoardId": "1042",
"name": "Development",
"assigneeUsername": null
},
"columns": [
{
"name": "In Progress",
"type": "label",
"labels": [
"Stage::In Progress"
],
"match": null,
"color": "#1f75cb",
"wipLimit": 3,
"issues": [
{
"number": 318,
"title": "Re-key webhook registrations when a project is transferred",
"state": "opened",
"webUrl": "https://gitlab.com/acme/platform/-/issues/318",
"labels": [
"Stage::In Progress",
"backend"
],
"assignees": [
{
"username": "rmedina",
"name": "Robin Medina",
"avatarUrl": "https://gitlab.com/uploads/-/system/user/avatar/4471/avatar.png"
}
],
"authorName": "Robin Medina",
"authorUsername": "rmedina",
"remoteCreatedAt": "2026-07-19T09:14:02.000Z",
"remoteUpdatedAt": "2026-07-27T16:41:55.000Z",
"dueDate": "2026-08-04T00:00:00.000Z",
"milestoneTitle": "14.2",
"milestoneDueDate": "2026-08-15T00:00:00.000Z",
"statusName": "In progress",
"statusCategory": "in_progress",
"linkedMergeRequests": [
{
"number": 902,
"title": "Re-key WebhookRegistration onto (provider, remoteProjectId)",
"state": "opened",
"draft": false,
"webUrl": "https://gitlab.com/acme/platform/-/merge_requests/902",
"pipelineStatus": "success",
"reviewState": "pending"
}
]
}
]
},
{
"name": "In Review",
"type": "label",
"labels": [
"Stage::In Review"
],
"match": null,
"color": "#ab6100",
"wipLimit": null,
"issues": [
{
"number": 305,
"title": "Collapsed columns should flag hidden search matches",
"state": "opened",
"webUrl": "https://gitlab.com/acme/platform/-/issues/305",
"labels": [
"Stage::In Review",
"frontend"
],
"assignees": [
{
"username": "dpatel",
"name": "Dana Patel",
"avatarUrl": null
}
],
"authorName": "Sam Okafor",
"authorUsername": "sokafor",
"remoteCreatedAt": "2026-07-11T13:02:44.000Z",
"remoteUpdatedAt": "2026-07-28T08:19:07.000Z",
"dueDate": null,
"milestoneTitle": "14.2",
"milestoneDueDate": "2026-08-15T00:00:00.000Z",
"statusName": "In review",
"statusCategory": "in_progress",
"linkedMergeRequests": [
{
"number": 897,
"title": "Flag search matches inside collapsed columns",
"state": "opened",
"draft": false,
"webUrl": "https://gitlab.com/acme/platform/-/merge_requests/897",
"pipelineStatus": "running",
"reviewState": "approved"
}
]
}
]
},
{
"name": "Open",
"type": "label",
"labels": [],
"match": null,
"color": null,
"wipLimit": null,
"issues": []
}
],
"truncated": false
}Conventions
- Base URL
- All endpoints live under https://gitgumbo.com/api/v1. The API is read-only and requires a Pro or Team plan.
- Authentication
- Send your token in the Authorization header: Authorization: Bearer ggb_... . There is no cookie/session fallback; a missing, revoked, or expired token returns 401.
- Pagination
- List endpoints return { data, nextCursor }. Pass ?cursor=<nextCursor> for the next page and ?limit= (1-100, default 50) to size it. A null nextCursor means the end.
- Errors
- Errors return { error: { code, message } }. 401 = auth, 402 api_requires_pro = your plan has no API access, 404 = not found or not in your firm, 429 = rate limited (with Retry-After).
- Rate limits
- Limits are per firm by plan (Pro 1,000/hr, Team 5,000/hr). Every response carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset.
Pagination in practice
Every list endpoint returns the same envelope. Pass the nextCursor back as ?cursor= until it comes back null.
{
"data": [
{
"id": "clz8k2q0h0001s6mf4c9x2b7d",
"remoteProjectId": "58210447",
"provider": "gitlab",
"name": "platform",
"nameWithNamespace": "Acme / platform",
"pathWithNamespace": "acme/platform",
"webUrl": "https://gitlab.com/acme/platform",
"boardMode": "custom",
"syncEnabled": true,
"lastSyncAt": "2026-07-28T08:25:11.000Z"
},
{
"id": "clz8k2q0h0002s6mfa1p7q4we",
"remoteProjectId": "742119058",
"provider": "github",
"name": "acme-web",
"nameWithNamespace": "acme/acme-web",
"pathWithNamespace": "acme/acme-web",
"webUrl": "https://github.com/acme/acme-web",
"boardMode": "auto",
"syncEnabled": true,
"lastSyncAt": "2026-07-28T08:24:58.000Z"
}
],
"nextCursor": "clz8k2q0h0002s6mfa1p7q4we"
}Schemas
The object shapes the endpoints above return.
Person
| Field | Type | Nullable |
|---|---|---|
| username | string | yes |
| name | string | yes |
| avatarUrl | string | yes |
Project
| Field | Type | Nullable |
|---|---|---|
| id | string | no |
| remoteProjectId | string | no |
| provider | string | no |
| name | string | no |
| nameWithNamespace | string | yes |
| pathWithNamespace | string | yes |
| webUrl | string | no |
| boardMode | string | no |
| syncEnabled | boolean | no |
| lastSyncAt | string | yes |
MrCompact
| Field | Type | Nullable |
|---|---|---|
| number | integer | no |
| title | string | no |
| state | string | no |
| draft | boolean | no |
| webUrl | string | no |
| pipelineStatus | string | yes |
| reviewState | string | yes |
Mr
| Field | Type | Nullable |
|---|---|---|
| number | integer | no |
| title | string | no |
| state | string | no |
| draft | boolean | no |
| webUrl | string | no |
| pipelineStatus | string | yes |
| reviewState | string | yes |
| sourceBranch | string | yes |
| targetBranch | string | yes |
| authorName | string | yes |
| authorUsername | string | yes |
| authorAvatarUrl | string | yes |
| hasConflicts | boolean | no |
| mergeStatus | string | yes |
| reviewers | Person[] | no |
| approvedBy | Person[] | no |
| changesRequestedBy | Person[] | no |
| unresolvedThreads | integer | no |
| labels | string[] | no |
| remoteCreatedAt | string | yes |
| remoteUpdatedAt | string | yes |
| lastCommitAt | string | yes |
Issue
| Field | Type | Nullable |
|---|---|---|
| number | integer | no |
| title | string | no |
| state | string | no |
| webUrl | string | no |
| labels | string[] | no |
| assignees | Person[] | no |
| authorName | string | yes |
| authorUsername | string | yes |
| remoteCreatedAt | string | yes |
| remoteUpdatedAt | string | yes |
| dueDate | string | yes |
| milestoneTitle | string | yes |
| milestoneDueDate | string | yes |
| statusName | string | yes |
| statusCategory | string | yes |
| linkedMergeRequests | MrCompact[] | no |
Label
| Field | Type | Nullable |
|---|---|---|
| name | string | no |
| color | string | no |
BoardColumn
| Field | Type | Nullable |
|---|---|---|
| name | string | no |
| type | "label" | "assignee" | "milestone" | "status" | no |
| labels | string[] | no |
| match | string | yes |
| color | string | yes |
| wipLimit | integer | yes |
| issues | Issue[] | no |
BoardSummary
| Field | Type | Nullable |
|---|---|---|
| remoteBoardId | string | no |
| name | string | no |
| assigneeUsername | string | yes |
Me
| Field | Type | Nullable |
|---|---|---|
| firm | { id, name, plan } | no |
| token | { name, scopes } | no |
| rateLimit | { limit, remaining, reset } | no |
Error
| Field | Type | Nullable |
|---|---|---|
| error | { code, message } | no |
BoardResponse
| Field | Type | Nullable |
|---|---|---|
| board | BoardSummary | yes |
| columns | BoardColumn[] | no |
| truncated | boolean | no |
Full reference
Everything above, machine-readable. Import it into Postman or any OpenAPI tool, or hand it to your codegen / AI client generator.