PFlux DOCS
GitHub Integration enquiries Start integrating
REFERENCE/ERRORS

Errors

Stable codes, each paired with the action your system should take. Underlying chain messages are never forwarded.

Every error is a stable code. Most carry an action saying what your system should do, so the decision table does not have to be duplicated on your side.

TWO DELIVERY SHAPES

Every endpoint except one returns errors as an HTTP status with { error, action } in the body — the statuses in the tables below. /v1/payments/verify is the exception: it answers HTTP 200 with { valid: false, code } for every one of these outcomes, because “this payment is not proven” is an answer rather than a failure. The codes are the same; only the envelope differs.

Error shape

error response
{
  "error": "INSUFFICIENT_ALLOWANCE",
  "action": "CUSTOMER_ACTION_REQUIRED"
}

Rate-limit and capacity errors add retry_after in seconds and set the Retry-After header. Underlying chain messages are never forwarded — they routinely echo calldata, node URLs and addresses.

Actions

SUCCESSThis period is paid. Mark it and move on.
WAITNot yet provable. Ask again with nothing changed — same hash, same subscription. Never read it as either success or failure.
RETRY_LATERNothing was spent. The identical call is safe to repeat later.
CUSTOMER_ACTION_REQUIREDOnly the customer can resolve it — balance or allowance.
STOP_SUBSCRIPTIONPermanent. Stop billing this subscription.
INVALID_REQUESTThe request is wrong. Retrying returns the same answer forever.

Payment and verification

CODEHTTPMEANING
INVALID_INTENT400Malformed, forged, or minted for another deployment.
INTENT_EXPIRED400Past its expiry. Create a new payment.
AMOUNT_OUT_OF_BOUNDS400Below the minimum a charge can cover, or above the configured ceiling.
INVALID_REFERENCE400The receipt does not contain this payment.
TERMS_MISMATCH400Recipient, amount or fee in the receipt does not match the intent.
WRONG_TOKEN400The expected USDC movements are not in the receipt.
PAYMENT_CONFIRMING409 / 200Not yet provable: either not deep enough, or no receipt seen for that hash. Re-verify the same hash; do not fulfil and do not start a second payment. Delivered inside a 200 by /v1/payments/verify, as a 409 elsewhere.
PAYMENT_ALREADY_PROCESSED409The contract has already settled this exact payment.
TRANSACTION_REVERTED400The transaction failed on chain. Nothing moved.
TRANSACTION_NOT_FOUND404No such transaction.

Subscription and charge

CODEHTTPMEANING
INVALID_SUBSCRIPTION400The capability is malformed, forged or for another deployment.
INVALID_SETUP_TOKEN400Bad setup token.
SETUP_TOKEN_EXPIRED400Setup token past its 24-hour life.
INVALID_CANCEL_TOKEN400Bad cancel token.
CANCEL_TOKEN_EXPIRED400Cancel tokens live 15 minutes.
INVALID_SIGNATURE400The EIP-712 signature does not verify for that payer.
UNSUPPORTED_SIGNATURE_FORMAT400A signature for an account that is not deployed yet. A recurring authorization is replayed for months, so the account must exist first.
SIGNATURE_VALIDATION_TOO_EXPENSIVE400A contract wallet’s validator cost more than we will spend. Not a verdict that the signature is wrong.
PERIOD_OUT_OF_BOUNDS400Outside the configured minimum and maximum period.
NOT_DUE409The period has not opened. next_period_at says when.
ALREADY_CHARGED400This period was already collected — an idempotent success, not a failure.
PERMISSION_REVOKED400Revoked on chain, or outside the signed window. Permanent.
SUBSCRIPTION_EXPIRED409Past the authorization’s end date.
INSUFFICIENT_BALANCE400The payer’s USDC balance is short.
INSUFFICIENT_ALLOWANCE400The allowance was removed or never granted.
PERMISSION_NOT_FOUND404No such authorization on chain.
WRONG_SPENDER400The authorization names a different spender.
GAS_FEE_TOO_HIGH400The gas reimbursement exceeds what the customer signed for.

Service and capacity

None of these spent anything or touched the subscription. All are safe to retry.

CODEHTTPMEANING
RATE_LIMITED429Too many requests. Carries retry_after.
CONCURRENCY_LIMIT429Too many charges in flight at once.
RPC_BUSY503The service is saturated — not your caller specifically.
GAS_TOO_HIGH409Gas moved beyond what this subscription authorized.
GAS_QUOTE_UNAVAILABLE502Gas could not be priced at all. No transaction was attempted.
RELAYER_TX_COST_TOO_HIGH503The transaction would cost more than the relayer will risk.
RELAYER_BUDGET_EXCEEDED503The relayer’s rolling spend budget is exhausted.
RELAYER_NOT_READY503The relayer cannot safely sign right now.
RPC_ERROR502A chain read failed.
RELAYER_ERROR502Transaction submission failed.
INTERNAL_ERROR500An unexpected P2Flux failure.
INVALID_REQUEST400Schema validation failed, or the body was too large.
Something more than a standard integration?
Marketplace flows, platform billing and custom settlement logic.
Discuss an integration