Skip to content
GitmoapdocsBeta
Guide· How do I…?

Billing and plans

Overview

During the Beta, Gitmoap is free of charge and takes no payment: every organisation is on the Free plan, and the checkout, billing portal and invoices described on this page are switched off. They are described so the page is ready when paid plans exist.

Every organisation on Gitmoap runs on a plan, and the plan decides how much you can store, how many repositories you keep, and how much pipeline compute you get each month. You can read the plan you are on, move to a paid one through Stripe Checkout, change the card or cancel from Stripe's billing portal, and list the invoices recorded for your organisation. When a single limit is the only thing in your way, ask for that limit to be raised rather than buying a bigger plan — limits are soft, and a raise is one request against one number.

Before you start

  • Owner.A plan attaches to the top of a group tree — the group with no parent — and everything beneath it shares one plan, one card and one set of limits. That whole tree is what this page calls an organisation. The calls that name a group take the id of any group in the tree and answer for the whole tree; your level is resolved on the group you name and on the groups above it, so an Owner of the top-level group qualifies from anywhere inside it.
  • Billing is Owner-only whatever the group's visibility.A public group's billing reads no more openly than a private one's, and there is no guest shortcut.
  • A token with the right scope, if you are calling the API or the CLI: billing:read to read the subscription, the invoices, your own requests and an AI organization's balance and ledger; billing:manage to open Checkout or the billing portal; billing:request_limit_increase to file a request; billing:admin for the administrator calls, which also need the administrator sign-in below.
  • The four administrator calls want an administrator sign-in, not a minted token.The review queue, approve, deny and the direct-overrides call belong to Gitmoap's platform administrators. They authenticate on a signed-in platform administrator — through the web app, or through gitmoap login for the CLI — and a personal or service-account token is refused there with 401 UNAUTHORIZED however it is scoped.
  • A person files a limit-increase request, not a service account.The request records who asked, so a service-account token is refused.

How it works

Two systems share the work, and the line between them explains almost every surprise on this page.

Stripe holds the money. The card, the charge, proration, tax, dunning, refunds and the invoice document itself all live at Stripe. Gitmoap computes no amount and stores no card.

Gitmoap holds the entitlement — which plan your organisation is on, and therefore every limit enforced when you push, create or run something. That plan changes because Stripe told us the subscription moved, never because Gitmoap decided.

you ──▶ Stripe Checkout ──▶ subscription starts at Stripe
│
▼
Stripe reports the change to us
│
▼
your organisation's plan is recorded
│
▼
every storage, count and compute check reads it

The subscription's status is what grants the plan:

Subscription statusWhat you get
trialingthe plan you subscribed to, until the trial ends
activethe plan you subscribed to
past_duethe plan you subscribed to — kept while Stripe retries the charge, so one failed payment does not degrade you mid-sprint
incomplete, incomplete_expired, unpaid, paused, canceledFree

Upgrades apply at once. Downgrades apply at the end of the period you paid for. Stripe schedules the lower price for the next renewal and reports it then, so you keep what you bought until the date you bought it through.

A drop in plan never deletes anything. If your storage sits above the new plan's limit, the repositories keep every byte; what is refused is new growth, with 429 TOO_MANY_REQUESTS, until you are back under the number.

Limits are soft, ceilings are hard. A plan's number is a starting point. One limit can be raised for one organisation without changing plan, and every raise stops at an absolute ceiling:

effective limit = min( your override if one is set, else your plan's default , the hard ceiling )

An approved limit increase writes the override. It touches neither your plan nor your card, and it applies to the very next check — there is nothing to redeploy or restart.

How to

See which plan you are on

A namespace that has never subscribed reads back as Free and active, so this call always answers; there is no such thing as a missing subscription. Alongside the plan you get the renewal date, whether a cancellation is already scheduled, when a trial ends, the seat count, and has_payment_method, which turns true once a subscription exists at Stripe for the organisation.

Open the group, choose Settings, then Usage. The panel names the plan the namespace runs on and shows each metered resource against its effective maximum, plus the per-resource limits enforced for a repository, a merge request or a work item. Opening it on a subgroup still reports the organisation's pooled figures, because that is the scope the plan applies to; only the per-group counts beside them belong to the group you opened. The renewal date, trial end, seat count and a scheduled cancellation come back from the API.

Terminalbash
gitmoap billing get-subscription --group-id <id>
curlbash
curl -X GET https://api.gitmoap.example/groups/{group_id}/billing/subscription \
-H "Authorization: Bearer $GITMOAP_TOKEN"

Subscribe to a paid plan

Checkout is Stripe's page, not ours: the call returns a URL and you send the browser to it. You supply the two absolute URLs Stripe returns to — one for a completed purchase, one for an abandoned one — so Checkout lands the buyer back wherever it makes sense in your own product.

Gitmoap hosts no checkout screen. Start the session through the API or the CLI and open the URL it returns; everything from the card form to the receipt happens on Stripe's pages. When the buyer comes back, Settings → Usage shows the plan that resulted.

Terminalbash
gitmoap billing create-checkout-session \
--group-id <id> \
--cancel-url <cancel url> \
--success-url <success url> \
--tier free|pro|team|enterprise
curlbash
curl -X POST https://api.gitmoap.example/groups/{group_id}/billing/checkout-session \
-H "Authorization: Bearer $GITMOAP_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "cancel_url": "<string>", "success_url": "<string>", "tier": "<one of enterprise | free | pro | team>" }'

seats sets the starting quantity for a per-seat plan and lets the buyer adjust it in Checkout and later in the portal. Entitlement follows the product, never the quantity — twenty seats of Team grants exactly Team. Where the plan comes with a free trial, Checkout starts the subscription in trialing and you have the full plan until it ends.

Checkout sells whichever paid plans Gitmoap publishes a price for. Ask for one it does not price and the call is refused with 400 BAD_REQUEST naming the plan; free is never among them, because it is what you fall back to rather than something you buy.

Creating a session changes nothing about your plan. The plan changes when Stripe reports the subscription, which follows the payment rather than the click that opened Checkout — and a subscription whose first charge has not cleared reads incomplete and grants Free until it does.

Change plan, update the card, or cancel

The billing portal is Stripe's too, and it is the one place to swap plan, change the card, update the billing address or cancel. Anything you do there reaches us as an event; there is nothing to tell Gitmoap afterwards.

Gitmoap hosts no billing screen. Create the portal session through the API or the CLI, open the URL it returns, and make the change on Stripe's pages.

Terminalbash
gitmoap billing create-portal-session \
--group-id <id> \
--return-url <return url>
curlbash
curl -X POST https://api.gitmoap.example/groups/{group_id}/billing/portal-session \
-H "Authorization: Bearer $GITMOAP_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "return_url": "<string>" }'

Cancelling leaves the plan in place until the period you paid for ends — the subscription reads cancel_at_period_end as true, and current_period_end is the date it drops to Free. An organisation for which no Checkout session has ever been started has no customer at Stripe to open a portal for, and the call answers 400 BAD_REQUEST saying so. Starting one is enough — the portal opens even if nobody finished paying.

Read your invoices

Invoices arrive as Stripe issues them, newest first, twenty to a page and at most a hundred. Amounts are whole minor units of the currency named — 2000 with "usd" is twenty dollars — so no rounding can creep in. Each entry carries Stripe's own hosted view and PDF links where Stripe supplies them, because the document lives at Stripe; what we keep is the summary and the way back to it.

Gitmoap hosts no invoice screen. List them through the API or the CLI and follow the hosted link on the invoice you want; that page is where the document, its line items and the tax breakdown live.

Terminalbash
gitmoap billing list-invoices --group-id <id>
curlbash
curl -X GET https://api.gitmoap.example/groups/{group_id}/billing/invoices \
-H "Authorization: Bearer $GITMOAP_TOKEN"

The list reads what has already arrived, with no call out to Stripe, so it answers quickly and it answers even while payments are unavailable — in which case it shows what had arrived before.

See your AI organization's balance

An AI organization's model calls are paid for from a balance held in dollars, before each call is made: the call's most it could cost is reserved, and when it ends what it actually cost is charged and the rest released. The balance shows what is left, how much is reserved by calls in flight, and the low-balance threshold.

Gitmoap hosts no balance screen. Read it through the API or the CLI.

Terminalbash
gitmoap billing get-group-balance --group-id <id>
curlbash
curl -X GET https://api.gitmoap.example/groups/{group_id}/billing/balance \
-H "Authorization: Bearer $GITMOAP_TOKEN"

During early access Gitmoap funds the balance, and there is no top-up to buy.

Read what each model call cost

The ledger holds one entry per model call, newest first: what it cost, the fee beside it, the session and turn it belonged to, and the model and token counts it was priced from. Amounts are in millionths of a dollar — 1500000 is a dollar fifty — so no rounding creeps in. A call is never charged twice, and never more than was reserved for it.

Gitmoap hosts no ledger screen. Read it through the API or the CLI.

Terminalbash
gitmoap billing list-group-usage-entries --group-id <id>
curlbash
curl -X GET https://api.gitmoap.example/groups/{group_id}/billing/usage/entries \
-H "Authorization: Bearer $GITMOAP_TOKEN"

Fund a balance

The call belongs to Gitmoap's platform administrators: it credits or debits an organisation's balance with a stated reason, which the organisation's ledger of transactions keeps. It needs a platform administrator signed in to Gitmoap, and answers 403 FORBIDDEN for anyone else. At most 20 adjustments may be made to one organisation in a day.

Gitmoap hosts no adjustment screen. Adjust through the API or the CLI, signed in as a platform administrator.

Terminalbash
gitmoap billing create-admin-balance-adjustment \
--root-group-id <id> \
--amount-micros <n> \
--note <note>
curlbash
curl -X POST https://api.gitmoap.example/admin/namespaces/{root_group_id}/billing/balance/adjustments \
-H "Authorization: Bearer $GITMOAP_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "amount_micros": "<int64>", "note": "<string>" }'

Ask for one limit to be raised

Name the limit, the value you need and why you need it. Give the reviewer something to act on: what you are building, what stopped, and the number that would unblock it. The justification runs from 1 to 2000 characters.

Gitmoap hosts no request form. Settings → Usage is where you find the limit that is in your way and the effective maximum enforced today; file the request itself through the API or the CLI, naming that limit.

Terminalbash
gitmoap billing request-limit-increase \
--group-id <id> \
--justification <justification> \
--limit-key storage_bytes|max_repos_per_group|max_members_per_scope|max_teams_per_org|max_members_per_team|max_custom_roles_per_org|max_limits_per_scope|max_approval_rules_per_scope|max_scim_tokens_per_org|max_ai_agents_per_org|max_ai_concurrent_sessions_per_org|max_ai_sessions_per_org_per_day|max_ai_revision_drafts_per_org_per_day|max_balance_adjustments_per_namespace_per_day|max_agent_workspace_minutes_per_month|ai_management_fee_bps|max_open_mrs_per_repo|max_comments_per_mr|max_branches_per_repo|max_tags_per_repo|max_webhooks_per_scope|max_service_accounts_per_scope|max_branch_rules_per_scope|max_provider_connections_per_scope|max_reviewers_per_mr|max_reactions_per_comment|max_commit_statuses_per_commit|max_provider_installs_per_group|max_concurrent_pipeline_runs|max_pipeline_runs_per_month|max_pipeline_minutes_per_month|max_pipeline_dag_nodes|max_push_bytes|max_package_bytes|max_release_asset_bytes|max_node_log_bytes|max_releases_per_repo|max_pipelines_per_repo|max_open_issues_per_scope|max_labels_per_scope|max_milestones_per_scope|max_blueprints_per_scope|max_wiki_pages_per_scope|max_services_per_scope|max_environments_per_scope|max_scorecards_per_scope|max_pipeline_components_per_scope|max_versions_per_pipeline_component|max_comments_per_issue|max_relations_per_issue|max_children_per_issue|max_activities_per_issue|max_code_links_per_issue|max_mr_links_per_issue|max_anchors_per_issue|max_anchors_per_repo|max_criteria_per_issue|max_criteria_per_repo|max_code_todos_per_repo|max_root_groups \
--requested-value <n>
curlbash
curl -X POST https://api.gitmoap.example/groups/{group_id}/limit-increase \
-H "Authorization: Bearer $GITMOAP_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "justification": "<string>", "limit_key": "<one of ai_management_fee_bps | max_activities_per_issue | max_agent_workspace_minutes_per_month | max_ai_agents_per_org | max_ai_concurrent_sessions_per_org | max_ai_revision_drafts_per_org_per_day | max_ai_sessions_per_org_per_day | max_anchors_per_issue | max_anchors_per_repo | max_approval_rules_per_scope | max_balance_adjustments_per_namespace_per_day | max_blueprints_per_scope | max_branch_rules_per_scope | max_branches_per_repo | max_children_per_issue | max_code_links_per_issue | max_code_todos_per_repo | max_comments_per_issue | max_comments_per_mr | max_commit_statuses_per_commit | max_concurrent_pipeline_runs | max_criteria_per_issue | max_criteria_per_repo | max_custom_roles_per_org | max_environments_per_scope | max_labels_per_scope | max_limits_per_scope | max_members_per_scope | max_members_per_team | max_milestones_per_scope | max_mr_links_per_issue | max_node_log_bytes | max_open_issues_per_scope | max_open_mrs_per_repo | max_package_bytes | max_pipeline_components_per_scope | max_pipeline_dag_nodes | max_pipeline_minutes_per_month | max_pipeline_runs_per_month | max_pipelines_per_repo | max_provider_connections_per_scope | max_provider_installs_per_group | max_push_bytes | max_reactions_per_comment | max_relations_per_issue | max_release_asset_bytes | max_releases_per_repo | max_repos_per_group | max_reviewers_per_mr | max_root_groups | max_scim_tokens_per_org | max_scorecards_per_scope | max_service_accounts_per_scope | max_services_per_scope | max_tags_per_repo | max_teams_per_org | max_versions_per_pipeline_component | max_webhooks_per_scope | max_wiki_pages_per_scope | storage_bytes>", "requested_value": "<int64>" }'

Three rules decide whether the request is accepted for review. The value has to be strictly above your current effective limit, it has to sit at or below the limit's hard ceiling, and only one request per limit may be open at a time for an organisation — a second one answers 409 CONFLICT until the first is decided.

One limit is not an organisation's at all: max_root_groups is the number of top-level groups you may own. File it against any organisation you own, and an approval raises your personal budget rather than that organisation's limits. For this one limit the must-be-an-increase check is made against the standard starting budget of three rather than against a raise you already hold, so ask for a number above whichever of the two is higher. No group's usage view reports it either, because it belongs to you and not to a namespace: the only way to see where you stand is that creating one more top-level group either works or answers 429.

Track a request you filed

Requests come back newest first and you can filter by status. pending is waiting for a reviewer, denied carries the reason in its decision note, and applied is the terminal success state — approval writes the override in the same step, so a successful request never rests at approved.

Gitmoap hosts no request list. Read them through the API or the CLI; the effect of an applied request is visible in Settings → Usage, where the effective maximum is the raised number.

Terminalbash
gitmoap billing list-limit-increase-requests --group-id <id>
curlbash
curl -X GET https://api.gitmoap.example/groups/{group_id}/limit-increase-requests \
-H "Authorization: Bearer $GITMOAP_TOKEN"

Review the queue

The four calls below belong to Gitmoap's platform administrators, not to an organisation's Owner. They need a platform administrator signed in to Gitmoap, and they answer 403 FORBIDDEN for anyone else.

The queue spans every organisation and defaults to the pending ones, which is the working list. Each entry carries the limit asked for, the value, the effective limit at the moment of filing, the justification and who filed it.

Gitmoap hosts no review screen. Read the queue through the API or the CLI, signed in as a platform administrator.

Terminalbash
gitmoap billing list-admin-limit-increase-requests
curlbash
curl -X GET https://api.gitmoap.example/admin/limit-increase-requests \
-H "Authorization: Bearer $GITMOAP_TOKEN"

Approve a request

Approval applies immediately, and it is safe to retry: the override is written before the request is marked applied, so an interruption leaves the request still pending and approving again finishes the job without granting anything twice. Approve with no value to grant exactly what was asked, or name your own value, larger or smaller than the request.

Gitmoap hosts no approval screen. Approve through the API or the CLI, signed in as a platform administrator.

Terminalbash
gitmoap billing approve-limit-increase-request --request-id <id>
curlbash
curl -X POST https://api.gitmoap.example/admin/limit-increase-requests/{request_id}/approve \
-H "Authorization: Bearer $GITMOAP_TOKEN"

The applied value is clamped to the limit's hard ceiling, so an approval can never exceed it however it is written. A request that has already been decided answers 409 CONFLICT — decisions are final, and a second raise is a second request. An approved max_root_groups writes the filer's own budget, not the organisation's limits.

Deny a request

A denial requires a reason, and the requester reads it. Say what would change the answer — a smaller number, a different plan, a workload split across organisations — because the only route on from a denial is a fresh request.

Gitmoap hosts no denial screen. Deny through the API or the CLI, signed in as a platform administrator, and give the reason in the decision note.

Terminalbash
gitmoap billing deny-limit-increase-request \
--request-id <id> \
--decision-note <decision note>
curlbash
curl -X POST https://api.gitmoap.example/admin/limit-increase-requests/{request_id}/deny \
-H "Authorization: Bearer $GITMOAP_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "decision_note": "<string>" }'

Set an organisation's limits directly

The negotiated path: set limits for one organisation with no request in front of them. Every value is checked against the hard ceiling and refused if it is over — the direct call rejects rather than quietly clamping, so a fat-fingered number surfaces as a 400 BAD_REQUEST instead of as a silently smaller raise.

Warning

Sending a limit as null deletes its override, and the organisation drops back to its plan's default for that limit on the very next check. If they are using more than the default allows, that is immediate: existing data is untouched, but new pushes, creations and runs against that limit are refused until they are back under it. The override is gone and the value it held is not recoverable from this call, and nothing reads a namespace's stored overrides back — so check the organisation's effective maximum for that limit before you clear it, and keep the response of this call, which returns the overrides that remain.

The call merges rather than replaces. Limits you name are set, limits you send as null are cleared, and limits you leave out keep whatever they had. The id in the URL has to be the top-level group; a subgroup answers 400 BAD_REQUEST.

Gitmoap hosts no overrides screen. Set them through the API or the CLI, signed in as a platform administrator.

Terminalbash
gitmoap billing set-namespace-limit-overrides \
--root-group-id <id> \
--overrides '<json>'
curlbash
curl -X PUT https://api.gitmoap.example/admin/namespaces/{root_group_id}/limit-overrides \
-H "Authorization: Bearer $GITMOAP_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "overrides": "<object>" }'

Keep the plan in step with Stripe

Stripe reports every subscription and invoice change to a single address on Gitmoap. It is the only path by which a plan changes, and it authenticates on Stripe's signature over the exact bytes of the request rather than on a token — a body that has been altered in flight fails verification and is never processed.

There is no screen and no reason to call this yourself: Stripe calls it. Gitmoap registers the address with Stripe and configures the matching signing secret.

Terminalbash
gitmoap billing stripe-webhook --body <body>
curlbash
curl -X POST https://api.gitmoap.example/billing/stripe/webhook

We handle replays and out-of-order delivery, so Stripe's retries are safe: an event already applied changes nothing the second time, and an older event arriving after a newer one is skipped instead of undoing it. An event about a subscription Gitmoap has never seen is ignored rather than treated as an error. A delivery whose signature timestamp sits more than five minutes from the deployment's clock is refused outright, which is what a captured request replayed later looks like.

Reference

14 endpoints

GET/groups/{group_id}/billing/subscriptionbilling:read

Read the namespace's subscription (tier, status, period)

get_subscriptionGET /groups/{group_id}/billing/subscriptionOpen in the API reference

Token scope

billing:read

Send

Path
  • group_iduuidAny group in the namespace

Refuses

  • 400Bad request — a path parameter is not a well-formed value of its type
  • 401Unauthenticated — no credential, or an invalid one
  • 403Forbidden — the caller's access level or token scope is insufficient
  • 404Not found — or found and private, which is masked as absent

Receive

  • cancel_at_period_endboolean
  • current_period_endobjectoptional
  • has_payment_methodboolean
  • plan_tierenterprisefreeproteamThe subscription plan an organization is on, which sets its resource limits. From smallest to largest: free, pro, team, enterprise.
  • root_group_iduuid
  • seatsint32optional
  • statusactivecanceledincompleteincomplete_expiredpast_duepausedtrialingunpaidStripe subscription status, mirrored. entitled_tier is the only place it becomes a PlanTier.
  • trial_endobjectoptional
POST/groups/{group_id}/billing/checkout-sessionbilling:manage

Start a Stripe Checkout Session to subscribe the namespace to a paid tier

create_checkout_sessionPOST /groups/{group_id}/billing/checkout-sessionOpen in the API reference

Token scope

billing:manage

Send

Path
  • group_iduuidAny group in the namespace
Body
  • cancel_urlstring
  • seatsint32optionalSeat count for a per-seat tier (e.g. Team). When set, Checkout starts at this quantity and lets the customer adjust it; omit (or 1) for a flat per-namespace tier. Entitlement keys on the product, never the quantity.
  • success_urlstring
  • tierenterprisefreeproteamThe subscription plan an organization is on, which sets its resource limits. From smallest to largest: free, pro, team, enterprise.

Refuses

  • 400Tier not available for self-service checkout
  • 401Unauthenticated — no credential, or an invalid one
  • 403Forbidden — the caller's access level or token scope is insufficient
  • 404Not found — or found and private, which is masked as absent
  • 409The request conflicts with the resource's current state; `reason` says how
  • 501Billing not configured on this deployment

Receive

  • checkout_urlstring
  • session_idstring
POST/groups/{group_id}/billing/portal-sessionbilling:manage

Open the Stripe Billing Portal for the namespace's customer

create_portal_sessionPOST /groups/{group_id}/billing/portal-sessionOpen in the API reference

Token scope

billing:manage

Send

Path
  • group_iduuidAny group in the namespace
Body
  • return_urlstring

Refuses

  • 400No Stripe customer for this namespace yet
  • 401Unauthenticated — no credential, or an invalid one
  • 403Forbidden — the caller's access level or token scope is insufficient
  • 404Not found — or found and private, which is masked as absent
  • 409The request conflicts with the resource's current state; `reason` says how
  • 501Billing not configured on this deployment

Receive

  • portal_urlstring
GET/groups/{group_id}/billing/invoicesbilling:read

List the namespace's invoices, newest first

list_invoicesGET /groups/{group_id}/billing/invoicesOpen in the API reference

Token scope

billing:read

Send

Path
  • group_iduuidAny group in the namespace
Query
  • limitint32optionalPage size (1-100, default 20)
  • cursorstringoptionalPagination cursor

Refuses

  • 400Bad request — a path parameter is not a well-formed value of its type
  • 401Unauthenticated — no credential, or an invalid one
  • 403Forbidden — the caller's access level or token scope is insufficient
  • 404Not found — or found and private, which is masked as absent

Receive

  • invoices[]object11 fields
    • amount_dueint64
    • amount_paidint64
    • created_atstring
    • currencystring
    • hosted_invoice_urlobjectoptional
    • invoice_pdfobjectoptional
    • numberobjectoptional
    • period_endobjectoptional
    • period_startobjectoptional
    • statusdraftopenpaiduncollectiblevoidStripe invoice status, mirrored. A thin projection value — gitmoap never computes it, only records what Stripe reports.
    • stripe_invoice_idstring
  • next_cursorobjectoptional
POST/groups/{group_id}/limit-increasebilling:request_limit_increase

File a request to raise one namespace limit

request_limit_increasePOST /groups/{group_id}/limit-increaseOpen in the API reference

Token scope

billing:request_limit_increase

Send

Path
  • group_iduuidAny group in the namespace
Body
  • justificationstring
  • limit_keyai_management_fee_bpsmax_activities_per_issuemax_agent_workspace_minutes_per_monthmax_ai_agents_per_orgmax_ai_concurrent_sessions_per_orgmax_ai_revision_drafts_per_org_per_daymax_ai_sessions_per_org_per_daymax_anchors_per_issuemax_anchors_per_repomax_approval_rules_per_scopemax_balance_adjustments_per_namespace_per_daymax_blueprints_per_scopemax_branch_rules_per_scopemax_branches_per_repomax_children_per_issuemax_code_links_per_issuemax_code_todos_per_repomax_comments_per_issuemax_comments_per_mrmax_commit_statuses_per_commitmax_concurrent_pipeline_runsmax_criteria_per_issuemax_criteria_per_repomax_custom_roles_per_orgmax_environments_per_scopemax_labels_per_scopemax_limits_per_scopemax_members_per_scopemax_members_per_teammax_milestones_per_scopemax_mr_links_per_issuemax_node_log_bytesmax_open_issues_per_scopemax_open_mrs_per_repomax_package_bytesmax_pipeline_components_per_scopemax_pipeline_dag_nodesmax_pipeline_minutes_per_monthmax_pipeline_runs_per_monthmax_pipelines_per_repomax_provider_connections_per_scopemax_provider_installs_per_groupmax_push_bytesmax_reactions_per_commentmax_relations_per_issuemax_release_asset_bytesmax_releases_per_repomax_repos_per_groupmax_reviewers_per_mrmax_root_groupsmax_scim_tokens_per_orgmax_scorecards_per_scopemax_service_accounts_per_scopemax_services_per_scopemax_tags_per_repomax_teams_per_orgmax_versions_per_pipeline_componentmax_webhooks_per_scopemax_wiki_pages_per_scopestorage_bytesA recognised limit name — every PlanLimits cap plus the user-scoped max_root_groups. The identity a limit-increase request and a namespace override are keyed by.
  • requested_valueint64

Refuses

  • 400Invalid request
  • 401Unauthenticated — no credential, or an invalid one
  • 403Forbidden — the caller's access level or token scope is insufficient
  • 404Not found — or found and private, which is masked as absent
  • 409A pending request for this limit already exists

Receive

  • applied_valueint64optional
  • created_atstring
  • current_effectiveint64
  • decided_atobjectoptional
  • decided_byobjectoptional
  • decision_noteobjectoptional
  • justificationstring
  • limit_keyai_management_fee_bpsmax_activities_per_issuemax_agent_workspace_minutes_per_monthmax_ai_agents_per_orgmax_ai_concurrent_sessions_per_orgmax_ai_revision_drafts_per_org_per_daymax_ai_sessions_per_org_per_daymax_anchors_per_issuemax_anchors_per_repomax_approval_rules_per_scopemax_balance_adjustments_per_namespace_per_daymax_blueprints_per_scopemax_branch_rules_per_scopemax_branches_per_repomax_children_per_issuemax_code_links_per_issuemax_code_todos_per_repomax_comments_per_issuemax_comments_per_mrmax_commit_statuses_per_commitmax_concurrent_pipeline_runsmax_criteria_per_issuemax_criteria_per_repomax_custom_roles_per_orgmax_environments_per_scopemax_labels_per_scopemax_limits_per_scopemax_members_per_scopemax_members_per_teammax_milestones_per_scopemax_mr_links_per_issuemax_node_log_bytesmax_open_issues_per_scopemax_open_mrs_per_repomax_package_bytesmax_pipeline_components_per_scopemax_pipeline_dag_nodesmax_pipeline_minutes_per_monthmax_pipeline_runs_per_monthmax_pipelines_per_repomax_provider_connections_per_scopemax_provider_installs_per_groupmax_push_bytesmax_reactions_per_commentmax_relations_per_issuemax_release_asset_bytesmax_releases_per_repomax_repos_per_groupmax_reviewers_per_mrmax_root_groupsmax_scim_tokens_per_orgmax_scorecards_per_scopemax_service_accounts_per_scopemax_services_per_scopemax_tags_per_repomax_teams_per_orgmax_versions_per_pipeline_componentmax_webhooks_per_scopemax_wiki_pages_per_scopestorage_bytesA recognised limit name — every PlanLimits cap plus the user-scoped max_root_groups. The identity a limit-increase request and a namespace override are keyed by.
  • request_iduuid
  • requested_byuuid
  • requested_valueint64
  • root_group_iduuid
  • statusappliedapproveddeniedpendingLifecycle of a limit-increase request. Applied is the terminal success state (the override was written); Approved exists for symmetry but the approve path applies immediately, so a persisted request is never left Approved-but-not-Applied.
  • updated_atstring
GET/groups/{group_id}/limit-increase-requestsbilling:read

List the namespace's own limit-increase requests

list_limit_increase_requestsGET /groups/{group_id}/limit-increase-requestsOpen in the API reference

Token scope

billing:read

Send

Path
  • group_iduuidAny group in the namespace
Query
  • statusstringoptionalpending | approved | denied | applied
  • limitint32optionalPage size, 1–100 (default 50)
  • cursorstringoptionalPagination cursor

Refuses

  • 400Bad request — a path parameter is not a well-formed value of its type
  • 401Unauthenticated — no credential, or an invalid one
  • 403Forbidden — the caller's access level or token scope is insufficient
  • 404Not found — or found and private, which is masked as absent

Receive

  • items[]object14 fields
    • applied_valueint64optional
    • created_atstring
    • current_effectiveint64
    • decided_atobjectoptional
    • decided_byobjectoptional
    • decision_noteobjectoptional
    • justificationstring
    • limit_keyai_management_fee_bpsmax_activities_per_issuemax_agent_workspace_minutes_per_monthmax_ai_agents_per_orgmax_ai_concurrent_sessions_per_orgmax_ai_revision_drafts_per_org_per_daymax_ai_sessions_per_org_per_daymax_anchors_per_issuemax_anchors_per_repomax_approval_rules_per_scopemax_balance_adjustments_per_namespace_per_daymax_blueprints_per_scopemax_branch_rules_per_scopemax_branches_per_repomax_children_per_issuemax_code_links_per_issuemax_code_todos_per_repomax_comments_per_issuemax_comments_per_mrmax_commit_statuses_per_commitmax_concurrent_pipeline_runsmax_criteria_per_issuemax_criteria_per_repomax_custom_roles_per_orgmax_environments_per_scopemax_labels_per_scopemax_limits_per_scopemax_members_per_scopemax_members_per_teammax_milestones_per_scopemax_mr_links_per_issuemax_node_log_bytesmax_open_issues_per_scopemax_open_mrs_per_repomax_package_bytesmax_pipeline_components_per_scopemax_pipeline_dag_nodesmax_pipeline_minutes_per_monthmax_pipeline_runs_per_monthmax_pipelines_per_repomax_provider_connections_per_scopemax_provider_installs_per_groupmax_push_bytesmax_reactions_per_commentmax_relations_per_issuemax_release_asset_bytesmax_releases_per_repomax_repos_per_groupmax_reviewers_per_mrmax_root_groupsmax_scim_tokens_per_orgmax_scorecards_per_scopemax_service_accounts_per_scopemax_services_per_scopemax_tags_per_repomax_teams_per_orgmax_versions_per_pipeline_componentmax_webhooks_per_scopemax_wiki_pages_per_scopestorage_bytesA recognised limit name — every PlanLimits cap plus the user-scoped max_root_groups. The identity a limit-increase request and a namespace override are keyed by.
    • request_iduuid
    • requested_byuuid
    • requested_valueint64
    • root_group_iduuid
    • statusappliedapproveddeniedpendingLifecycle of a limit-increase request. Applied is the terminal success state (the override was written); Approved exists for symmetry but the approve path applies immediately, so a persisted request is never left Approved-but-not-Applied.
    • updated_atstring
  • next_cursorobjectoptional
GET/admin/limit-increase-requestsbilling:admin

Review queue: limit-increase requests across all namespaces (platform admin)

list_admin_limit_increase_requestsGET /admin/limit-increase-requestsOpen in the API reference

Token scope

billing:admin

Send

Query
  • statusstringoptionalFilter by status (default pending)
  • limitint32optionalPage size, 1–100 (default 50)
  • cursorstringoptionalPagination cursor

Refuses

  • 401Unauthenticated — no credential, or an invalid one
  • 403Forbidden — the caller's access level or token scope is insufficient

Receive

The same shape list_limit_increase_requests returns — 2 fields. Go to it

Show it here
  • items[]object14 fields
    • applied_valueint64optional
    • created_atstring
    • current_effectiveint64
    • decided_atobjectoptional
    • decided_byobjectoptional
    • decision_noteobjectoptional
    • justificationstring
    • limit_keyai_management_fee_bpsmax_activities_per_issuemax_agent_workspace_minutes_per_monthmax_ai_agents_per_orgmax_ai_concurrent_sessions_per_orgmax_ai_revision_drafts_per_org_per_daymax_ai_sessions_per_org_per_daymax_anchors_per_issuemax_anchors_per_repomax_approval_rules_per_scopemax_balance_adjustments_per_namespace_per_daymax_blueprints_per_scopemax_branch_rules_per_scopemax_branches_per_repomax_children_per_issuemax_code_links_per_issuemax_code_todos_per_repomax_comments_per_issuemax_comments_per_mrmax_commit_statuses_per_commitmax_concurrent_pipeline_runsmax_criteria_per_issuemax_criteria_per_repomax_custom_roles_per_orgmax_environments_per_scopemax_labels_per_scopemax_limits_per_scopemax_members_per_scopemax_members_per_teammax_milestones_per_scopemax_mr_links_per_issuemax_node_log_bytesmax_open_issues_per_scopemax_open_mrs_per_repomax_package_bytesmax_pipeline_components_per_scopemax_pipeline_dag_nodesmax_pipeline_minutes_per_monthmax_pipeline_runs_per_monthmax_pipelines_per_repomax_provider_connections_per_scopemax_provider_installs_per_groupmax_push_bytesmax_reactions_per_commentmax_relations_per_issuemax_release_asset_bytesmax_releases_per_repomax_repos_per_groupmax_reviewers_per_mrmax_root_groupsmax_scim_tokens_per_orgmax_scorecards_per_scopemax_service_accounts_per_scopemax_services_per_scopemax_tags_per_repomax_teams_per_orgmax_versions_per_pipeline_componentmax_webhooks_per_scopemax_wiki_pages_per_scopestorage_bytesA recognised limit name — every PlanLimits cap plus the user-scoped max_root_groups. The identity a limit-increase request and a namespace override are keyed by.
    • request_iduuid
    • requested_byuuid
    • requested_valueint64
    • root_group_iduuid
    • statusappliedapproveddeniedpendingLifecycle of a limit-increase request. Applied is the terminal success state (the override was written); Approved exists for symmetry but the approve path applies immediately, so a persisted request is never left Approved-but-not-Applied.
    • updated_atstring
  • next_cursorobjectoptional
POST/admin/limit-increase-requests/{request_id}/approvebilling:admin

Approve a limit-increase request and apply the override (platform admin)

approve_limit_increase_requestPOST /admin/limit-increase-requests/{request_id}/approveOpen in the API reference

Token scope

billing:admin

Send

Path
  • request_iduuidRequest id
Body
  • approved_valueint64optionalValue to apply; defaults to the request's requested_value. Clamped to the ceiling.
  • decision_noteobjectoptional

Refuses

  • 400Bad request — a path parameter is not a well-formed value of its type
  • 401Unauthenticated — no credential, or an invalid one
  • 403Forbidden — the caller's access level or token scope is insufficient
  • 404Not found
  • 409Already decided

Receive

The same shape request_limit_increase returns — 14 fields. Go to it

Show it here
  • applied_valueint64optional
  • created_atstring
  • current_effectiveint64
  • decided_atobjectoptional
  • decided_byobjectoptional
  • decision_noteobjectoptional
  • justificationstring
  • limit_keyai_management_fee_bpsmax_activities_per_issuemax_agent_workspace_minutes_per_monthmax_ai_agents_per_orgmax_ai_concurrent_sessions_per_orgmax_ai_revision_drafts_per_org_per_daymax_ai_sessions_per_org_per_daymax_anchors_per_issuemax_anchors_per_repomax_approval_rules_per_scopemax_balance_adjustments_per_namespace_per_daymax_blueprints_per_scopemax_branch_rules_per_scopemax_branches_per_repomax_children_per_issuemax_code_links_per_issuemax_code_todos_per_repomax_comments_per_issuemax_comments_per_mrmax_commit_statuses_per_commitmax_concurrent_pipeline_runsmax_criteria_per_issuemax_criteria_per_repomax_custom_roles_per_orgmax_environments_per_scopemax_labels_per_scopemax_limits_per_scopemax_members_per_scopemax_members_per_teammax_milestones_per_scopemax_mr_links_per_issuemax_node_log_bytesmax_open_issues_per_scopemax_open_mrs_per_repomax_package_bytesmax_pipeline_components_per_scopemax_pipeline_dag_nodesmax_pipeline_minutes_per_monthmax_pipeline_runs_per_monthmax_pipelines_per_repomax_provider_connections_per_scopemax_provider_installs_per_groupmax_push_bytesmax_reactions_per_commentmax_relations_per_issuemax_release_asset_bytesmax_releases_per_repomax_repos_per_groupmax_reviewers_per_mrmax_root_groupsmax_scim_tokens_per_orgmax_scorecards_per_scopemax_service_accounts_per_scopemax_services_per_scopemax_tags_per_repomax_teams_per_orgmax_versions_per_pipeline_componentmax_webhooks_per_scopemax_wiki_pages_per_scopestorage_bytesA recognised limit name — every PlanLimits cap plus the user-scoped max_root_groups. The identity a limit-increase request and a namespace override are keyed by.
  • request_iduuid
  • requested_byuuid
  • requested_valueint64
  • root_group_iduuid
  • statusappliedapproveddeniedpendingLifecycle of a limit-increase request. Applied is the terminal success state (the override was written); Approved exists for symmetry but the approve path applies immediately, so a persisted request is never left Approved-but-not-Applied.
  • updated_atstring
POST/admin/limit-increase-requests/{request_id}/denybilling:admin

Deny a limit-increase request (platform admin)

deny_limit_increase_requestPOST /admin/limit-increase-requests/{request_id}/denyOpen in the API reference

Token scope

billing:admin

Send

Path
  • request_iduuidRequest id
Body
  • decision_notestringA required reason for the denial.

Refuses

  • 400Bad request — a path parameter is not a well-formed value of its type
  • 401Unauthenticated — no credential, or an invalid one
  • 403Forbidden — the caller's access level or token scope is insufficient
  • 404Not found
  • 409Already decided

Receive

The same shape request_limit_increase returns — 14 fields. Go to it

Show it here
  • applied_valueint64optional
  • created_atstring
  • current_effectiveint64
  • decided_atobjectoptional
  • decided_byobjectoptional
  • decision_noteobjectoptional
  • justificationstring
  • limit_keyai_management_fee_bpsmax_activities_per_issuemax_agent_workspace_minutes_per_monthmax_ai_agents_per_orgmax_ai_concurrent_sessions_per_orgmax_ai_revision_drafts_per_org_per_daymax_ai_sessions_per_org_per_daymax_anchors_per_issuemax_anchors_per_repomax_approval_rules_per_scopemax_balance_adjustments_per_namespace_per_daymax_blueprints_per_scopemax_branch_rules_per_scopemax_branches_per_repomax_children_per_issuemax_code_links_per_issuemax_code_todos_per_repomax_comments_per_issuemax_comments_per_mrmax_commit_statuses_per_commitmax_concurrent_pipeline_runsmax_criteria_per_issuemax_criteria_per_repomax_custom_roles_per_orgmax_environments_per_scopemax_labels_per_scopemax_limits_per_scopemax_members_per_scopemax_members_per_teammax_milestones_per_scopemax_mr_links_per_issuemax_node_log_bytesmax_open_issues_per_scopemax_open_mrs_per_repomax_package_bytesmax_pipeline_components_per_scopemax_pipeline_dag_nodesmax_pipeline_minutes_per_monthmax_pipeline_runs_per_monthmax_pipelines_per_repomax_provider_connections_per_scopemax_provider_installs_per_groupmax_push_bytesmax_reactions_per_commentmax_relations_per_issuemax_release_asset_bytesmax_releases_per_repomax_repos_per_groupmax_reviewers_per_mrmax_root_groupsmax_scim_tokens_per_orgmax_scorecards_per_scopemax_service_accounts_per_scopemax_services_per_scopemax_tags_per_repomax_teams_per_orgmax_versions_per_pipeline_componentmax_webhooks_per_scopemax_wiki_pages_per_scopestorage_bytesA recognised limit name — every PlanLimits cap plus the user-scoped max_root_groups. The identity a limit-increase request and a namespace override are keyed by.
  • request_iduuid
  • requested_byuuid
  • requested_valueint64
  • root_group_iduuid
  • statusappliedapproveddeniedpendingLifecycle of a limit-increase request. Applied is the terminal success state (the override was written); Approved exists for symmetry but the approve path applies immediately, so a persisted request is never left Approved-but-not-Applied.
  • updated_atstring
PUT/admin/namespaces/{root_group_id}/limit-overridesbilling:admin

Set or clear a namespace's limit overrides directly (platform admin)

set_namespace_limit_overridesPUT /admin/namespaces/{root_group_id}/limit-overridesOpen in the API reference

Token scope

billing:admin

Send

Path
  • root_group_iduuidThe namespace's top-level group
Body
  • noteobjectoptional
  • overridesobjectLimit-name → value (or null to clear). Keys must be namespace LimitKeys.

Refuses

  • 400Not a namespace's top-level group, an unknown limit, or a value above the limit's ceiling
  • 401Unauthenticated — no credential, or an invalid one
  • 403Forbidden — the caller's access level or token scope is insufficient
  • 404Not found — or found and private, which is masked as absent
  • 409The request conflicts with the resource's current state; `reason` says how

Receive

  • overridesobjectLimit-name → override value (clamped to the ceiling). Absent keys use the tier default.
  • root_group_iduuid
  • updated_atstring
  • updated_bystring
POST/billing/stripe/webhookpublic

Receive an event from Stripe

stripe_webhookPOST /billing/stripe/webhookOpen in the API reference

Token scope

None — this one is public

Send

Nothing — the address is the whole request.

Refuses

  • 400The `Stripe-Signature` header is missing
  • 401Signature verification failed
  • 501Billing not configured on this deployment

Receive

No body.

GET/groups/{group_id}/billing/balancebilling:read

A namespace's prepaid balance.

get_group_balanceGET /groups/{group_id}/billing/balanceOpen in the API reference

Token scope

billing:read

Send

Path
  • group_iduuidAny group in the namespace

Refuses

  • 400Bad request — a path parameter is not a well-formed value of its type
  • 401Unauthenticated — no credential, or an invalid one
  • 403Forbidden — the caller's access level or token scope is insufficient
  • 404Not found — or found and private, which is masked as absent

Receive

  • available_microsint64What can still be reserved: the balance, less what is reserved, plus any overdraft.
  • balance_microsint64Top-ups less settled charges, refunds and chargebacks, in micro-dollars.
  • frozenbooleanWhether a disputed payment has frozen the balance.
  • group_iduuid
  • low_threshold_microsint64
  • reserved_microsint64Held by calls in flight.
GET/groups/{group_id}/billing/usage/entriesbilling:read

A namespace's usage ledger, newest first.

list_group_usage_entriesGET /groups/{group_id}/billing/usage/entriesOpen in the API reference

Token scope

billing:read

Send

Path
  • group_iduuidAny group in the namespace
Query
  • limitint64optionalMaximum number of entries, 1-100 (default 50)
  • next_tokenstringoptionalPagination token

Refuses

  • 400Bad request — a path parameter is not a well-formed value of its type
  • 401Unauthenticated — no credential, or an invalid one
  • 403Forbidden — the caller's access level or token scope is insufficient
  • 404Not found — or found and private, which is masked as absent

Receive

  • items[]object9 fields
    • amount_microsint64
    • entry_iduuid
    • fee_microsint64
    • kindcorrectionorphan_settledsettled
    • lineone of ai_model_usageWhat a ledger entry charges for. One line so far: AI model usage.
    • monthstring
    • occurred_atdate-time
    • price_refobjectWhat the amount was calculated from: the model price used and the token counts.
    • subjectobjectWhat was charged for — for a model call, organization, agent, session and turn.
  • next_tokenobjectoptional
POST/admin/namespaces/{root_group_id}/billing/balance/adjustmentsbilling:admin

Adjust a namespace's prepaid balance (platform admin)

create_admin_balance_adjustmentPOST /admin/namespaces/{root_group_id}/billing/balance/adjustmentsOpen in the API reference

Token scope

billing:admin

Counts against

balance_adjustments_per_namespace_per_day

Send

Path
  • root_group_iduuidThe namespace's top-level group
Body
  • amount_microsint64Micro-dollars to add (positive) or take away (negative); never zero.
  • notestring

Refuses

  • 400Not a namespace's top-level group, or an amount out of range
  • 401Unauthenticated — no credential, or an invalid one
  • 403Forbidden — the caller's access level or token scope is insufficient
  • 404Not found — or found and private, which is masked as absent
  • 409The request conflicts with the resource's current state; `reason` says how
  • 429Adjustment limit reached for this namespace today

Receive

  • amount_microsint64
  • balance_microsint64The balance after this change, in micro-dollars.
  • created_atdate-time
  • created_byobjectoptional
  • group_iduuid
  • kindadjustmentchargebackcommitmentrefundtop_up
  • noteobjectoptional
  • transaction_iduuid

Limits

Four plans, and each raises every limit or holds it level — nothing gets smaller as you move right. The ceiling column is the absolute maximum an override reaches for that limit, whatever plan you are on and whatever value is approved. Below are the limits people meet; the full set of names a request may name is listed on the request card in Reference.

LimitFreeProTeamEnterpriseCeiling
Stored bytes across the organisation5 GiB100 GiB1 TiB10 TiB100 TiB
Repositories per group202002,00020,000100,000
Members per group or repository502001,0005,00050,000
Branches per repository1,0005,00020,00050,000500,000
Tags per repository1,0005,00020,00050,000500,000
Open merge requests per repository1005002,0005,00050,000
Open work items per group or repository5,00020,000100,000500,0005,000,000
Releases per repository1,0005,00020,00050,000500,000
Pipeline runs in flight at once210502002,000
Pipeline runs per calendar month50010,000100,0001,000,00010,000,000
Pipeline minutes per calendar month2,00025,000200,0002,000,00020,000,000
Steps in one pipeline501002505002,000
Bytes in one push2 GiB5 GiB10 GiB20 GiB50 GiB
Bytes in one package upload500 MiB2 GiB5 GiB10 GiB25 GiB
Bytes in one release asset2 GiB5 GiB10 GiB20 GiB50 GiB
Log bytes kept for one pipeline step4 MiB64 MiB256 MiB512 MiB1 GiB
Service accounts per group or repository10502001,00010,000
Webhooks per group or repository20502005005,000
Environments per group or repository102550100500

The branch and tag limits are agreed rather than counted: creating a branch or a tag past them is not refused.

Three more numbers do not come from a plan at all. Top-level groups one person may own starts at 3 and is raised by an approved request against max_root_groups, up to 1,000. Access tokens per person or service account is a flat 100, and an uploaded avatar is 5 MiB, on every plan.

Reaching a limit refuses the request; it never half-performs it. The answer is 429 TOO_MANY_REQUESTS, and nothing is created, stored or started — a repository that would have taken you past the storage limit is not left half-made. Settings → Usage shows every meter against the effective maximum enforced for you, which is the number to read before you decide whether you need a bigger plan or a single raise. That view is not Owner-gated the way billing is — Reporter on the group is enough — so the people who actually hit a limit can see where they stand without holding the card.

Two ways to get more room: move to a plan whose defaults cover you, through Checkout or the billing portal; or file a limit-increase request naming the one limit that is in your way. The second changes nothing else about what you pay.

Troubleshooting

501 NOT_IMPLEMENTEDon Checkout, the portal, or the Stripe address
Cause
Payments are unavailable on Gitmoap's side, so there is nothing to talk to
What to do
Contact support@gitmoap.com. Reading your plan, listing invoices and the whole limit-increase flow keep working in the meantime
401 UNAUTHORIZEDon a billing call
Cause
No credential on the request, or an expired or malformed token
What to do
Sign in again, or mint a fresh token and retry
400 BAD_REQUESTon the Stripe address
Cause
The Stripe-Signature header is missing or malformed, the timestamp it carries is more than five minutes from Gitmoap's clock, or the body is not a Stripe event
What to do
Resend from Stripe's own dashboard rather than replaying a captured request
401 UNAUTHORIZEDon the Stripe address
Cause
The signature does not verify against the signing secret configured here — a mismatched secret, or a body altered between Stripe and us
What to do
Resend from Stripe's own dashboard. If it keeps failing, contact support@gitmoap.com — the signing secret is configured on Gitmoap's side
403 FORBIDDENon a billing call that names a group
Cause
Your level on the group you named is below Owner. Billing is Owner-only, and no visibility setting opens it up
What to do
Ask an Owner of the top-level group to make the call — an Owner there qualifies on every group in the tree — or to raise your level to Owner
403 FORBIDDENfiling a limit increase from a script
Cause
A request records the person who filed it, so a service-account token is refused
What to do
File it with a personal token instead
401 UNAUTHORIZEDon the review queue, approve, deny or the overrides call, from a token that works elsewhere
Cause
Those four read a signed-in platform administrator, and a personal or service-account token is not one however it is scoped
What to do
Sign in as a platform administrator — gitmoap login for the CLI — and make the call from that session
403 FORBIDDENon the review queue, approve, deny or the overrides call
Cause
You are signed in, but not as a platform administrator. Those four belong to Gitmoap's platform administrators, not to an organisation's Owner
What to do
File a request instead and let a reviewer decide it
403 INSUFFICIENT_SCOPE
Cause
Your token is valid but was minted without the scope this call needs; the response names the missing one
What to do
Mint a new token carrying billing:read, billing:manage or billing:request_limit_increase, whichever the response asked for. Scopes are fixed when a token is minted and cannot be added afterwards
400 BAD_REQUESTon Checkout, naming the plan
Cause
You asked for free, or for a plan Gitmoap publishes no price for
What to do
Ask for a paid plan Gitmoap prices. If the one you need is not sold through Checkout, contact support@gitmoap.com
400 BAD_REQUESTon the portal, mentioning no customer
Cause
No Checkout session has ever been started for this organisation, so Stripe holds no customer to open a portal for
What to do
Start a Checkout session. Creating it is enough — the portal opens from that point on, whether or not anyone finished paying
400 BAD_REQUESTfiling a request, mentioning the current effective limit
Cause
The value you asked for is at or below what you already have
What to do
Read the effective maximum in Settings → Usage and ask for a number above it
400 BAD_REQUESTfiling a request, mentioning the hard ceiling
Cause
Every limit has an absolute maximum no raise passes
What to do
Ask for the ceiling itself. If the ceiling is genuinely the problem, split the work across organisations, each with its own budget
400 BAD_REQUESTfiling a request, mentioning the justification
Cause
It is empty, or longer than 2000 characters
What to do
Write a paragraph or two: what you are building, what stopped, and the number that unblocks it
400 BAD_REQUESTon the overrides call, mentioning a root namespace
Cause
The id you passed names a subgroup
What to do
Pass the id of the top-level group — the one with no parent
400 BAD_REQUESTon the overrides call, naming a limit
Cause
The name is not a limit, or it is a per-person budget rather than an organisation's
What to do
Check the name against the list on the card. max_root_groups is raised through an approved request, not through this call
400 BAD_REQUESTon any call, mentioning the group id
Cause
The id in the URL is not a well-formed id — usually a path like my-org/my-team pasted where an id belongs
What to do
Use the group's id
404 NOT_FOUNDon a group you are sure exists
Cause
Either the group is private and you are not a member, or the id is wrong. On the administrator overrides call it only ever means the id is wrong
What to do
A private group answers 404 rather than 403 so its existence stays private. Check you are a member, then check the id
404 NOT_FOUNDon approve or deny
Cause
The request id is wrong, or the request went with the organisation when it was deleted
What to do
Re-read the queue and take the id from there
409 CONFLICTfiling a request
Cause
An open request for the same limit is already waiting for a decision
What to do
Wait for that decision, or ask the reviewer to take it. Filing again does not move it up the queue
409 CONFLICTon approve or deny
Cause
The request has already been decided, and decisions are final
What to do
Read the request to see which decision landed. To go further, file a new one
429 TOO_MANY_REQUESTSwhile pushing, creating or running something
Cause
You are at a limit. Nothing was partly created
What to do
Open Settings → Usage, find the meter that is full, then free some room, move to a bigger plan, or file a limit increase for that one limit
Checkout finished but the plan still reads Free
Cause
The plan changes when Stripe reports the subscription, a moment after payment, and a subscription whose first charge has not cleared reads incomplete and grants Free
What to do
Re-read the subscription after a few seconds. If it stays incomplete, the first payment did not go through — open the billing portal and check the card
A cancellation made in the portal appears to have done nothing
Cause
Cancelling schedules the end of the period you have paid for rather than ending it now
What to do
Read the subscription: cancel_at_period_end is true and current_period_end is the date the plan drops to Free
A plan change to a smaller plan has not lowered anything
Cause
A downgrade takes effect at the next renewal, so you keep what you paid for until then
What to do
Read current_period_end for the date it applies. An upgrade, by contrast, lands as soon as Stripe reports it
The plan still reads as the paid one after a failed payment
Cause
past_due keeps the plan while Stripe retries the charge, so a transient card failure does not degrade you
What to do
Fix the card in the billing portal. If Stripe gives up, the subscription moves to unpaid and the plan drops to Free
No invoices listed although you have paid
Cause
Invoices are recorded as Stripe reports them, and none has been reported for this payment yet
What to do
Contact support@gitmoap.com. Stripe's own dashboard holds the documents in the meantime
A request was approved but the same operation is still refused
Cause
The applied value clamps to the ceiling, and the limit that stopped you may be a different one, or one counted per repository rather than across the organisation
What to do
Read Settings → Usage: the effective maximum shown there is the number being enforced, and it names which limit it belongs to
An approved max_root_groups did not change the organisation's limits
Cause
That budget belongs to the person who filed the request, not to any organisation
What to do
Confirm by creating a top-level group as the filer; the raise follows them, not the namespace they filed against
An override you set earlier has gone after a later overrides call
Cause
The call merges what you send: named limits are set, limits sent as null are cleared, and anything you leave out is untouched — so a null in a later payload removed it
What to do
Set it again. Send null only for limits you mean to clear

FAQ

Does upgrading charge me twice for the same month?

No. Stripe computes the proration and bills the difference; Gitmoap computes no amount at all. The exact figure appears on the invoice for the period.

Who can see what we pay?

Only Owners of the top-level group. Access to a repository, or membership of a subgroup, grants nothing here, and making the group public changes none of it.

What happens if a payment fails?

Stripe retries on its own schedule and the subscription sits in past_due, which keeps your plan the whole time. Only when Stripe gives up does it move to unpaid and the plan drop to Free.

Do I lose data if we go back to Free?

No. Existing repositories, releases and pipeline history stay exactly as they are. What changes is the ceiling on new growth: anything that would push a meter further past the smaller limit is refused with 429 TOO_MANY_REQUESTS.

Can I get more of one thing without paying more?

Yes — that is what a limit-increase request is for. It raises one limit for one organisation and leaves your plan and your card untouched.

Do we get a free trial?

Only where the plan comes with one. Where it does, Checkout starts the subscription in trialing, you hold the full plan until the trial_end date the subscription reports, and Stripe moves it to active or canceled there.

  • Groupscreating the top-level group a plan attaches to, and the usage and limits views that show where you stand against every effective limit
  • Access tokensminting a token that carries billing:read or billing:manage, and choosing scopes at mint time
  • Pipelinesthe runs and the compute minutes the monthly limits meter
  • Repositoriesthe stored bytes the organisation-wide storage limit counts