34 endpoints. Send your API key as Authorization: Bearer <key> on each request; see The API and AI assistants for keys, errors, idempotency and the conventions every endpoint shares.
POST /api/organisation/export
Download the organisation's data as a JSON file (owners and admins)
Settings, members, invitations, API key labels, secret names, projects, phases, tasks, subtasks, issues with their events, and activity. Secret values, keys and ingest keys are never included. The current password is required again; the ten attempts per hour are shared with the personal export.
Request body (application/json, required).
| Field | Type | Required | Description |
|---|---|---|---|
current_password | string | Yes |
Responses:
| Status | Meaning |
|---|---|
| 200 | The file |
| 400 | Current password wrong |
| 403 | Only owners and admins |
| 429 | Too many attempts |
POST /api/organisation/delete-request
Start deleting the organisation (owners only); a one-hour link goes to your address
Needs the current password, the authenticator or recovery code when two-factor is on, and the organisation's name typed exactly. Refused for organisation 1 and while a Stripe subscription is active, trialing or past due (cancel it in Billing first; the app never changes Stripe). Ten attempts an hour, shared with exports and account deletion. The organisation is deleted only when the emailed link's button is used, at once and for good.
Request body (application/json, required).
| Field | Type | Required | Description |
|---|---|---|---|
current_password | string | Yes | |
code | string | No | |
confirm_name | string | Yes |
Responses:
| Status | Meaning |
|---|---|
| 202 | The link is on its way |
| 400 | Password |
| 403 | Only an owner signed in as themselves can do this |
| 409 | Organisation 1 |
| 429 | Too many attempts |
POST /api/projects/{id}/enable
Switch a project on (admins); needs room under the plan
Projects switched off because the organisation is over its plan are read-only. Switching one on needs fewer active projects than the plan allows; switch another off first, or upgrade.
Parameters:
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | integer | Yes |
Responses:
| Status | Meaning |
|---|---|
| 200 | The project |
| 404 | Not found |
| 409 | The plan has no room for another active project |
POST /api/projects/{id}/disable
Switch a project off (admins); it becomes read-only
Parameters:
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | integer | Yes |
Responses:
| Status | Meaning |
|---|---|
| 200 | The project |
| 404 | Not found |
POST /api/members/{userId}/enable
Switch a member on (owners); needs room under the plan
Parameters:
| Name | In | Type | Required | Description |
|---|---|---|---|---|
userId | path | integer | Yes |
Responses:
| Status | Meaning |
|---|---|
| 200 | The member |
| 404 | Not found |
| 409 | The plan has no room for another active member |
POST /api/members/{userId}/disable
Switch a member off (owners); they cannot use the organisation until switched on
Owners and viewers cannot be switched off. The member's sessions end; their account and work stay.
Parameters:
| Name | In | Type | Required | Description |
|---|---|---|---|---|
userId | path | integer | Yes |
Responses:
| Status | Meaning |
|---|---|
| 200 | The member |
| 404 | Not found |
| 409 | An owner or a viewer |
GET /api/members
People in this organisation, with their roles
Responses:
| Status | Meaning |
|---|---|
| 200 | Members (user_id |
PATCH /api/members/{userId}
Change a member's role (admin or owner; only owners touch ownership; the last owner stays)
Parameters:
| Name | In | Type | Required | Description |
|---|---|---|---|---|
userId | path | integer | Yes | From 1 to .... |
Request body (application/json, required).
| Field | Type | Required | Description |
|---|---|---|---|
role | string | Yes | One of: owner, admin, member, viewer. |
Responses:
| Status | Meaning |
|---|---|
| 200 | Changed |
| 403 | Not allowed for your role |
| 404 | Not a member of this organisation |
| 409 | Would leave the organisation without an owner |
DELETE /api/members/{userId}
Remove a member (admins), or leave (your own id); their sessions here end
Parameters:
| Name | In | Type | Required | Description |
|---|---|---|---|---|
userId | path | integer | Yes | From 1 to .... |
Responses:
| Status | Meaning |
|---|---|
| 204 | Removed |
| 409 | Would leave the organisation without an owner |
GET /api/invitations
Open invitations (admins)
Responses:
| Status | Meaning |
|---|---|
| 200 | Invitations |
POST /api/invitations
Email an invitation (admins; only owners invite owners). Works once, for 7 days.
Request body (application/json, required).
| Field | Type | Required | Description |
|---|---|---|---|
email | string (email) | Yes | |
role | string | Yes | One of: owner, admin, member, viewer. |
Responses:
| Status | Meaning |
|---|---|
| 201 | Sent |
| 400 | Invalid |
DELETE /api/invitations/{id}
Cancel an open invitation (admins)
Parameters:
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | integer | Yes | From 1 to 2147483647. |
Responses:
| Status | Meaning |
|---|---|
| 204 | Cancelled |
POST /auth/invitation
What an invitation token is for (organisation, email, role, inviter, whether the address has an account)
Request body (application/json, required).
| Field | Type | Required | Description |
|---|---|---|---|
token | string | Yes |
Responses:
| Status | Meaning |
|---|---|
| 200 | Invitation details |
| 400 | Invalid or expired |
POST /auth/invitation/accept
Accept an invitation and sign in to the organisation
A new address sends name, password and over_18 true (the time of that confirmation is stored on the account; no date of birth is asked for). An existing account must be signed in as that address (401 with sign_in_required otherwise).
Request body (application/json, required).
| Field | Type | Required | Description |
|---|---|---|---|
token | string | Yes | |
name | string | No | |
password | string | No | At least 10 characters. |
over_18 | boolean | No | Must be true for a new account: the person confirms they are 18 or over. |
Responses:
| Status | Meaning |
|---|---|
| 200 | Joined and signed in |
| 400 | Invalid or expired |
| 401 | Sign in as the invited address first |
GET /api/api-keys
Your keys in this organisation (admins see everyone's). Never the key itself.
Responses:
| Status | Meaning |
|---|---|
| 200 | Keys with label |
POST /api/api-keys
Make a key (signed-in members; role at most yours). The key is in the response once.
Request body (application/json, required).
| Field | Type | Required | Description |
|---|---|---|---|
label | string | Yes | Up to 100 characters. |
role | string | No | One of: admin, member, viewer. Default "member". |
Responses:
| Status | Meaning |
|---|---|
| 201 | The key, in key |
| 403 | Not signed in as a person |
DELETE /api/api-keys/{id}
Revoke a key (yours, or any for an admin)
Parameters:
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | integer | Yes | From 1 to 2147483647. |
Responses:
| Status | Meaning |
|---|---|
| 204 | Revoked |
| 404 | Not found |
GET /api/organisation
This organisation's name, plan and settings; admins also see which secrets are set and the GitGuardian webhook address
Responses:
| Status | Meaning |
|---|---|
| 200 | The organisation |
PATCH /api/organisation
Change settings (admins) or the name (owners). Settings merge section by section.
Request body (application/json, required).
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Up to 200 characters. |
settings | object | No |
Responses:
| Status | Meaning |
|---|---|
| 200 | Updated |
| 400 | Unknown or invalid settings |
| 403 | Not an admin |
PUT /api/organisation/secrets/{name}
Store a secret, encrypted (admins). It is never returned.
Parameters:
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | Yes | One of: gitguardian_webhook_secret. |
Request body (application/json, required).
| Field | Type | Required | Description |
|---|---|---|---|
value | string | Yes | Up to 4000 characters. |
Responses:
| Status | Meaning |
|---|---|
| 200 | Stored; the organisation with which secrets are set |
| 503 | The server has no SECRETS_KEY |
DELETE /api/organisation/secrets/{name}
Remove a secret (admins)
Parameters:
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | Yes | One of: gitguardian_webhook_secret. |
Responses:
| Status | Meaning |
|---|---|
| 200 | Removed |
GET /api/billing
The plan, its limits, usage this month, the subscription, and every plan
Responses:
| Status | Meaning |
|---|---|
| 200 | Billing summary |
POST /api/billing/checkout
A Stripe Checkout address to subscribe to Solo or Team (owners)
Request body (application/json, required).
| Field | Type | Required | Description |
|---|---|---|---|
plan | string | Yes | One of: solo, team. |
Responses:
| Status | Meaning |
|---|---|
| 200 | url to send the owner to |
| 409 | Already subscribed; use the portal |
| 503 | Payments are not set up |
POST /api/billing/portal
A Stripe customer portal address: change plan, card, invoices, cancel (owners)
Responses:
| Status | Meaning |
|---|---|
| 200 | url |
GET /api/github
Connected GitHub installations (owner, own account only; present only when the server has GITHUB_APP=on)
Responses:
| Status | Meaning |
|---|---|
| 200 | The installations (installation_id |
| 403 | Not an owner signed in with their own account |
| 404 | GitHub connection is off |
POST /api/github/connect
Start connecting GitHub; returns the GitHub address to install the App from (owner only)
Responses:
| Status | Meaning |
|---|---|
| 200 | The install address |
| 403 | Not an owner signed in with their own account |
POST /api/github/link
Link an installation to the organisation (owner only; single-use state from the redirect)
Request body (application/json, required).
| Field | Type | Required | Description |
|---|---|---|---|
installation_id | integer | Yes | |
state | string | Yes |
Responses:
| Status | Meaning |
|---|---|
| 200 | Linked |
| 400 | The state or installation was refused |
| 403 | Not an owner signed in with their own account |
PATCH /api/github/installations/{id}
Set whether a merged pull request marks its tasks done (owner only)
Parameters:
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | integer | Yes |
Request body (application/json, required).
| Field | Type | Required | Description |
|---|---|---|---|
merge_sets_done | boolean | No |
Responses:
| Status | Meaning |
|---|---|
| 200 | Updated |
| 404 | Not found |
DELETE /api/github/installations/{id}
Disconnect and delete the installation and every link made through it (owner only)
Parameters:
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | integer | Yes |
Responses:
| Status | Meaning |
|---|---|
| 200 | Deleted |
| 404 | Not found |
POST /webhooks/github
GitHub's own delivery address (signature on the raw body checked first; 404 when off)
Responses:
| Status | Meaning |
|---|---|
| 200 | Handled or ignored |
| 401 | Bad or missing signature |
| 429 | Rate limited |
GET /api/actions-minutes
The month's Actions minutes, for the account and each project
A repository counts towards the first project (by id) whose repo_url links it; the rest are listed in unmatched. Projects with a repository link, an allowance or usage are listed, those with an allowance or usage first.
Parameters:
| Name | In | Type | Required | Description |
|---|---|---|---|---|
month | query | string | No | YYYY-MM (default this month, UTC) |
Responses:
| Status | Meaning |
|---|---|
| 200 | The month's figures (ActionsMinutes) |
| 400 | The request body is invalid or is not valid JSON (Error) |
| 401 | Missing or invalid API key (Error) |
| 503 | Actions minutes are not configured on the server |
POST /api/actions-minutes/refresh
Read GitHub's usage report now
At most once a minute. A failed read keeps the last figures and sets error (the HTTP status only).
Parameters:
| Name | In | Type | Required | Description |
|---|---|---|---|---|
month | query | string | No | YYYY-MM (default this month, UTC) |
Responses:
| Status | Meaning |
|---|---|
| 200 | The month's figures after the read (ActionsMinutes) |
| 401 | Missing or invalid API key (Error) |
| 429 | Refreshed less than a minute ago |
| 503 | GitHub is not set up for Actions usage on this server |
GET /api/projects/{id}/actions-minutes
One project's minutes, and whether a planned build fits
fits is true only when live figures have been read this month, the project has an allowance, its used + planned is within it, and the account's used + planned + reserve is within the plan. reasons says why not. Build guards call this before a paid runner starts.
Parameters:
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | integer | Yes | From 1 to 2147483647. |
planned | query | integer | No | Minutes the build about to start is expected to use (runner multiplier applied). From 0 to .... |
Responses:
| Status | Meaning |
|---|---|
| 200 | The project's figures (ProjectActionsMinutes) |
| 400 | The request body is invalid or is not valid JSON (Error) |
| 401 | Missing or invalid API key (Error) |
| 404 | Item (or its parent) does not exist (Error) |
PUT /api/projects/{id}/actions-allowance
Set or remove a project's monthly allowance
All the allowances together can be at most the plan less the reserve (3,000 less 100 by default); a value that would pass it is refused with how much is left. The change is in the activity log.
Parameters:
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | integer | Yes | From 1 to 2147483647. |
Request body (application/json, required).
| Field | Type | Required | Description |
|---|---|---|---|
monthly_minutes | integer or null | Yes | Minutes a month. From 0 to .... |
Responses:
| Status | Meaning |
|---|---|
| 200 | The project's figures with the new allowance (ProjectActionsMinutes) |
| 400 | The request body is invalid or is not valid JSON (Error) |
| 401 | Missing or invalid API key (Error) |
| 404 | Item (or its parent) does not exist (Error) |