Billing Block Errors
Explains what a billing block is, how BillingBlockEnvelope errors surface across the HTTP API, agent SSE stream, CLI, and MCP server, and how users and developers can resolve them.
A billing block is a hard stop that MarkDocket applies when a requested action cannot be authorized under your current plan or payment status. Instead of silently failing or returning a generic error, every surface of the platform — the REST API, the agent streaming interface, the CLI, and the MCP server — returns a structured BillingBlockEnvelope that tells you exactly why the action was blocked and what you need to do to unblock it.
What is a BillingBlockEnvelope?
A BillingBlockEnvelope is a typed, versioned error object defined in the shared billing contract that all MarkDocket services use. Every billing block, regardless of where it originates, carries the same fields:
| Field | Description |
|---|---|
contractVersion | The billing contract version that produced this block. |
reason | A machine-readable code identifying why the block occurred (see Reasons and required actions). |
requiredAction | The specific action you must take to resolve the block. Always paired 1-to-1 with reason. |
message | A human-readable explanation. |
The reason and requiredAction fields are always a matched pair. If they do not match the canonical mapping, the envelope is considered invalid and is rejected by the platform before it reaches your client.
Reasons and required actions
Each block reason maps to exactly one required action:
reason | requiredAction | What it means |
|---|---|---|
no_payment_method | add_payment_method | No payment method is attached to your account. Add one in billing settings before the action can proceed. |
payment_failed | resolve_payment | A recent charge failed. Resolve the outstanding payment in your billing settings. |
quota_exceeded | upgrade_plan | You have reached a usage limit on your current plan. Upgrade to a higher tier or wait for your quota to reset. |
subscription_inactive | reactivate_subscription | Your subscription is paused or cancelled. Reactivate it to resume access. |
feature_not_available | upgrade_plan | The feature you requested is not included in your current plan. |
Billing blocks are not retryable
How blocks surface by interface
HTTP API — 402 Payment Required
When a billing block occurs during a REST API call, the server responds with HTTP status 402 and a JSON body that is a BillingBlockEnvelope:
{
"contractVersion": "2026-07-12-payg-v1",
"reason": "no_payment_method",
"requiredAction": "add_payment_method",
"message": "No payment method is attached to your account."
}Your API client should check for 402 responses and surface the requiredAction to the user. Do not retry a 402 — the request will continue to fail until the underlying billing issue is resolved.
Agent SSE stream — billing_required event
During an agent conversation, billing authorization happens before the turn begins. If authorization fails, or if a billing block arises mid-stream (for example, during a tool call), the SSE stream emits a billing_required event instead of continuing:
event: billing_required
data: {"contractVersion":"2026-07-12-payg-v1","reason":"quota_exceeded","requiredAction":"upgrade_plan","message":"..."}The stream is terminated after this event. The web application intercepts billing_required events at the transport layer and automatically presents a resolution dialog — individual agent call sites do not need to handle this event themselves.
If you are consuming the SSE stream directly (for example, through the API with a personal API key), listen for event: billing_required and treat it as a terminal event for that turn.
Automation runs — suspended state
When a billing block occurs inside an automation run, the run is suspended with a billing_blocked status rather than marked as failed. This preserves the run's state so it can be resumed after you resolve the billing issue. Suspended runs appear in your Automations dashboard with a "Billing required" indicator and the specific requiredAction.
Once you have resolved the underlying issue, you can resume the run from the dashboard. The run will restart from the point at which it was suspended.
CLI — formatted error output
The @markdocket/cli package translates billing blocks into human-readable CLI errors. When a command encounters a billing block, it exits with a non-zero status code and prints:
Error: Billing required — quota_exceeded
Required action: upgrade_plan
Visit https://app.markdocket.com/settings/billing to resolve this.The exit code is non-zero, so shell scripts and CI pipelines can detect billing blocks programmatically. The reason and requiredAction values are always included in the output so they can be parsed if needed.
MCP server — structured error result
When the MarkDocket MCP server (either the stdio server from @markdocket/cli or the hosted MCP endpoint) encounters a billing block during a tool call, it returns an MCP tool result with isError: true and a structuredContent field containing the full BillingBlockEnvelope:
{
"isError": true,
"structuredContent": {
"contractVersion": "2026-07-12-payg-v1",
"reason": "payment_failed",
"requiredAction": "resolve_payment",
"message": "A recent charge failed on your account."
}
}MCP clients and AI assistants using MarkDocket tools should inspect isError and, when structuredContent.requiredAction is present, surface the billing resolution link to the user rather than retrying the tool call.
Resolving a billing block
All billing blocks are resolved through your account's billing settings at https://app.markdocket.com/settings/billing. The table below maps each requiredAction to the specific step:
requiredAction | Steps to resolve |
|---|---|
add_payment_method | Go to Settings → Billing → Payment methods and add a credit or debit card. |
resolve_payment | Go to Settings → Billing → Payment history and follow the prompts to retry or update the failed payment. |
upgrade_plan | Go to Settings → Billing → Plan and select a plan that includes the feature or quota you need. |
reactivate_subscription | Go to Settings → Billing → Subscription and reactivate your plan. |
After resolving the issue, retry the original action. If you were in the middle of an automation run, resume it from the Automations dashboard.
Agent turns cannot be automatically resumed
Handling billing blocks in custom integrations
If you are building on top of the MarkDocket API or MCP server, follow these guidelines:
- Always check for HTTP
402before retrying failed requests. A402with aBillingBlockEnvelopebody should be surfaced to the user with themessageandrequiredAction, not silently retried. - Treat
billing_requiredSSE events as terminal. Close the stream and present therequiredActionto the user. - Treat MCP
isError: truewith arequiredActioninstructuredContentas a user-action-required state, not a transient error. Do not pass it back to the model as something to retry automatically. - Do not parse or validate the
contractVersionfield in your own code. The platform guarantees that envelopes presented to clients are always valid and self-consistent. If you need to programmatically distinguish billing blocks from other errors, check for the presence of therequiredActionfield alongside the402status code orisError: trueflag.
Frequently asked questions
Why does the platform return 402 instead of 403?
HTTP 402 Payment Required is the correct status code for this class of error. A 403 Forbidden indicates that the server understood the request but the authenticated identity does not have permission to perform it — a permanent access control decision. A 402 indicates that the action is otherwise allowed but requires payment or billing resolution to proceed.
Will a billing block cause data loss?
No. Billing blocks are applied before any data-modifying operation begins. If a block occurs mid-automation, the run is suspended cleanly at a safe checkpoint. No partial writes or corrupted state result from a billing block.
Can I test billing block handling without triggering a real block?
If you are using the StartWise partner embed or building an integration against the API, the MarkDocket developer preview environment includes simulated billing_required events. Contact support for access to the preview environment.
Pre-Authorization and Reservations
Explains how MarkDocket pre-authorizes billing capacity before agent turns and other operations, documents the turn state machine and CAS transitions, describes reservation lifecycle, and explains what happens to reservations and files on expiry or cancellation.
Usage Metering
Explains how MarkDocket records usage events through a transactional outbox, the retry and dead-letter behavior of the drain loop, and the distinction between product usage metering and direct COGS metering.