Billing and plans
- See which plan you are on
- Subscribe to a paid plan
- Change plan, update the card, or cancel
- Read your invoices
- See your AI organization's balance
- Read what each model call cost
- Fund a balance
- Ask for one limit to be raised
- Track a request you filed
- Review the queue
- Approve a request
- Deny a request
- Set an organisation's limits directly
- Keep the plan in step with Stripe
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:readto read the subscription, the invoices, your own requests and an AI organization's balance and ledger;billing:manageto open Checkout or the billing portal;billing:request_limit_increaseto file a request;billing:adminfor 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 loginfor the CLI — and a personal or service-account token is refused there with401 UNAUTHORIZEDhowever 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 itThe subscription's status is what grants the plan:
| Subscription status | What you get |
|---|---|
trialing | the plan you subscribed to, until the trial ends |
active | the plan you subscribed to |
past_due | the 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, canceled | Free |
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.
gitmoap billing get-subscription --group-id <id>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.
gitmoap billing create-checkout-session \ --group-id <id> \ --cancel-url <cancel url> \ --success-url <success url> \ --tier free|pro|team|enterprisecurl -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.
gitmoap billing create-portal-session \ --group-id <id> \ --return-url <return url>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.
gitmoap billing list-invoices --group-id <id>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.
gitmoap billing get-group-balance --group-id <id>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.
gitmoap billing list-group-usage-entries --group-id <id>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.
gitmoap billing create-admin-balance-adjustment \ --root-group-id <id> \ --amount-micros <n> \ --note <note>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.
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>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.
gitmoap billing list-limit-increase-requests --group-id <id>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.
gitmoap billing list-admin-limit-increase-requestscurl -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.
gitmoap billing approve-limit-increase-request --request-id <id>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.
gitmoap billing deny-limit-increase-request \ --request-id <id> \ --decision-note <decision note>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.
gitmoap billing set-namespace-limit-overrides \ --root-group-id <id> \ --overrides '<json>'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.
gitmoap billing stripe-webhook --body <body>curl -X POST https://api.gitmoap.example/billing/stripe/webhookWe 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)
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 type401Unauthenticated — no credential, or an invalid one403Forbidden — the caller's access level or token scope is insufficient404Not 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_tieris the only place it becomes aPlanTier. - trial_endobjectoptional
POST/groups/{group_id}/billing/checkout-sessionbilling:manage
Start a Stripe Checkout Session to subscribe the namespace to a paid tier
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 checkout401Unauthenticated — no credential, or an invalid one403Forbidden — the caller's access level or token scope is insufficient404Not found — or found and private, which is masked as absent409The request conflicts with the resource's current state; `reason` says how501Billing 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
Token scope
billing:manage
Send
Path
- group_iduuidAny group in the namespace
Body
- return_urlstring
Refuses
400No Stripe customer for this namespace yet401Unauthenticated — no credential, or an invalid one403Forbidden — the caller's access level or token scope is insufficient404Not found — or found and private, which is masked as absent409The request conflicts with the resource's current state; `reason` says how501Billing not configured on this deployment
Receive
- portal_urlstring
GET/groups/{group_id}/billing/invoicesbilling:read
List the namespace's invoices, newest first
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 type401Unauthenticated — no credential, or an invalid one403Forbidden — the caller's access level or token scope is insufficient404Not 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
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
PlanLimitscap plus the user-scopedmax_root_groups. The identity a limit-increase request and a namespace override are keyed by. - requested_valueint64
Refuses
400Invalid request401Unauthenticated — no credential, or an invalid one403Forbidden — the caller's access level or token scope is insufficient404Not found — or found and private, which is masked as absent409A 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
PlanLimitscap plus the user-scopedmax_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.
Appliedis the terminal success state (the override was written);Approvedexists for symmetry but the approve path applies immediately, so a persisted request is never leftApproved-but-not-Applied. - updated_atstring
GET/groups/{group_id}/limit-increase-requestsbilling:read
List the namespace's own limit-increase requests
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 type401Unauthenticated — no credential, or an invalid one403Forbidden — the caller's access level or token scope is insufficient404Not 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
PlanLimitscap plus the user-scopedmax_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.
Appliedis the terminal success state (the override was written);Approvedexists for symmetry but the approve path applies immediately, so a persisted request is never leftApproved-but-not-Applied. - updated_atstring
- next_cursorobjectoptional
GET/admin/limit-increase-requestsbilling:admin
Review queue: limit-increase requests across all namespaces (platform admin)
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 one403Forbidden — 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
PlanLimitscap plus the user-scopedmax_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.
Appliedis the terminal success state (the override was written);Approvedexists for symmetry but the approve path applies immediately, so a persisted request is never leftApproved-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 referenceToken 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 type401Unauthenticated — no credential, or an invalid one403Forbidden — the caller's access level or token scope is insufficient404Not found409Already 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
PlanLimitscap plus the user-scopedmax_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.
Appliedis the terminal success state (the override was written);Approvedexists for symmetry but the approve path applies immediately, so a persisted request is never leftApproved-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 referenceToken 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 type401Unauthenticated — no credential, or an invalid one403Forbidden — the caller's access level or token scope is insufficient404Not found409Already 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
PlanLimitscap plus the user-scopedmax_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.
Appliedis the terminal success state (the override was written);Approvedexists for symmetry but the approve path applies immediately, so a persisted request is never leftApproved-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 referenceToken scope
billing:admin
Send
Path
- root_group_iduuidThe namespace's top-level group
Body
- noteobjectoptional
- overridesobjectLimit-name → value (or
nullto clear). Keys must be namespaceLimitKeys.
Refuses
400Not a namespace's top-level group, an unknown limit, or a value above the limit's ceiling401Unauthenticated — no credential, or an invalid one403Forbidden — the caller's access level or token scope is insufficient404Not found — or found and private, which is masked as absent409The 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
Token scope
None — this one is public
Send
Nothing — the address is the whole request.
Refuses
400The `Stripe-Signature` header is missing401Signature verification failed501Billing not configured on this deployment
Receive
No body.
GET/groups/{group_id}/billing/balancebilling:read
A namespace's prepaid balance.
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 type401Unauthenticated — no credential, or an invalid one403Forbidden — the caller's access level or token scope is insufficient404Not 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.
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 type401Unauthenticated — no credential, or an invalid one403Forbidden — the caller's access level or token scope is insufficient404Not 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 referenceToken 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 range401Unauthenticated — no credential, or an invalid one403Forbidden — the caller's access level or token scope is insufficient404Not found — or found and private, which is masked as absent409The request conflicts with the resource's current state; `reason` says how429Adjustment 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.
| Limit | Free | Pro | Team | Enterprise | Ceiling |
|---|---|---|---|---|---|
| Stored bytes across the organisation | 5 GiB | 100 GiB | 1 TiB | 10 TiB | 100 TiB |
| Repositories per group | 20 | 200 | 2,000 | 20,000 | 100,000 |
| Members per group or repository | 50 | 200 | 1,000 | 5,000 | 50,000 |
| Branches per repository | 1,000 | 5,000 | 20,000 | 50,000 | 500,000 |
| Tags per repository | 1,000 | 5,000 | 20,000 | 50,000 | 500,000 |
| Open merge requests per repository | 100 | 500 | 2,000 | 5,000 | 50,000 |
| Open work items per group or repository | 5,000 | 20,000 | 100,000 | 500,000 | 5,000,000 |
| Releases per repository | 1,000 | 5,000 | 20,000 | 50,000 | 500,000 |
| Pipeline runs in flight at once | 2 | 10 | 50 | 200 | 2,000 |
| Pipeline runs per calendar month | 500 | 10,000 | 100,000 | 1,000,000 | 10,000,000 |
| Pipeline minutes per calendar month | 2,000 | 25,000 | 200,000 | 2,000,000 | 20,000,000 |
| Steps in one pipeline | 50 | 100 | 250 | 500 | 2,000 |
| Bytes in one push | 2 GiB | 5 GiB | 10 GiB | 20 GiB | 50 GiB |
| Bytes in one package upload | 500 MiB | 2 GiB | 5 GiB | 10 GiB | 25 GiB |
| Bytes in one release asset | 2 GiB | 5 GiB | 10 GiB | 20 GiB | 50 GiB |
| Log bytes kept for one pipeline step | 4 MiB | 64 MiB | 256 MiB | 512 MiB | 1 GiB |
| Service accounts per group or repository | 10 | 50 | 200 | 1,000 | 10,000 |
| Webhooks per group or repository | 20 | 50 | 200 | 500 | 5,000 |
| Environments per group or repository | 10 | 25 | 50 | 100 | 500 |
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-Signatureheader 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 loginfor 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:manageorbilling: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_groupsis 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-teampasted 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
404rather than403so 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
incompleteand 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_endis true andcurrent_period_endis 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_endfor 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_duekeeps 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
unpaidand 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
nullare cleared, and anything you leave out is untouched — so anullin a later payload removed it - What to do
- Set it again. Send
nullonly 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.
Related
- 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:readorbilling: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