Agent-readable docs index: /llms.txt. Full docs in one file: /llms-full.txt. Download /docs.zip to grep all markdown files locally.

Errors of the Mesub API

Every error has the same body:
{ "statusCode": 409, "message": "You are already subscribed to this plan.", "error": "Conflict", "code": "already_subscribed", "retryable": false, "request_id": "req_4f8KzQ2nVb7XcR1mT9wLp3sD" }
FieldWhat it says
statusCodeThe HTTP status, repeated
messageA sentence for a person. A validation error answers a list of them. It may be reworded
errorThe status's name
codeWhat your code reads
retryableWhether the same request, sent again unchanged, may succeed later
request_idThe request's id, as the Mesub-Request-Id header says it. Quote it to Mesub support
Branch on code, never on message. A code is never moved to another status or reused, and is renamed only in a new Mesub-Version, but new ones are added: keep a default branch.
One exception was made before the first integrator, within 2026-10-02: plan_deleted became plan_removed, and plan_rebuilt became plan_replaced. The old names are no longer answered. Code written against them must branch on the new ones.
When retryable is true, the same request sent again unchanged may succeed later; a Retry-After header says when, in seconds. It never means "retry at once". Every route is safe to call twice.
Each route's page lists the codes that route answers. This page lists them all.

General

codeStatusWhen
invalid_request400A parameter is missing or malformed
unsupported_version400Mesub-Version names a version not served
missing_api_key401No API key was sent
invalid_api_key401The key is not one Mesub issued
forbidden403The request is understood and refused
not_found404Nothing at that address
conflict409The request does not fit the current state
payload_too_large413The body is too large
rate_limited429Too many calls. Retryable
internal_error500A failure on Mesub's side. Retryable
unavailable503Mesub cannot answer right now. Retryable
network_unavailable503The Solana network does not answer. Retryable

Plans

codeStatusWhen
plan_not_found404No plan of yours under that slug
plan_not_on_chain409The plan was never published
plan_removed409The plan is gone from the chain
plan_sunset409The plan takes no new subscribers
plan_ended409The plan is past its end date: see below
plan_replaced409Another plan now stands at its address
plan_mismatch409The plan on chain is not the one Mesub recorded
receiver_account_missing409The wallet that receives has no account for the token
receiver_account_frozen409The account the plan pays into is frozen
receiver_account_needs_memo409That account requires a memo on every transfer in
receiver_account_confidential_only409That account takes confidential transfers only
mint_paused409The token's issuer paused it
mint_transfer_hook409The token's issuer made its transfers run a program
mint_not_on_chain400The token does not exist on chain
plan_ended is what Create a subscription answers once a plan's end date has passed. In the dashboard, the same code refuses closing that plan to new subscribers, changing its names, and retrying one of its payments by hand: nothing can be charged on it any more.
Three more are answered in the dashboard only, when you create a plan with an end date:
codeStatusWhen
end_date_too_soon400The end date is less than one billing period, plus five minutes, away
end_date_too_far400The end date is more than 100 years away
end_date_stale409The plan's end date no longer holds as you sign its creation
None of the three is retryable: change the date. An end date is counted in Unix seconds, and end_date_too_far is what a date sent in milliseconds gets.
The dashboard also refuses a plan on a token nobody could pay in, before you sign: mint_not_a_token (400, no token program owns that address), mint_paused and mint_transfer_hook (409), and mint_frozen_by_default, mint_non_transferable, mint_confidential_only, mint_extension_unknown and mint_display_scaled (400). How it works says what each means.

Subscribing

codeStatusWhen
already_subscribed409This wallet already holds this plan
insufficient_balance409The wallet cannot pay the first period
insufficient_sol409The wallet holds too little SOL for the rent, the fee and its reserve
seat_cap_reached409The project is at its subscriber limit
pending_cap_reached429Too many subscriptions wait for a signature. Retryable
wallet_mismatch409The wallet is not the one the subscription was created for
payment_pending409A payment on it failed and is being retried
subscription_cancelled409It was cancelled already
subscription_stopped409It stopped after missed payments
subscription_terms_changed409The plan's terms changed since it was created
comeback_in_flight409A return to this plan is being confirmed. Retryable
comeback_landed409A return to this plan already landed
comeback_period_rolling409A return while its billing period turns. Retryable

Signing and sending

codeStatusWhen
terms_missing403No signed terms came with the transaction
terms_expired403The terms were signed too late. Create again
invalid_terms_signature403The signature is not the wallet's, over those terms
terms_used403Those terms were already used
terms_changed409The terms no longer match the plan
not_our_transaction400The transaction is not the one Mesub built
transaction_not_built409Nothing was built for this subscription yet
transaction_expired409The transaction expired before it was sent
transaction_refused409The chain refused the transaction
not_awaiting_signature409The subscription is past the signing step
subscription_changed409It changed while the request ran. Retryable
After transaction_expired, nothing was sent and the same submit cannot land. Ask for a fresh transaction, have the wallet sign it, and sign the terms again if terms.message changed.

Managing

codeStatusWhen
subscription_not_found404No subscription of your project under that id
subscription_not_active409Cancel: it is not active, unpaid or stopped
subscription_not_cancelled409Resume or close: nothing cancelled it. Cancel a stopped one first
subscription_ended409Resume: the paid period is over
close_too_early409Close: its end has not passed yet
subscription_not_on_chain409It is closed already
nothing_to_confirm400A confirm before any transaction was built

Retrying a payment

What Retry a payment answers besides the codes above:
codeStatusWhen
subscription_not_late409It is not unpaid: only a late payment is retried
subscription_paused409A parked seat: nothing charges it until a seat frees up
retry_too_soon409The wait since the last retry is not over. Retryable
pull_running409A charge of it is running now. Retryable
retry_cannot_succeed409It would fail whatever the wallet holds: late_reason
retries_spent409On Free, the missed period's three retries are spent
retry_deadline_passed409On Free, the missed period ends too soon, or has ended

Events

codeStatusWhen
event_not_found404No event of your project under that id, in the window