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

  1. 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.
  2. 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

ParameterInTypeRequired
cursorquerystringno
limitqueryintegerno

Returns Page<Project> · Errors 401, 402, 429

GET/api/v1/projects/{id}

Get one project

ParameterInTypeRequired
idpathstringyes

Returns Project · Errors 401, 402, 404, 429

GET/api/v1/projects/{id}/issues

List issues in a project

ParameterInTypeRequired
idpathstringyes
cursorquerystringno
limitqueryintegerno
statequery"opened" | "closed" | "all"no
labelquerystringno
labelMatchquery"any" | "all"no
assigneequerystringno
updatedSincequerystringno

Returns Page<Issue> · Errors 401, 402, 404, 429

GET/api/v1/projects/{id}/merge-requests

List merge requests in a project

ParameterInTypeRequired
idpathstringyes
cursorquerystringno
limitqueryintegerno
statequerystringno
draftquerybooleanno
authorquerystringno
reviewerquerystringno

Returns Page<Mr> · Errors 401, 402, 404, 429

GET/api/v1/projects/{id}/labels

List labels in a project

ParameterInTypeRequired
idpathstringyes
cursorquerystringno
limitqueryintegerno

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.

ParameterInTypeRequired
idpathstringyes
assigneequerystringno
labelquerystringno
labelMatchquery"any" | "all"no
searchquerystringno
draftquerybooleanno
hasConflictsquerybooleanno
pipelineFailedquerybooleanno
unresolvedThreadsquerybooleanno
boardquerystringno

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

FieldTypeNullable
usernamestringyes
namestringyes
avatarUrlstringyes

Project

FieldTypeNullable
idstringno
remoteProjectIdstringno
providerstringno
namestringno
nameWithNamespacestringyes
pathWithNamespacestringyes
webUrlstringno
boardModestringno
syncEnabledbooleanno
lastSyncAtstringyes

MrCompact

FieldTypeNullable
numberintegerno
titlestringno
statestringno
draftbooleanno
webUrlstringno
pipelineStatusstringyes
reviewStatestringyes

Mr

FieldTypeNullable
numberintegerno
titlestringno
statestringno
draftbooleanno
webUrlstringno
pipelineStatusstringyes
reviewStatestringyes
sourceBranchstringyes
targetBranchstringyes
authorNamestringyes
authorUsernamestringyes
authorAvatarUrlstringyes
hasConflictsbooleanno
mergeStatusstringyes
reviewersPerson[]no
approvedByPerson[]no
changesRequestedByPerson[]no
unresolvedThreadsintegerno
labelsstring[]no
remoteCreatedAtstringyes
remoteUpdatedAtstringyes
lastCommitAtstringyes

Issue

FieldTypeNullable
numberintegerno
titlestringno
statestringno
webUrlstringno
labelsstring[]no
assigneesPerson[]no
authorNamestringyes
authorUsernamestringyes
remoteCreatedAtstringyes
remoteUpdatedAtstringyes
dueDatestringyes
milestoneTitlestringyes
milestoneDueDatestringyes
statusNamestringyes
statusCategorystringyes
linkedMergeRequestsMrCompact[]no

Label

FieldTypeNullable
namestringno
colorstringno

BoardColumn

FieldTypeNullable
namestringno
type"label" | "assignee" | "milestone" | "status"no
labelsstring[]no
matchstringyes
colorstringyes
wipLimitintegeryes
issuesIssue[]no

BoardSummary

FieldTypeNullable
remoteBoardIdstringno
namestringno
assigneeUsernamestringyes

Me

FieldTypeNullable
firm{ id, name, plan }no
token{ name, scopes }no
rateLimit{ limit, remaining, reset }no

Error

FieldTypeNullable
error{ code, message }no

BoardResponse

FieldTypeNullable
boardBoardSummaryyes
columnsBoardColumn[]no
truncatedbooleanno

Full reference

Everything above, machine-readable. Import it into Postman or any OpenAPI tool, or hand it to your codegen / AI client generator.