> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gigstack.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage account billing

> Integration guide for Manage account billing

Read the current plan, usage, eligible plans and invoice history, then start a plan change or open the billing portal. Billing affects the whole billing account, including its other teams.

Use a verified personal MCP credential or a signed-in Firebase user. A team API key cannot act as its creator. Current unblocked team members can read summary, plans, invoice history and fiscal details. Changes and operation recovery require a current billing-account administrator.

## Read the account and choose an eligible plan

```bash theme={null}
export GIGSTACK_API_BASE="https://api.gigstack.io/v2"
export TEAM_ID="team_example"

curl --fail-with-body "$GIGSTACK_API_BASE/teams/$TEAM_ID/billing/summary" \
  -H "Authorization: Bearer $GIGSTACK_API_KEY"

curl --fail-with-body "$GIGSTACK_API_BASE/teams/$TEAM_ID/billing/plans" \
  -H "Authorization: Bearer $GIGSTACK_API_KEY"
```

Inspect `data.billing_account_id`, `data.can_manage` and `data.provider_environment`. `effect_scope` is `billing_account_shared`. Credential `livemode` selects business data elsewhere; it does **not** select the account billing environment. Staging always uses sandbox billing. Production follows the canonical account billing configuration.

The summary includes the current plan, credits and available usage counters. A `null` counter means unavailable, not zero. Subscription reads return at most 100 subscriptions and expose `subscriptions_has_more`. Eligible plans follow the same hidden-plan and team-volume rules as the app. Use a returned plan ID and version; do not submit a Stripe price ID. Price and invoice amounts use minor units.

## Start checkout with an operation ID

Generate and save a new UUID v4 before sending a change. This lets you read the same operation if the connection drops. Keep its team, account, provider environment and exact request together; do not log credentials, fiscal input or hosted payment URLs.

```bash theme={null}
OPERATION_ID="$(python3 -c 'import uuid; print(uuid.uuid4())')"
printf '%s\n' "$OPERATION_ID"

curl --fail-with-body "$GIGSTACK_API_BASE/teams/$TEAM_ID/billing/checkout" \
  -H "Authorization: Bearer $GIGSTACK_API_KEY" \
  -H 'Content-Type: application/json' \
  -d "{\"operation_id\":\"$OPERATION_ID\",\"plan_id\":\"PLAN_FROM_LIST\",\"billing_cycle\":\"monthly\"}"
```

Replace `PLAN_FROM_LIST` with an eligible plan. An optional `plan_version` must still be current. `intro: true` cannot be combined with `trial_id`; actual eligibility is checked by the server. Free and free-plus plans accept monthly billing only. Accounts on pricing v3 cannot use legacy checkout or upgrade.

Inspect `data.status` and `data.result`. A `handoff_ready` operation with `result.kind: "checkout"` provides a hosted URL for the person to finish payment. Receiving this URL does not mean the plan changed. Some free-plan changes can complete without a hosted checkout.

The account holds one billing write lock per provider environment. An open checkout keeps that lock until completion or expiry is confirmed. Sending the same operation ID and identical parameters reads the existing operation without replaying the write. Reusing an ID with different parameters returns a conflict.

## Read back an uncertain or pending change

```bash theme={null}
curl --fail-with-body "$GIGSTACK_API_BASE/teams/$TEAM_ID/billing/operations/$OPERATION_ID" \
  -H "Authorization: Bearer $GIGSTACK_API_KEY"

curl --fail-with-body -X POST \
  "$GIGSTACK_API_BASE/teams/$TEAM_ID/billing/operations/$OPERATION_ID/reconcile" \
  -H "Authorization: Bearer $GIGSTACK_API_KEY" \
  -H 'Content-Type: application/json' -d '{}'
```

Reconciliation reads the exact local/provider operation markers and never repeats a write. An open checkout can remain `handoff_ready`. A `failed` or `outcome_unknown` result is unsuccessful even when the HTTP response is `200`. After a timeout or `billing_result_unconfirmed`, read this original operation before deciding the next action; do not automatically create a new operation ID and retry.

Operation timestamps are milliseconds. Provider subscription, invoice and checkout dates are seconds. After ten minutes, an unresolved processing operation reads as `outcome_unknown`. A signed-in Firebase billing administrator can explicitly acknowledge unconfirmed effects and release its lock through `POST /operations/{id}/resolve`. This preserves the unknown outcome and permits a **new** operation; it does not cancel, roll back or prove absence of the old effect. Personal MCP credentials cannot perform this browser recovery.

## Cancel an abandoned checkout

To expire an open checkout, generate a **different** UUID v4 and send it as `operation_id` to `POST /operations/{original_checkout_operation_id}/cancel`. Read and reconcile the new cancellation operation ID afterward. This is available to current billing administrators using a verified personal credential.

A confirmed expiry completes the cancellation and makes the original checkout `cancelled`, with its hosted URL removed. If checkout already completed, cancellation fails with `checkout_already_completed` and the original becomes `completed`; manage the subscription through the billing portal. During an uncertain cancellation, the original reads as unknown and points to the cancellation operation. Do not reuse the old checkout link or retry expiry automatically.

## Change a subscription or payment method

`POST /upgrade` accepts a new `operation_id`, eligible `plan_id`, `billing_cycle`, and optional quantity. It requires exactly one manageable subscription and preserves the existing proration behavior. Inspect the operation result and read the account summary afterward.

`POST /portal` accepts a new `operation_id` and one intent:

| Intent | Hosted task |
| - | - |
| `manage` | Manage billing in the provider portal |
| `cancel_subscription` | Review and confirm subscription cancellation |
| `update_payment_method` | Update the account payment method |

The result is a hosted handoff, not confirmation that the task happened. Creating the portal link releases the billing write lock. Return URLs are configured by the application; callers cannot supply an arbitrary redirect.

## Read invoices and update fiscal details

`GET /history?limit=20` returns invoices at `data.data`, with `data.has_more` and `data.cursor`. Pass the cursor back unchanged. It is bound to the account, provider environment and customer. Hosted invoice/PDF URLs are sensitive; show them only to the intended user.

`GET /fiscal` returns the current billing fiscal profile. This read does not repair local mirrors or synchronize Stripe. `stripe_synced: null` means no synchronization was attempted.

`PATCH /fiscal` accepts a new `operation_id` and a `fiscal` object containing `legal_name`, `rfc`, `tax_system`, `use`, and `address.zip` (five digits). Optional email, phone and address fields can be cleared with `null`. Existing SAT validation still applies. Inspect the operation result: `stripe_synced: false` means local fiscal data may have been saved while provider synchronization failed. Reconcile and read back before retrying.

## Troubleshooting

| Result | Next step |
| - | - |
| `401` | Use a verified personal credential; a team key cannot impersonate a person. |
| `403` | Check current team membership and billing-account administrator access. |
| `409` | Read the existing operation and account state. Check for an active checkout, stale plan version, changed parameters or ambiguous provider customer. |
| `502` / interrupted response | Read the original operation ID before sending another write. |
| `503` | Check the explicit runtime project, internal service identity and configured app origin. |

These contracts are covered by offline validation. Provider and deployment verification must use the intended environment and records authorized for that run.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.