Skip to content
How it worksProductPricingDocs
Sign inGet started

Docs

  • Quickstart
  • Stripe SDK drop-in
  • JSON API
  • Idempotency, modes, errors
  • Signed callbacks
  • Payment methods and routing

Docs

Idempotency, modes and errors

The rules that make retries safe, keep test and live apart, and tell you what went wrong.

Idempotency

Creating money-moving objects needs an Idempotency-Key header: 8 to 255 printable characters, unique per intent (an order id works well). Cortana stores the key with the invoice before any provider is called, so a retry after a timeout returns the original object instead of creating a second one.

Replays
# First call: 201 Created
curl -i https://cortanapay.com/api/v1/invoices -H "Idempotency-Key: order-1042" …

# Same key, same body: 200 OK, Idempotent-Replayed: true, same invoice
# Same key, different body: 409 idempotency_conflict

Reusing a key with a different body is an error on purpose. The Stripe-compatible /v1 routes treat the header as optional because Stripe SDKs always send one.

Test and live

Test and live mode compared
AspectTestLive
Key prefixck_test_…ck_live_…
SeesTest invoices and payments onlyLive invoices and payments only
ProvidersYour Stripe or Whop test keys, or the built-in test providerYour live provider accounts
AvailabilityAlwaysNeeds an active plan

The mode comes from the key, never from a parameter. A test key cannot read, change or void a live invoice, and the dashboard shows one mode at a time.

Errors

Errors use the HTTP status first and a stable code second. Match on the code; messages can change.

Error body
HTTP/1.1 422 Unprocessable Entity

{
  "error": {
    "code": "invalid_amount",
    "message": "An invoice needs at least one item",
    "details": null
  }
}
StatusMeaning
400
Bad request: idempotency_key_required, invalid_idempotency_key, malformed input.
401
invalid_api_key: missing, wrong or revoked.
403
insufficient_scope, live_access_required, workspace_suspended.
404
No such object in this mode.
409
idempotency_conflict, request_in_progress, invoice_payment_in_progress when voiding mid-settlement.
422
Valid JSON, rejected values: amounts, currency, unregistered callback_url.
429
rate_limited. 600 requests a minute per key; wait Retry-After seconds.
5xx
Our side. Retrying with the same Idempotency-Key is safe.

The Stripe-compatible routes answer in Stripe's shape instead (type, code, message, param), with 422 reported as 400.

Many gateways, one place you control. Payments settle into your own accounts. Cortana never holds your funds.

Product

  • How it works
  • Features
  • Pricing
  • FAQ

Developers

  • Quickstart
  • Stripe SDK drop-in
  • JSON API
  • Signed callbacks

Account

  • Sign in
  • Create account

© 2026 Cortana