Curated reference

API Surface by Integration Task

Start here for the endpoints most native checkout integrations need. Use the full OpenAPI reference when you need every schema and response field.

Checkout Sessions and Embedded Checkout

Create checkout sessions from your backend, render the hosted iframe in the browser, and complete buyer-facing payment flows.

POST/api/v1/checkout-sessions/embed-tokenServer-side

Create a payment-ready proxy checkout session.

X-API-KeyGuide
Implementation details

Use this for payment-only provider proxy mode when your application owns cart, shipping, and order summary UI. The response returns a Throttle session id plus hosted and embedded URLs.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Request body

FieldTypeRequiredDescription
amountintegerYesAmount to charge in minor units, for example 2599 for $25.99.
currencystringYesThree-letter ISO 4217 currency code.
countrystringNoTwo-letter ISO 3166-1 country code. Defaults to US.
Default: US
externalCartIdstringNoYour cart reference. Stored on session metadata for reconciliation.

Responses

200Session created and embed URLs returned.

Response fields

FieldTypeRequiredDescription
checkoutSessionIdstringYesDurable Throttle session id. Use this as the React embed sessionId.
embedTokenstringYesShort-lived provider embed JWT. The hosted iframe can re-mint it later.
hostedUrlurlYesStandalone hosted checkout URL.
embedUrlurlYesChromeless iframe URL for embedded checkout.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
402workspace_not_liveA production-environment credential was used but the workspace has not completed the go-live flow (lifecycleStage is still sandbox).Use a non-production environment key for sandbox testing, or complete the go-live action in the dashboard to unlock production paths.
402workspace_not_entitled_for_liveA production-environment credential was used but the workspace does not have an active paying subscription (and is not a partner). Production payments are paused.Subscribe (or restore your subscription) from the workspace billing page to accept production payments. Non-production environment keys remain fully functional.
402trial_expiredThe workspace trial period has ended and no payment method is on file.Add a payment method and subscribe from the workspace billing page.
400allowed_methods_unsupportedallowedMethods was sent to the payment-only embed-token endpoint. The Gr4vy widget renders the methods configured on your connection and cannot be filtered here.Remove allowedMethods. To restrict methods, configure the Gr4vy connection, or use the full hosted checkout where allowedMethods filters the selection.
422no_gr4vy_connectionThe merchant does not have an active payment connection.Connect a payment processor before creating card checkout sessions.

SDK coverage

@usethrottle/checkout-sdk/server · Server-side SDK. Pair the returned session id with @usethrottle/checkout-sdk in React.

  • createCheckoutClient().createEmbedToken(input)

Never mint embed tokens from the browser. The React SDK renders the session id returned by this server helper.

Create session
curl -X POST https://api.usethrottle.dev/api/v1/checkout-sessions/embed-token \
  -H "x-api-key: $THROTTLE_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "amount": 2599,
    "currency": "USD",
    "country": "US",
    "externalCartId": "cart_123"
  }'

Production notes

  • Never call this endpoint directly from a browser; it requires your secret API key.
  • The session id is the durable handle. The embed token is short-lived and can be refreshed by the hosted checkout page.
POST/api/v1/checkout/sessionsServer-side

Create a cart-backed hosted checkout session.

X-API-KeyGuide
Implementation details

Use this when Throttle owns or can reference the cart that should become an order. This is the preferred session creation path for native carts, subscriptions, collect flags, and full checkout.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Request body

FieldTypeRequiredDescription
applicationIduuidYesApplication that owns the checkout session.
cartIduuidNoThrottle native cart id. Required unless externalCartId is provided.
externalCartIdstringNoMerchant/provider cart reference. Required unless cartId is provided.
returnUrlurlYesBuyer return URL after hosted checkout success.
cancelUrlurlYesBuyer return URL when checkout is cancelled.
customerEmailstringNoBuyer email used for checkout and recurring setup when customer is not supplied.
customerobjectNoOptional prefill object with customerId, externalCustomerId, email, names, phone, shippingAddress, billingAddress, and metadata.
allowedMethodsstring[]NoOptional card/net30 payment method allowlist for this session.
paymentTerms.netNinteger | nullNoOptional cart-level Invoice Terms override, 0-365. Customer netN still wins; null clears the cart override.
recurringobjectNoSubscription intent: plan, interval, amount, trialDays, planName, and create mode auto/manual.
collectobjectNoControls required checkout fields. shippingAddress defaults to true; billingAddress defaults to false.
discountCodestringNoOptional promotion code to validate and apply synchronously during session creation.
metadataobjectNoUp to 50 keys and 10 KB of merchant-owned JSON metadata.

Responses

201Checkout session created.

Response fields

FieldTypeRequiredDescription
idstringYesSession id used by hosted checkout and React embed components.
statusopen | completed | expired | cancelledYesSession lifecycle state.
hostedUrl, embedUrlurlNoHosted and iframe-ready checkout URLs when returned by the service.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
402workspace_not_liveA production-environment credential was used but the workspace has not completed the go-live flow (lifecycleStage is still sandbox).Use a non-production environment key for sandbox testing, or complete the go-live action in the dashboard to unlock production paths.
402workspace_not_entitled_for_liveA production-environment credential was used but the workspace does not have an active paying subscription (and is not a partner). Production payments are paused.Subscribe (or restore your subscription) from the workspace billing page to accept production payments. Non-production environment keys remain fully functional.
402trial_expiredThe workspace trial period has ended and no payment method is on file.Add a payment method and subscribe from the workspace billing page.
422discount_invaliddiscountCode is expired, inactive, over limit, or not valid for this cart.Preview the code first or retry session creation without the code.

SDK coverage

@usethrottle/checkout-sdk/server · Server-side checkout SDK.

  • createCheckoutClient().createSession(input)

@usethrottle/checkout-sdk/server creates the session; @usethrottle/checkout-sdk renders and tracks it in React.

Create cart-backed session
curl -X POST https://api.usethrottle.dev/api/v1/checkout/sessions \
  -H "x-api-key: $THROTTLE_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "applicationId": "00000000-0000-0000-0000-000000000000",
    "cartId": "11111111-1111-1111-1111-111111111111",
    "returnUrl": "https://shop.example.com/thank-you",
    "cancelUrl": "https://shop.example.com/cart",
    "allowedMethods": ["card", "net30"],
    "paymentTerms": { "netN": 45 },
    "collect": { "shippingAddress": true, "billingAddress": true }
  }'
GET/api/v1/checkout-sessions/{id}/embed-tokenBrowser-safe

Refresh the iframe embed token for an existing session.

Session idGuide
Implementation details

The hosted checkout app calls this without a merchant API key so buyers can load or reload a checkout after the original embed JWT expires.

Path parameters

FieldTypeRequiredDescription
idstringYesOpen checkout session id.

Responses

200Fresh embed token and payment processor context.

Response fields

FieldTypeRequiredDescription
embedTokenstringYesFresh provider embed JWT.
amount, currencyinteger, stringNoAmount and currency resolved from session metadata, cart totals, or the latest calculation snapshot.
gr4vyCheckoutSessionIdstringNoProcessor-side checkout session id.

Common errors

StatusCodeCauseFix
404not_foundNo checkout session exists for the supplied id.Create a new session and update the iframe src.
410session_expiredThe checkout session expired.Return the buyer to your cart and create a new checkout session.
422session_not_openThe session is completed, cancelled, expired, or otherwise not open.Do not re-use completed sessions. Start a new checkout.

Production notes

  • Most workspaces do not call this directly; the hosted checkout and React SDK paths handle refresh during render.
GET/api/v1/checkout-sessions/{id}/payment-methodsBrowser-safe

List eligible payment methods for a checkout session.

Session idGuide
Implementation details

The iframe uses this to decide which payment method tiles to show. The server checks connector eligibility and then applies the session allowedMethods filter.

Path parameters

FieldTypeRequiredDescription
idstringYesOpen checkout session id.

Responses

200Eligible payment method list.

Response fields

FieldTypeRequiredDescription
methods[].methodcard | net30 | stringYesPayment method key used by the completion payload.
methods[].displayNamestringYesBuyer-facing method label.
methods[].connectorIdstringNoConnector that supplied the method.

Common errors

StatusCodeCauseFix
404session_not_foundThe session id is unknown.Create a new session and re-render checkout.
POST/api/v1/checkout-sessions/{id}/completeBrowser-safe

Complete a buyer-facing checkout session.

Session idGuide
Implementation details

Called by the hosted iframe after the buyer submits payment. The session id scopes the operation; your backend should listen for webhooks rather than calling this directly.

Headers

FieldTypeRequiredDescription
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Path parameters

FieldTypeRequiredDescription
idstringYesOpen checkout session id.

Request body

FieldTypeRequiredDescription
paymentMethodcard | gr4vy | net30YesCompletion path selected by the buyer.
emailstringNoBuyer email. Required for card and net30 modes when not already collected.
shippingAddressobjectNoShipping address object when the session collect flags require it.
billingAddressobjectNoBilling address object when the session collect flags require it.
paymentTokenstringNoCard payment token for the unified card path.
gr4vyTransactionIdstringNoProvider transaction id for proxy mode.
net30AcceptanceobjectNotermsHash, acceptedAt, companyName, and billingEmail for Net 30 checkout.

Responses

200Checkout completed.

Response fields

FieldTypeRequiredDescription
orderIduuidYesCreated or updated order id.
paymentIduuidYesPayment record created for the completed checkout.
subscriptionIduuidNoReturned when recurring create:auto creates a subscription.

Common errors

StatusCodeCauseFix
404not_foundSession does not exist.Create a fresh checkout session.
422missing_required_fieldThe session collect flags require email, shipping, billing, or payment-specific fields.Collect the required fields in the iframe or supply them in the completion payload.
402payment_failedThe processor declined or failed the payment.Show the buyer the failure message and let them retry with a different method.

SDK coverage

@usethrottle/checkout-sdk/server · Server-side checkout SDK for authenticated proxy-mode completion.

  • createCheckoutClient().completeSession(sessionId, input)

Most storefronts let the hosted iframe call the public complete route. Use the SDK when your backend intentionally owns the completion step.

Carts and Items

Create native carts, mutate line items, select shipping, persist taxes, and convert carts into orders.

POST/api/v1/cartsServer-side

Create a native Throttle cart.

X-API-KeyGuide
Implementation details

Start here when Throttle should own cart state before checkout. Create the cart from your backend, then add items and calculate totals before converting it to an order.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Request body

FieldTypeRequiredDescription
applicationIduuidYesApplication that owns the cart.
customerIduuidNoOptional Throttle customer id to attach to the cart.
customerEmailstringNoOptional lightweight email capture (no full customer record). Makes an otherwise-anonymous abandoned cart recoverable. A linked customer’s email takes precedence.
currencystringNoThree-letter currency code.
Default: USD
metadataobjectNoMerchant-owned JSON metadata.

Responses

201Cart created.

Response fields

FieldTypeRequiredDescription
iduuidYesThrottle cart identifier used by all cart mutation endpoints.
statusopen | checkout | converted | abandonedYesCurrent cart lifecycle state. Only open carts should be mutated.
currencystringYesISO 4217 currency used for all cart totals.
subtotal, taxTotal, discountTotal, shippingTotal, totalintegerYesCart totals in minor units.
lineItemsarrayNoLine items included when reading a cart or after item mutations.
appliedDiscountobject | nullNoSnapshot of the active promotion code, if one is applied.
selectedShippingobject | nullNoSelected shipping method and rate, if one has been selected.
taxLinesarrayNoTax line breakdown persisted on the cart.
metadataobjectNoMerchant-owned JSON metadata returned unchanged.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/cart · Server-side Node client.

  • client.carts.create(input)
  • client.carts.get(id)
  • client.carts.update(id, input)

The SDK uses camelCase input fields such as applicationId and unitPrice, then maps to the REST API.

GET/api/v1/carts/{id}Server-side

Fetch a cart snapshot.

X-API-KeyGuide
Implementation details

Read the current cart, including totals, line items, selected shipping, tax lines, and applied discount state.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
iduuidYesCart id.

Responses

200Cart snapshot returned.

Response fields

FieldTypeRequiredDescription
iduuidYesThrottle cart identifier used by all cart mutation endpoints.
statusopen | checkout | converted | abandonedYesCurrent cart lifecycle state. Only open carts should be mutated.
currencystringYesISO 4217 currency used for all cart totals.
subtotal, taxTotal, discountTotal, shippingTotal, totalintegerYesCart totals in minor units.
lineItemsarrayNoLine items included when reading a cart or after item mutations.
appliedDiscountobject | nullNoSnapshot of the active promotion code, if one is applied.
selectedShippingobject | nullNoSelected shipping method and rate, if one has been selected.
taxLinesarrayNoTax line breakdown persisted on the cart.
metadataobjectNoMerchant-owned JSON metadata returned unchanged.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
404cart_not_foundThe cart id is invalid or belongs to another merchant.Confirm the cart id and API key merchant match.

SDK coverage

@usethrottle/cart · Server-side Node client.

  • client.carts.get(id)

Use after mutations when your backend needs the authoritative cart snapshot.

PATCH/api/v1/carts/{id}Server-side

Update cart-level buyer and metadata fields.

X-API-KeyGuide
Implementation details

Patch the customer id, addresses, notes, or metadata on an open native cart.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Path parameters

FieldTypeRequiredDescription
iduuidYesCart id.

Request body

FieldTypeRequiredDescription
customerIduuidNoThrottle customer id.
customerEmailstringNoLightweight email capture; pass null to clear.
shippingAddressCartAddressNoCanonical address (required addressLine1, city, countryCode). Non-canonical keys are rejected at write time.
billingAddressCartAddressNoCanonical address (same shape as shippingAddress).
notesstringNoInternal cart notes.
metadataobjectNoMerchant-owned JSON metadata.

Responses

200Updated cart returned.

Response fields

FieldTypeRequiredDescription
iduuidYesThrottle cart identifier used by all cart mutation endpoints.
statusopen | checkout | converted | abandonedYesCurrent cart lifecycle state. Only open carts should be mutated.
currencystringYesISO 4217 currency used for all cart totals.
subtotal, taxTotal, discountTotal, shippingTotal, totalintegerYesCart totals in minor units.
lineItemsarrayNoLine items included when reading a cart or after item mutations.
appliedDiscountobject | nullNoSnapshot of the active promotion code, if one is applied.
selectedShippingobject | nullNoSelected shipping method and rate, if one has been selected.
taxLinesarrayNoTax line breakdown persisted on the cart.
metadataobjectNoMerchant-owned JSON metadata returned unchanged.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/cart · Server-side Node client.

  • client.carts.update(id, input)

SDK input names are camelCase: customerId, billingAddress, shippingAddress.

POST/api/v1/carts/{id}/itemsServer-side

Add a line item to a cart.

X-API-KeyGuide
Implementation details

Use this for products, services, tickets, donations, custom items, and subscription line items before checkout.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Path parameters

FieldTypeRequiredDescription
iduuidYesCart id.

Request body

FieldTypeRequiredDescription
typeproduct | subscription | service | ticket | donation | customNoLine item type.
Default: product
referenceIdstringNoYour SKU, plan id, ticket id, or other external item reference.
namestringYesBuyer-facing item name.
descriptionstringNoOptional item description.
unitPriceintegerYesUnit price in minor units (cents).
quantityintegerNoQuantity, minimum 1.
Default: 1
taxAmountintegerNoOptional item tax amount in minor units.
discountAmountintegerNoOptional item discount amount in minor units.
imageUrlstringNoOptional product image. Accepts an absolute http(s) URL or a relative path (e.g. "/images/x.png"). Relative paths are resolved to an absolute URL against the application storefront base URL (set storefrontBaseUrl via PUT /v1/embed-config; falls back to the first allowedOrigin) so the image renders on the hosted checkout.
requiresShippingbooleanNoWhether this item is physically shippable. For external/ad-hoc catalogs with no Throttle product behind the item. Omit to infer from type (everything except service ships); set explicitly to force-include or force-exclude the item from calculated shipping.
metadataobjectNoMerchant-owned item metadata.

Responses

201Line item added.

Response fields

FieldTypeRequiredDescription
iduuidYesLine item id.
namestringYesItem name.
unitPrice, quantity, totalintegerNoPricing fields in minor units.
metadataobjectNoItem metadata.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
404cart_not_foundThe cart id is invalid or belongs to another merchant.Read the cart before mutating it and confirm you are using the correct merchant API key.
400image_url_unresolvableimageUrl is a relative path but the application has no storefront base URL to resolve it against.Send an absolute http(s) imageUrl, or set storefrontBaseUrl via PUT /v1/embed-config (the first allowedOrigin is used as a fallback).

SDK coverage

@usethrottle/cart · Server-side Node client.

  • client.items.add(cartId, input)
  • client.items.update(cartId, itemId, input)
  • client.items.remove(cartId, itemId)

SDK inputs use camelCase: referenceId, unitPrice, taxAmount, discountAmount, imageUrl, requiresShipping.

PATCH/api/v1/carts/{cartId}/items/{id}Server-side

Update a line item.

X-API-KeyGuide
Implementation details

Patch quantity, price, tax, discount, or metadata for an existing cart line item.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Path parameters

FieldTypeRequiredDescription
cartIduuidYesCart id.
iduuidYesLine item id.

Request body

FieldTypeRequiredDescription
quantityintegerNoQuantity, minimum 1.
unitPriceintegerNoUnit price in minor units.
taxAmountintegerNoTax amount in minor units.
discountAmountintegerNoDiscount amount in minor units.
metadataobjectNoReplacement item metadata.

Responses

200Updated line item returned.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/cart · Server-side Node client.

  • client.items.update(cartId, itemId, input)

SDK input names are camelCase, matching the wire format.

DELETE/api/v1/carts/{cartId}/items/{id}Server-side

Remove a line item.

X-API-KeyGuide
Implementation details

Deletes a line item from an open native cart.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
cartIduuidYesCart id.
iduuidYesLine item id.

Responses

204Line item removed. No JSON body is returned.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/cart · Server-side Node client.

  • client.items.remove(cartId, itemId)

Read the cart after removal if your backend needs recalculated totals.

POST/api/v1/carts/{id}/shippingServer-side

Select a shipping method for a cart.

X-API-KeyGuide
Implementation details

Persist the buyer-selected shipping option before final checkout. Use the id returned from shipping/tax calculation when possible.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Path parameters

FieldTypeRequiredDescription
iduuidYesCart id.

Request body

FieldTypeRequiredDescription
methodIdstringYesShipping method id.
displayNamestringYesBuyer-facing shipping label.
rateAmountintegerYesShipping rate in minor units.
currencystringNoThree-letter currency code.
carrierstringNoOptional carrier name.
serviceCodestringNoOptional carrier service code.
estimatedDeliveryDaysintegerNoOptional delivery estimate in days.

Responses

200Cart returned with selectedShipping populated.

Response fields

FieldTypeRequiredDescription
iduuidYesThrottle cart identifier used by all cart mutation endpoints.
statusopen | checkout | converted | abandonedYesCurrent cart lifecycle state. Only open carts should be mutated.
currencystringYesISO 4217 currency used for all cart totals.
subtotal, taxTotal, discountTotal, shippingTotal, totalintegerYesCart totals in minor units.
lineItemsarrayNoLine items included when reading a cart or after item mutations.
appliedDiscountobject | nullNoSnapshot of the active promotion code, if one is applied.
selectedShippingobject | nullNoSelected shipping method and rate, if one has been selected.
taxLinesarrayNoTax line breakdown persisted on the cart.
metadataobjectNoMerchant-owned JSON metadata returned unchanged.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/cart · Server-side Node client.

  • client.shipping.select(cartId, input)
  • client.shipping.clear(cartId)

Call clear when the buyer changes address and the previous method is no longer valid.

DELETE/api/v1/carts/{id}/shippingServer-side

Clear selected shipping from a cart.

X-API-KeyGuide
Implementation details

Use when the buyer changes address, shipping is no longer required, or the selected method is no longer available.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
iduuidYesCart id.

Responses

200Cart returned with selectedShipping cleared.

Response fields

FieldTypeRequiredDescription
iduuidYesThrottle cart identifier used by all cart mutation endpoints.
statusopen | checkout | converted | abandonedYesCurrent cart lifecycle state. Only open carts should be mutated.
currencystringYesISO 4217 currency used for all cart totals.
subtotal, taxTotal, discountTotal, shippingTotal, totalintegerYesCart totals in minor units.
lineItemsarrayNoLine items included when reading a cart or after item mutations.
appliedDiscountobject | nullNoSnapshot of the active promotion code, if one is applied.
selectedShippingobject | nullNoSelected shipping method and rate, if one has been selected.
taxLinesarrayNoTax line breakdown persisted on the cart.
metadataobjectNoMerchant-owned JSON metadata returned unchanged.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/cart · Server-side Node client.

  • client.shipping.clear(cartId)

Recalculate totals after clearing shipping if payment amount depends on shipping.

PUT/api/v1/carts/{id}/tax-linesServer-side

Replace tax lines on a cart.

X-API-KeyGuide
Implementation details

Use this when you bring your own tax calculation and need to persist the final line-level tax breakdown on a native cart.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Path parameters

FieldTypeRequiredDescription
iduuidYesCart id.

Request body

FieldTypeRequiredDescription
linesarrayYesComplete replacement list of tax lines.
lines[].lineItemIduuidYesLine item receiving the tax.
lines[].jurisdictionCodestringYesTax jurisdiction code.
lines[].jurisdictionNamestringNoHuman-readable jurisdiction name.
lines[].taxTypesales | vat | gst | pst | hst | service | excise | otherYesTax category.
lines[].ratenumberYesDecimal rate between 0 and 1.
lines[].amountintegerYesTax amount in minor units.
lines[].currencystringNoThree-letter currency code.

Responses

200Cart returned with replacement taxLines.

Response fields

FieldTypeRequiredDescription
iduuidYesThrottle cart identifier used by all cart mutation endpoints.
statusopen | checkout | converted | abandonedYesCurrent cart lifecycle state. Only open carts should be mutated.
currencystringYesISO 4217 currency used for all cart totals.
subtotal, taxTotal, discountTotal, shippingTotal, totalintegerYesCart totals in minor units.
lineItemsarrayNoLine items included when reading a cart or after item mutations.
appliedDiscountobject | nullNoSnapshot of the active promotion code, if one is applied.
selectedShippingobject | nullNoSelected shipping method and rate, if one has been selected.
taxLinesarrayNoTax line breakdown persisted on the cart.
metadataobjectNoMerchant-owned JSON metadata returned unchanged.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/cart · Server-side Node client.

  • client.taxLines.set(cartId, lines)
  • client.taxLines.clear(cartId)

This is a full replacement operation, not a patch.

DELETE/api/v1/carts/{id}/tax-linesServer-side

Clear all tax lines from a cart.

X-API-KeyGuide
Implementation details

Remove persisted tax lines when the cart address changes, the tax mode changes, or you need to recompute taxes from scratch.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
iduuidYesCart id.

Responses

200Cart returned with taxLines cleared.

Response fields

FieldTypeRequiredDescription
iduuidYesThrottle cart identifier used by all cart mutation endpoints.
statusopen | checkout | converted | abandonedYesCurrent cart lifecycle state. Only open carts should be mutated.
currencystringYesISO 4217 currency used for all cart totals.
subtotal, taxTotal, discountTotal, shippingTotal, totalintegerYesCart totals in minor units.
lineItemsarrayNoLine items included when reading a cart or after item mutations.
appliedDiscountobject | nullNoSnapshot of the active promotion code, if one is applied.
selectedShippingobject | nullNoSelected shipping method and rate, if one has been selected.
taxLinesarrayNoTax line breakdown persisted on the cart.
metadataobjectNoMerchant-owned JSON metadata returned unchanged.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/cart · Server-side Node client.

  • client.taxLines.clear(cartId)

This removes every tax line on the cart.

POST/api/v1/carts/{id}/apply-discountServer-side

Apply a promotion code to a cart.

X-API-KeyGuide
Implementation details

Validates a code and writes the active applied discount snapshot onto the cart. A cart can have one active code; applying a new valid code replaces the old one.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Path parameters

FieldTypeRequiredDescription
iduuidYesCart id.

Request body

FieldTypeRequiredDescription
codestringYesPromotion code to apply.

Responses

200Cart returned with appliedDiscount populated.

Response fields

FieldTypeRequiredDescription
iduuidYesThrottle cart identifier used by all cart mutation endpoints.
statusopen | checkout | converted | abandonedYesCurrent cart lifecycle state. Only open carts should be mutated.
currencystringYesISO 4217 currency used for all cart totals.
subtotal, taxTotal, discountTotal, shippingTotal, totalintegerYesCart totals in minor units.
lineItemsarrayNoLine items included when reading a cart or after item mutations.
appliedDiscountobject | nullNoSnapshot of the active promotion code, if one is applied.
selectedShippingobject | nullNoSelected shipping method and rate, if one has been selected.
taxLinesarrayNoTax line breakdown persisted on the cart.
metadataobjectNoMerchant-owned JSON metadata returned unchanged.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
422discount_invalidThe code is inactive, expired, over usage limits, or not valid for the cart/customer.Keep the existing cart state and show the buyer the returned message.

SDK coverage

@usethrottle/discounts or @usethrottle/cart · Server-side Node clients.

  • discounts.applyToCart(cartId, code)
  • cartClient.discounts.apply(cartId, code)

Use @usethrottle/discounts when discounts are your main workflow; use @usethrottle/cart inside cart orchestration.

DELETE/api/v1/carts/{id}/discountServer-side

Remove the active promotion code from a cart.

X-API-KeyGuide
Implementation details

Clears the applied discount snapshot and returns the cart without an active promotion code.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
iduuidYesCart id.

Responses

200Cart returned with appliedDiscount cleared.

Response fields

FieldTypeRequiredDescription
iduuidYesThrottle cart identifier used by all cart mutation endpoints.
statusopen | checkout | converted | abandonedYesCurrent cart lifecycle state. Only open carts should be mutated.
currencystringYesISO 4217 currency used for all cart totals.
subtotal, taxTotal, discountTotal, shippingTotal, totalintegerYesCart totals in minor units.
lineItemsarrayNoLine items included when reading a cart or after item mutations.
appliedDiscountobject | nullNoSnapshot of the active promotion code, if one is applied.
selectedShippingobject | nullNoSelected shipping method and rate, if one has been selected.
taxLinesarrayNoTax line breakdown persisted on the cart.
metadataobjectNoMerchant-owned JSON metadata returned unchanged.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/discounts or @usethrottle/cart · Server-side Node clients.

  • discounts.removeFromCart(cartId)
  • cartClient.discounts.remove(cartId)

Recalculate totals after removal if the buyer remains in checkout.

POST/api/v1/carts/{id}/checkoutServer-side

Convert a cart into an order.

X-API-KeyGuide
Implementation details

Call after items, discount, shipping, and final tax calculation are ready. This creates the order that payment and fulfillment workflows use.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Path parameters

FieldTypeRequiredDescription
iduuidYesCart id.

Request body

FieldTypeRequiredDescription
paymentMethodstringNoOptional selected payment method such as card or net30.
metadataobjectNoOptional checkout metadata.

Responses

201Order created from cart.

Response fields

FieldTypeRequiredDescription
iduuidYesOrder id.
orderNumberstringNoMerchant-visible order number.
statusdraftNoInitial order status.
subtotal, totalintegerNoOrder totals in minor units.
cartIduuidNoSource cart id.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
400cart_not_readyThe cart is missing required checkout state or cannot be converted.Confirm items exist and final totals have been calculated before checkout.

SDK coverage

@usethrottle/cart · Server-side Node client.

  • client.carts.checkout(cartId, input)

Run shippingTax.calculateCart with kind checkout_final before checkout when Throttle calculates totals.

GET/api/v1/carts/{id}/eventsServer-side

Read immutable cart events.

X-API-KeyGuide
Implementation details

Use cart events for polling/debugging cart mutations. For real-time delivery, subscribe to outbound webhooks.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
iduuidYesCart id.

Query parameters

FieldTypeRequiredDescription
sinceSequenceintegerNoReturn events after this sequence.
limitintegerNoPage size, 1 to 200.

Responses

200Ordered cart event list.

Response fields

FieldTypeRequiredDescription
iduuidYesEvent id.
eventTypestringYesEvent name such as cart.item_added.
sequenceintegerYesMonotonic per-cart sequence.
payloadobjectNoEvent payload.

SDK coverage

@usethrottle/cart · Server-side Node client.

  • client.events.list(cartId, { sinceSequence, limit })

Store the last sequence you processed if you poll events.

GET/api/v1/abandoned-cartsServer-side

List abandoned carts (most-recently abandoned first).

X-API-Key
Implementation details

Carts that the sweep flagged abandoned, newest first. Cursor-paginated. A cart becomes abandoned after the per-app idle threshold (see embed-config `cartAbandonmentThresholdMinutes`) or once it passes its expiry.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Query parameters

FieldTypeRequiredDescription
limitintegerNoPage size, 1 to 100 (default 25).
cursorstringNoOpaque cursor from the previous page.

Responses

200Cursor-paginated abandoned carts.

Response fields

FieldTypeRequiredDescription
iduuidYesCart id.
customerobject | nullNoBuyer identity ({ id, email, firstName }) or null for an anonymous cart.
totalintegerNoCart total in minor units (cents).
currencystringNoISO-4217 currency code.
itemCountintegerNoNumber of line items.
abandonedAtstring | nullNoISO-8601 timestamp the cart was marked abandoned.
recoveryStatusstringNoWhether a recovery email was sent, or recovery is webhook-only.
Values: emailed, webhook_only
GET/api/v1/abandoned-carts/summaryServer-side

Abandoned-cart summary metrics for a trailing window.

X-API-Key
Implementation details

Headline counts for the abandoned-carts dashboard over a trailing window.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Query parameters

FieldTypeRequiredDescription
sinceDaysintegerNoTrailing window in days, 1 to 365 (default 30).

Responses

200Summary metrics.

Response fields

FieldTypeRequiredDescription
sinceDaysintegerNoWindow applied.
abandonedCountintegerNoCarts abandoned in the window.
abandonedValueintegerNoSum of abandoned-cart totals in minor units (cents).
recoveryEmailsSentintegerNoRecovery emails dispatched in the window.
POST/api/v1/shipping-tax/external-snapshotsServer-side

Push provider-owned shipping/tax totals.

X-API-KeyGuide
Implementation details

Use when your application is in bring-your-own shipping or tax mode and an upstream provider owns the final totals.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Request body

FieldTypeRequiredDescription
applicationIduuidYesApplication receiving the snapshot.
cartIduuid | nullNoOptional Throttle cart to mirror totals onto.
checkoutSessionIdstring | nullNoOptional checkout session reference.
orderIduuid | nullNoOptional order reference.
currencystringNoThree-letter currency code.
totalsobjectYessubtotal, discountTotal, shippingTotal, taxTotal, and total in minor units.
selectedShippingobject | nullNoProvider-selected shipping snapshot.
taxLinesarrayNoProvider tax line breakdown.
sourcestringNoProvider/source label for audit.

Responses

200External snapshot accepted and calculation response returned.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
422external_snapshot_not_allowedNeither shipping nor tax mode is configured for bring-your-own totals.Switch at least one axis to byo mode before pushing external totals.

SDK coverage

@usethrottle/cart · Server-side Node client.

  • client.shippingTax.pushExternalSnapshot(input)

This is for provider-owned totals; native Throttle carts usually use calculateCart instead.

Discounts

Manage percentage and fixed amount promotion codes, preview them without mutation, and apply them to native carts.

POST/api/v1/discountsServer-side

Create a discount.

X-API-KeyGuide
Implementation details

Creates a percentage or fixed amount discount code for later preview and cart application.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Request body

FieldTypeRequiredDescription
codestringNoPromotion code. Leave empty for automatic discounts.
namestringYesHuman-readable discount name.
typepercentage | fixed_amountYesDiscount type.
valueintegerYesWhole percent for percentage discounts, or minor units for fixed amount discounts.
conditionsobjectNoOptional conditions such as minOrder.
usageLimitintegerNoOptional global usage cap.
maxRedemptionsPerCustomerinteger | nullNoPer-customer redemption cap. Use null for unlimited.
Default: 1
startsAt, endsAtdate-timeNoOptional active window.
metadataobjectNoCampaign or attribution metadata.

Responses

201Discount created.

Response fields

FieldTypeRequiredDescription
iduuidYesDiscount id.
codestringNoPromotion code.
type, valuestring, integerNoDiscount calculation fields.
isActivebooleanNoWhether the code can be used.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/discounts · Server-side Node client.

  • discounts.create(input)
  • discounts.list(filters)

Use the SDK from API routes, server actions, workers, or backend services only.

GET/api/v1/discountsServer-side

List discounts.

X-API-KeyGuide
Implementation details

Use for promotion management screens, campaign reconciliation, or validating which codes exist before checkout.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Query parameters

FieldTypeRequiredDescription
cursorstringNoCursor for pagination.
limitintegerNoPage size, 1 to 100.
Default: 10
isActivebooleanNoFilter by active state.
codestringNoFilter by promotion code.
typepercentage | fixed_amountNoFilter by type.
qstringNoSearch code, name, type, or metadata.
sortasc | descNoSort by creation time.

Responses

200Paginated discount list returned.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/discounts · Server-side Node client.

  • discounts.list(filters)
  • discounts.get(id)

Use cursor pagination for management UIs.

PATCH/api/v1/discounts/{id}Server-side

Update a discount.

X-API-KeyGuide
Implementation details

Patch campaign metadata, active windows, usage limits, or the display name for an existing discount.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Path parameters

FieldTypeRequiredDescription
iduuidYesDiscount id.

Request body

FieldTypeRequiredDescription
codestringNoPromotion code.
namestringNoHuman-readable discount name.
valueintegerNoUpdated percent or fixed amount value.
conditionsobjectNoReplacement conditions object.
usageLimitintegerNoUpdated global usage cap.
maxRedemptionsPerCustomerinteger | nullNoUpdated per-customer cap.
startsAt, endsAtdate-timeNoUpdated active window.
metadataobjectNoReplacement metadata.

Responses

200Updated discount returned.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/discounts · Server-side Node client.

  • discounts.update(id, input)

Existing cart snapshots keep the discount values captured when the code was applied.

DELETE/api/v1/discounts/{id}Server-side

Deactivate or delete a discount.

X-API-KeyGuide
Implementation details

Removes a discount from future use. Existing orders keep their historical discount snapshot.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
iduuidYesDiscount id.

Responses

204Discount removed. No JSON body is returned.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/discounts · Server-side Node client.

  • discounts.delete(id)

Prefer deactivation semantics in your UI copy if historical redemptions matter.

POST/api/v1/discounts/previewServer-side

Preview a code without mutating a cart.

X-API-KeyGuide
Implementation details

Call while the buyer types a code in your storefront. Preview returns the computed discount and final total without changing cart or usage counts.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Request body

FieldTypeRequiredDescription
codestringYesPromotion code to preview.
currencystringYesThree-letter currency code.
subtotalintegerYesCurrent subtotal in minor units.
customerIduuidNoOptional customer id for redemption-limit checks.
lineItemsarrayNoOptional line item context for future item-level conditions.

Responses

200Preview result.

Response fields

FieldTypeRequiredDescription
validbooleanYesWhether the code can currently be applied.
codestringNoNormalized code.
discountTotalintegerNoDiscount amount in minor units.
totalintegerNoSubtotal minus discount.
messagestringNoBuyer-safe reason when invalid.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/discounts · Server-side Node client.

  • discounts.preview(input)

Preview is safe to call repeatedly because it does not mutate usage counts.

Shipping and Tax

Issue storefront quote tokens, estimate buyer totals, and calculate or persist cart totals before checkout.

GET/api/v1/shipping-tax/configSetup

Read draft and published shipping/tax config.

X-API-KeyGuide
Implementation details

Use setup tooling or advanced dashboards to show the active shipping/tax modes and catalog for an application.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Query parameters

FieldTypeRequiredDescription
applicationIduuidYesApplication id to read config for.

Responses

200Draft and published configs returned.

Response fields

FieldTypeRequiredDescription
draftobject | nullNoEditable config draft.
publishedobject | nullNoPublished config used by calculations.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
400missing_application_idapplicationId query parameter is missing.Pass applicationId in the query string.
GET/api/v1/shipping-tax/quote-tokensSetup

List publishable quote tokens for an application.

X-API-KeyGuide
Implementation details

Use during setup to audit active quote tokens. Raw token values are not returned after creation.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Query parameters

FieldTypeRequiredDescription
applicationIduuidYesApplication id to list tokens for.

Responses

200Quote token metadata list returned.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
POST/api/v1/shipping-tax/quote-tokensSetup

Create a publishable storefront quote token.

X-API-KeyGuide
Implementation details

Quote tokens start with pk_ and let a storefront request read-only estimates without exposing a secret key.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Request body

FieldTypeRequiredDescription
applicationIduuidYesApplication the token can quote for.
namestringYesInternal token label, 1 to 80 characters.
expiresAtdate-time | nullNoOptional expiration time.

Responses

200Token created. rawToken is shown once.

Response fields

FieldTypeRequiredDescription
rawTokenstringYesPublishable pk_ token. Store it safely client-side.
tokenPrefixstringNoPrefix shown later for identification.
expiresAtdate-time | nullNoExpiration time.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
404store_not_foundThe application id does not belong to the authenticated workspace.Use a valid application id for this workspace.
DELETE/api/v1/shipping-tax/quote-tokens/{tokenId}Setup

Revoke a storefront quote token.

X-API-KeyGuide
Implementation details

Soft-deletes and deactivates a pk_ token so storefront quote requests using it stop working.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
tokenIduuidYesQuote token id.

Responses

200Revocation confirmation.

Response fields

FieldTypeRequiredDescription
iduuidNoRevoked token id.
revokedbooleanNoAlways true on success.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
POST/api/v1/shipping-tax/quotesBrowser-safe

Request a storefront shipping/tax estimate.

Publishable quote tokenGuide
Implementation details

Use from the browser or your backend for read-only estimates. It validates the pk_ quote token, application id, expiry, and allowed origin.

Headers

FieldTypeRequiredDescription
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Request body

FieldTypeRequiredDescription
applicationIduuidYesApplication being quoted.
quoteTokenstringYesPublishable pk_ token for this application.
currencystringNoThree-letter currency code. Defaults to application currency or USD.
itemsarrayYesAt least one item to quote.
items[].idstringYesSKU or item id.
items[].subtotalAmountintegerYesLine subtotal in minor units.
items[].quantityintegerNoQuantity, minimum 1.
Default: 1
items[].requiresShippingbooleanNoWhether the item needs shipping rates.
items[].taxCategorystringNoTax category used by configured rules.
discountsTotalintegerNoDiscount total in minor units.
selectedShippingMethodIdstring | nullNoMethod id selected by the buyer.
addresses.shippingobject | nullNoShipping address fields such as countryCode, stateProvince, postalCode.
addresses.billingobject | nullNoBilling address for tax rules that use billing address.

Responses

200Estimated shipping/tax calculation.

Response fields

FieldTypeRequiredDescription
kindquoteYesCalculation kind.
statusestimated | final | failedYesCalculation status.
shipping.methodsarrayNoAvailable shipping or pickup methods.
tax.taxTotalintegerNoTax total in minor units.
totals.totalintegerNoEstimated final total in minor units.
prompts, warnings, errorsarrayNoMissing info and calculation feedback.

Common errors

StatusCodeCauseFix
401invalid_quote_tokenToken is wrong, expired, for another application, or the request origin is not allowed.Create a new token and add your storefront origin to the merchant allowlist.
404store_not_foundThe application id is unknown.Use the application id tied to the quote token.

SDK coverage

@usethrottle/cart · Browser-safe or backend quote helper.

  • new StorefrontQuoteClient(opts).quote(input)

StorefrontQuoteClient uses the pk_ token, not your secret API key.

POST/api/v1/shipping-tax/carts/{cartId}/calculateServer-side

Calculate shipping/tax for a native cart.

X-API-KeyGuide
Implementation details

Use this from your backend when a Throttle cart exists. Persist checkout_final totals before cart checkout so payment receives locked totals. Pass shippingAddress/billingAddress inline to set the destination and calculate in one request — they are persisted to the cart before calculation, so a separate PATCH /carts/{id} is not required. Unknown fields are rejected with a 400 validation_error.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Path parameters

FieldTypeRequiredDescription
cartIduuidYesCart id.

Request body

FieldTypeRequiredDescription
kindcart_estimate | checkout_finalNoEstimate during browsing or final lock before payment.
Default: cart_estimate
selectedShippingMethodIdstring | nullNoBuyer-selected method id to include in final totals.
persistbooleanNoPersist calculation snapshot and mirror selected shipping/tax lines onto the cart when supported.
shippingAddressobject | nullNoOptional inline shipping destination (countryCode, stateProvince, postalCode, city, addressLine1/2). Persisted to the cart before calculation, so you can set the address and get rates in one call instead of a separate PATCH /carts/{id}.
billingAddressobject | nullNoOptional inline billing address; persisted to the cart before calculation.

Responses

200Cart calculation response.

Response fields

FieldTypeRequiredDescription
snapshotIduuidNoPersisted snapshot id when a snapshot is stored.
shipping.methodsarrayNoAvailable shipping methods.
shipping.selectedMethodobject | nullNoSelected method if supplied.
tax.linesarrayNoTax line breakdown.
totalsobjectNosubtotal, discountTotal, shippingTotal, taxTotal, and total.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/cart · Server-side Node client.

  • client.shippingTax.calculateCart(cartId, input)

Use kind checkout_final after the buyer commits to shipping and payment.

Orders and Payments

Read orders and payments from your backend, issue refunds, retrieve Net 30 invoice PDFs, and resend invoice emails.

GET/api/v1/ordersServer-side

List orders.

X-API-Key
Implementation details

Use for order history, reconciliation, and merchant-side operations dashboards.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Query parameters

FieldTypeRequiredDescription
cursorstringNoCursor for pagination.
limitintegerNoPage size, 1 to 100.
Default: 20
statusdraft | pending | processing | partially_fulfilled | completed | cancelled | closedNoOptional status filter.
paymentStatuspending | authorized | captured | partially_refunded | refunded | failed | voidedNoOptional payment status filter.
qstringNoSearch order id, order number, status, source, discount code, or metadata.
customerIduuidNoOptional customer filter.
applicationIduuidNoOptional application filter.

Responses

200Paginated order list.

Response fields

FieldTypeRequiredDescription
data[]arrayNoOrder records.
meta.pagination.cursorstring | nullNoCursor for the next page.
meta.pagination.hasMorebooleanNoWhether another page exists.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/api-client · Server-side generated REST client.

  • Generated client method for GET /api/v1/orders

For native cart checkout, most applications use webhooks for durable order updates and list APIs for reconciliation.

GET/api/v1/orders/{id}Server-side

Fetch an order and its line items.

X-API-Key
Implementation details

Use for order detail pages, reconciliation, fulfillment handoff, and support tooling.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
iduuidYesOrder id.

Responses

200Order detail returned.

Response fields

FieldTypeRequiredDescription
iduuidNoOrder id.
statusstringNoOrder lifecycle state.
lineItemsarrayNoOrder line items.
subtotal, totalintegerNoOrder totals in minor units.
metadataobjectNoOrder metadata.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
404not_foundThe order id is unknown or belongs to another merchant.Verify the order id and merchant API key.

SDK coverage

@usethrottle/checkout-sdk/server · Server-side checkout SDK.

  • createCheckoutClient().getOrder(id)
  • createCheckoutClient().getOrderWithPayments(id)

Prefer webhooks for state changes; read the order when rendering a confirmation page or reconciling checkout success.

GET/api/v1/paymentsServer-side

List payments for the calling merchant.

X-API-Key
Implementation details

Returns all payments scoped to the calling application, cursor-paginated by createdAt DESC. Filter by `method` (e.g. net30, card), `status` (repeat the param for multi-status OR logic), `order_id` (UUID — returns payments for a specific order), `due_from` / `due_to` (YYYY-MM-DD ISO dates that filter on `metadata.dueDate`), `amount_min` / `amount_max` (integer cents, inclusive bounds), `aging` (Net-N aging bucket: `0_30 | 31_60 | 61_90 | 90_plus`), `limit` (page size), and `cursor` (opaque continuation token from the previous response).

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Query parameters

FieldTypeRequiredDescription
methodstringNoFilter by payment method (e.g. net30, card, manual, external).
statusstringNoFilter by payment status. Repeat the parameter for multi-status OR logic (e.g. status=authorized&status=captured).
order_iduuidNoReturn payments belonging to a specific order.
due_fromYYYY-MM-DDNoInclusive lower bound on metadata.dueDate (ISO date).
due_toYYYY-MM-DDNoInclusive upper bound on metadata.dueDate (ISO date).
amount_minintegerNoInclusive minimum payment amount in minor currency units (cents).
amount_maxintegerNoInclusive maximum payment amount in minor currency units (cents).
aging0_30 | 31_60 | 61_90 | 90_plusNoFilter to a Net-N aging bucket based on days since the invoice due date.
limitintegerNoPage size, 1 to 100.
Default: 20
cursorstringNoOpaque pagination cursor returned by the previous response.

Responses

200Payments matching the filters, ordered by createdAt DESC.

Response fields

FieldTypeRequiredDescription
data[]arrayNoPayment records.
meta.pagination.cursorstring | nullNoCursor for the next page, or null when no further pages exist.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
GET/api/v1/orders/{id}/paymentsServer-side

List payments for an order.

X-API-Key
Implementation details

Use when you need to show payment state, processor references, refunds, or Net 30 state for a specific order.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
iduuidYesOrder id.

Responses

200Payments attached to the order.

Response fields

FieldTypeRequiredDescription
iduuidNoPayment id.
statusstringNoPayment status.
amount, currencyinteger, stringNoPayment amount and currency.
methodcard | net30 | manual | external | ...NoPayment method.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/checkout-sdk/server · Server-side checkout SDK.

  • createCheckoutClient().listOrderPayments(orderId)
  • createCheckoutClient().getOrderWithPayments(orderId)

Use getOrderWithPayments when your confirmation route needs order, payment, and transaction state in one helper.

GET/api/v1/payments/{id}/transactionsServer-side

List processor transactions for a payment.

X-API-Key
Implementation details

Use when you need capture, authorization, refund, or failure transaction details for reconciliation and support tooling.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
iduuidYesPayment id.

Responses

200Payment transactions returned.

Response fields

FieldTypeRequiredDescription
iduuidNoTransaction id.
paymentIduuidNoPayment this transaction belongs to.
typeauthorization | capture | refund | void | ...NoProcessor transaction type.
statusstringNoTransaction status.
amount, currencyinteger, stringNoTransaction amount and currency.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/checkout-sdk/server · Server-side checkout SDK.

  • createCheckoutClient().listPaymentTransactions(paymentId)

getOrderWithPayments calls this for every payment and returns transactions nested under each payment.

POST/api/v1/payments/{id}/refundServer-side

Refund a captured payment.

X-API-Key
Implementation details

Refund a payment fully or partially. Use webhooks to update downstream order state after the refund result is recorded.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Path parameters

FieldTypeRequiredDescription
iduuidYesPayment id.

Request body

FieldTypeRequiredDescription
amountintegerNoPartial refund amount in minor units. Omit for a full refund.

Responses

200Refund recorded or processor refund initiated.

Response fields

FieldTypeRequiredDescription
iduuidNoPayment id.
statusstringNoUpdated payment/refund status.
refundedAmountintegerNoTotal refunded amount in minor units when returned.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
422refund_not_allowedPayment is not captured, already fully refunded, or amount exceeds refundable balance.Read the payment first and only refund captured, refundable amounts.

SDK coverage

@usethrottle/api-client · Server-side generated REST client.

  • Generated client method for POST /api/v1/payments/{id}/refund

Refunds are operations code, not browser checkout code.

GET/api/v1/payments/{id}/invoice-pdfServer-side

Get a signed Net 30 invoice PDF URL.

X-API-Key
Implementation details

Use for buyer portals or operations tools that need to show or download a Net 30 invoice PDF.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
iduuidYesNet 30 payment id.

Responses

200Signed download information.

Response fields

FieldTypeRequiredDescription
urlurlYesTemporary signed invoice PDF URL.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
404not_foundNo payment with this id belongs to the merchant.Confirm the payment id and that it belongs to your workspace and application.
409not_invoiceThe payment is not a Net 30 invoice (e.g. a card or manual payment), so it has no invoice PDF.Only request an invoice PDF for payments whose method is net30.
409pdf_not_readyThe Net 30 invoice exists but its PDF has not been generated yet.Retry after invoice generation completes.
503storage_unavailableObject storage could not produce a signed URL for the PDF.Retry shortly; if it persists, contact support.
POST/api/v1/payments/{id}/invoice/resendServer-side

Resend the Net 30 invoice email.

X-API-Key
Implementation details

Queues the customer.net30_invoice_issued email again. The email includes a fresh buyer-facing invoice download link.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Path parameters

FieldTypeRequiredDescription
iduuidYesNet 30 payment id.

Responses

200Invoice email queued.

Response fields

FieldTypeRequiredDescription
messageIduuid | stringYesQueued email message id.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
409not_invoiceThe payment is not a Net 30 invoice payment.Only call this endpoint for payments where method is net30.
409no_recipientNo customer or Net 30 billing email is available for the invoice.Confirm the order customer or Net 30 acceptance billing email was captured.
409email_not_configuredTransactional email is not enabled for the API service.Configure RESEND_API_KEY, REDIS_URL, and email settings before resending.
GET/api/v1/payments/{id}/invoice/download?token={token}Browser-safe

Download a Net 30 invoice from an email link.

Signed invoice token
Implementation details

Public buyer route used by invoice emails. Throttle validates the signed token, reloads the payment, and redirects to a short-lived S3 signed URL. Tokens are valid for the snapshotted Net-N term, clamped to 1-365 days.

Path parameters

FieldTypeRequiredDescription
iduuidYesNet 30 payment id.

Query parameters

FieldTypeRequiredDescription
tokenjwtYesSigned invoice download token from the email.

Responses

302Redirects to a short-lived signed PDF URL.

Response fields

FieldTypeRequiredDescription
LocationurlYesTemporary S3 signed URL for the invoice PDF.

Common errors

StatusCodeCauseFix
400missing_tokenThe token query parameter was omitted.Use the full URL generated by the invoice email.
401invalid_tokenThe token is expired, malformed, or signed with the wrong secret.Resend the invoice email to issue a fresh buyer link.
409pdf_not_readyThe invoice PDF has not been rendered to object storage yet.Retry after the PDF render/backfill job finishes.

Webhooks

Configure signed HTTPS endpoints, test delivery, inspect attempts, and replay delivery payloads.

GET/api/v1/webhook-endpointsWebhook operations

List configured webhook endpoints.

X-API-KeyGuide
Implementation details

Returns active and paused outbound webhook endpoints. Deleted endpoints are excluded.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Responses

200Webhook endpoint list.

Response fields

FieldTypeRequiredDescription
iduuidNoEndpoint id.
urlurlNoDelivery URL.
enabledEventsarrayNoSubscribed event types.
isActivebooleanNoWhether dispatch is active.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
POST/api/v1/webhook-endpointsWebhook operations

Create a signed outbound webhook endpoint.

X-API-KeyGuide
Implementation details

Register the HTTPS URL that receives durable order, payment, cart, subscription, discount, customer, and fulfillment events.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Request body

FieldTypeRequiredDescription
urlhttps URLYesYour webhook receiver URL. Must use https.
enabledEventsstring[]YesEvent types to deliver. Must be non-empty and unique.

Responses

201Webhook endpoint created. signingSecret is returned once.

Response fields

FieldTypeRequiredDescription
iduuidYesWebhook endpoint id.
urlurlYesDelivery URL.
enabledEventsarrayYesSubscribed event list.
isActivebooleanYesWhether delivery is active.
signingSecretstringYesHMAC secret. Store it now; it is shown once.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
Create endpoint
curl -X POST https://api.usethrottle.dev/api/v1/webhook-endpoints \
  -H "x-api-key: $THROTTLE_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "url": "https://shop.example.com/api/throttle/webhook",
    "enabledEvents": ["order.created", "payment.captured", "payment.failed"]
  }'
PATCH/api/v1/webhook-endpoints/{id}Webhook operations

Update URL, event list, or active state.

X-API-KeyGuide
Implementation details

Use this to rotate receivers, pause delivery, resume delivery, or change subscribed events.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Path parameters

FieldTypeRequiredDescription
iduuidYesWebhook endpoint id.

Request body

FieldTypeRequiredDescription
urlhttps URLNoNew delivery URL.
enabledEventsstring[]NoReplacement event list.
isActivebooleanNofalse pauses dispatch; true resumes it.

Responses

200Updated endpoint returned.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
DELETE/api/v1/webhook-endpoints/{id}Webhook operations

Soft-delete a webhook endpoint.

X-API-KeyGuide
Implementation details

Stops future dispatch and removes the endpoint from list responses. Create a new endpoint to subscribe again.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
iduuidYesWebhook endpoint id.

Responses

200Deleted endpoint confirmation returned.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
GET/api/v1/webhook-deliveriesWebhook operations

Inspect recent webhook delivery attempts.

X-API-KeyGuide
Implementation details

Use for debugging and operational audit views. This endpoint returns attempts, not the endpoint configuration itself.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Query parameters

FieldTypeRequiredDescription
endpointIduuidNoFilter by webhook endpoint.
orderIduuidNoFilter by related order.
limitintegerNoPage size, 1 to 200.
Default: 50
offsetintegerNoOffset pagination start.
Default: 0

Responses

200Delivery page.

Response fields

FieldTypeRequiredDescription
itemsarrayNoDelivery attempts.
totalintegerNoTotal matching attempts.
hasMorebooleanNoWhether another page exists.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
POST/api/v1/webhook-endpoints/{id}/testWebhook operations

Send a synthetic signed test event.

X-API-KeyGuide
Implementation details

Use during setup to verify URL reachability, signature validation, and handler routing without waiting for a real checkout event.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Path parameters

FieldTypeRequiredDescription
iduuidYesWebhook endpoint id.

Request body

FieldTypeRequiredDescription
eventTypedocumented outbound webhook event typeNoSynthetic event type. Defaults to payment.captured.

Responses

200Synthetic delivery enqueued or sent.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
POST/api/v1/webhook-endpoints/{id}/rotate-secretWebhook operations

Rotate the endpoint signing secret (reveal-once).

X-API-KeyGuide
Implementation details

Generates a new signing secret and returns it once in the response. The previous secret stops verifying immediately, so update your receiver before (or right after) rotating. Use this to recover from a leaked secret.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
iduuidYesWebhook endpoint id.

Responses

200New signing secret returned (shown once).

Response fields

FieldTypeRequiredDescription
iduuidNoWebhook endpoint id.
signingSecretstringNoThe new whsec_… secret. Store it now; it is not retrievable later.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
POST/api/v1/webhook-deliveries/{id}/replayWebhook operations

Replay a prior webhook delivery.

X-API-KeyGuide
Implementation details

Re-fires the same event payload with a fresh signature. Use after fixing a receiver bug or recovering from downtime.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
iduuidYesDelivery id.

Responses

200Replay enqueued or dispatched.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

Production notes

  • Your receiver must still be idempotent because replay intentionally delivers an event more than once.

Embed Config

Allow storefront origins and set merchant branding used by hosted and embedded checkout.

GET/api/v1/embed-configSetup

Read allowed origins and checkout branding.

X-API-KeyGuide
Implementation details

Use this in setup tooling or dashboards to show which parent origins and brand values are currently configured.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Responses

200Current embed config.

Response fields

FieldTypeRequiredDescription
allowedOriginsstring[]NoOrigins allowed to embed checkout.
primaryColorstring | nullNoDefault checkout brand color.
logoUrlurl | nullNoDefault checkout logo.
merchantNamestring | nullNoBuyer-facing merchant name.

SDK coverage

@usethrottle/cli · Developer setup CLI.

  • throttle embed-config get

The CLI is the easiest way to configure origins during setup.

PUT/api/v1/embed-configSetup

Set allowed origins and checkout branding.

X-API-KeyGuide
Implementation details

Required before embedding checkout in production. The parentOrigin passed to the SDK must match an allowed origin.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Request body

FieldTypeRequiredDescription
allowedOriginsstring[]NoAllowed parent origins. Max 20, unique.
primaryColorstringNoBrand color forwarded to hosted checkout (hex `#rrggbb`).
logoUrlurlNoLogo URL used by hosted checkout.
merchantNamestringNoBuyer-facing merchant name, 1 to 100 characters.
cartRecoveryUrlTemplatestring | nullNoAbsolute https URL template for abandoned-cart recovery emails. Must contain a `{cartId}` placeholder (e.g. `https://store.com/cart?c={cartId}`). When set, idle carts with a known customer trigger the recovery email; when unset, recovery is webhook-only. Pass null to clear.
cartAbandonmentThresholdMinutesinteger | nullNoMinutes of inactivity before an open/checkout cart is treated as abandoned (fires `cart.abandoned` + any recovery email). Range 15 to 129600 (90 days). Pass null to clear; when unset, the platform default of 1440 (24h) applies.

Responses

200Updated embed config returned.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/cli · Developer setup CLI.

  • throttle embed-config set --origins ...

Use exact origins, including scheme and host. Do not include paths.

Subscriptions

Use recurring checkout plus subscription APIs for buyer portals and merchant-side management.

POST/api/v1/subscriptionsServer-side

Create a subscription manually.

X-API-KeyGuide
Implementation details

Use for manual creation flows after a vaulted payment method exists. Embed-driven create:auto remains the fastest checkout path.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Request body

FieldTypeRequiredDescription
customerIduuidYesThrottle customer id.
applicationIduuidNoOptional application id.
planReferencestringYesYour plan id.
planNamestringNoBuyer-facing plan name.
intervalweekly | monthly | quarterly | yearlyYesBilling interval.
amountintegerYesRecurring amount in minor units.
currencystringNoThree-letter currency code.
Default: USD
currentPeriodStartdate-timeYesCurrent period start (ISO 8601).
currentPeriodEnddate-timeYesCurrent period end (ISO 8601).
trialEnddate-timeNoOptional trial end.
metadataobjectNoMerchant-owned metadata.

Responses

201Subscription created.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/subscriptions/server · Server-side subscription SDK.

  • createSubscriptionsClient().create(input)
  • useCreateSubscription()

The server SDK accepts camelCase fields and can resolve externalCustomerId to the Throttle customer row before create.

GET/api/v1/subscriptionsServer-side

List subscriptions for a buyer portal or backend job.

X-API-KeyGuide
Implementation details

Filter by Throttle customer id, your external customer id, or status. Proxy this through your backend for buyer-facing portals.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Query parameters

FieldTypeRequiredDescription
cursorstringNoCursor for pagination.
limitintegerNoPage size, 1 to 100.
Default: 20
customerIduuidNoThrottle customer id filter.
externalCustomerIdstringNoYour customer id. Mutually exclusive with customerId.
statusactive | paused | cancelled | past_due | trialingNoOptional status filter.
intervalweekly | monthly | quarterly | yearlyNoOptional billing interval filter.
qstringNoSearch subscription id, customer id, plan, status, interval, or metadata.

Responses

200Paginated subscription list.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/subscriptions/server · Server-side SDK plus browser hooks through your backend proxy.

  • createSubscriptionsClient().list(filters)
  • useSubscriptions(filters)

Buyer-facing portals should route hooks through createSubscriptionProxyHandler so reads are pinned to the authenticated externalCustomerId.

GET/api/v1/subscriptions/{id}Server-side

Fetch a subscription.

X-API-KeyGuide
Implementation details

Use for buyer portal detail pages, support tooling, and access-gating checks.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
iduuidYesSubscription id.

Responses

200Subscription detail returned.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/subscriptions/server · Server-side SDK plus browser hooks through your backend proxy.

  • createSubscriptionsClient().get(id)
  • useSubscription(id)

The proxy helper verifies the subscription belongs to the authenticated buyer before forwarding mutations.

PATCH/api/v1/subscriptions/{id}Server-side

Change subscription plan or metadata.

X-API-KeyGuide
Implementation details

Updates plan reference, display name, interval, amount, or metadata. Changes apply according to the subscription lifecycle rules documented in the guide.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Path parameters

FieldTypeRequiredDescription
iduuidYesSubscription id.

Request body

FieldTypeRequiredDescription
planReferencestringNoUpdated plan id.
planNamestringNoUpdated plan name.
intervalweekly | monthly | quarterly | yearlyNoUpdated interval.
amountintegerNoUpdated amount in minor units.
metadataobjectNoReplacement metadata.

Responses

200Updated subscription returned.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/subscriptions/server · Server-side SDK plus browser hooks through your backend proxy.

  • createSubscriptionsClient().update(id, input)
  • createSubscriptionsClient().changePlan(input)
  • useUpdateSubscription()
  • useChangePlan()

No mid-period proration is applied in v1. Use your own plan catalog as the source of truth for planReference and amount.

POST/api/v1/subscriptions/{id}/pauseServer-side

Pause a subscription.

X-API-KeyGuide
Implementation details

Moves an active subscription into paused state from your backend proxy.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
iduuidYesSubscription id.

Responses

200Paused subscription returned.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/subscriptions/server · Server-side SDK plus browser hooks through your backend proxy.

  • createSubscriptionsClient().pause(id)
  • usePauseSubscription()

The proxy helper verifies buyer ownership before forwarding pause requests.

POST/api/v1/subscriptions/{id}/resumeServer-side

Resume a paused subscription.

X-API-KeyGuide
Implementation details

Moves a paused subscription back into an active billing state.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
iduuidYesSubscription id.

Responses

200Resumed subscription returned.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/subscriptions/server · Server-side SDK plus browser hooks through your backend proxy.

  • createSubscriptionsClient().resume(id)
  • useResumeSubscription()

The proxy helper verifies buyer ownership before forwarding resume requests.

POST/api/v1/subscriptions/{id}/cancelServer-side

Cancel a subscription immediately or at period end.

X-API-KeyGuide
Implementation details

Use from buyer portals and support tooling. For buyer-facing use, authorize ownership in your backend before calling Throttle.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Path parameters

FieldTypeRequiredDescription
iduuidYesSubscription id.

Request body

FieldTypeRequiredDescription
atPeriodEndbooleanNoIf true, cancels at the end of the current billing period.
Default: false

Responses

200Updated subscription returned.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/subscriptions/server · Server-side SDK plus browser hooks through your backend proxy.

  • createSubscriptionsClient().cancel(id, { atPeriodEnd })
  • useCancelSubscription()

Pause and resume follow the same backend-proxy pattern.

POST/api/v1/subscriptions/eligibility-checkServer-side

Check trial eligibility for a vaulted card.

X-API-KeyGuide
Implementation details

Pre-flight trial fraud protection by checking whether a payment method fingerprint has already used a trial for this merchant.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Request body

FieldTypeRequiredDescription
paymentMethodIduuidYesCustomer payment method id owned by the authenticated merchant.

Responses

200Eligibility result.

Response fields

FieldTypeRequiredDescription
eligiblebooleanNoWhether the payment method can receive a trial.
reasonstringNoReason when blocked.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/subscriptions/server · Server-side SDK plus browser hook through your backend proxy.

  • createSubscriptionsClient().checkTrialEligibility({ paymentMethodId })
  • useTrialEligibility()

Use after a card is vaulted when your UI needs to decide whether to offer a trial.

GET/api/v1/customers/by-external/{externalId}Server-side

Resolve a customer by your own customer id.

X-API-KeyGuide
Implementation details

Use when your app stores only its own user id. Throttle resolves the canonical customer row for subscription lists, direct subscription creates, and payment-method reads.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
externalIdstringYesYour customer or user id previously passed as externalCustomerId.

Responses

200Customer returned.

Response fields

FieldTypeRequiredDescription
iduuidYesThrottle customer id.
externalIdstring | nullNoYour customer id when one is attached.
emailstring | nullNoCustomer email.
metadataobjectNoCustomer metadata.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
404not_foundNo Throttle customer is associated with that external id.Create a checkout session or customer with customer.externalCustomerId first.

SDK coverage

@usethrottle/subscriptions/server · Server-side SDK plus browser hooks through your backend proxy.

  • createSubscriptionsClient().getCustomerByExternalId(externalId)
  • useCustomerByExternalId(externalId)

createSubscriptionProxyHandler pins this path to the authenticated buyer and ignores ids supplied by the browser.

GET/api/v1/customers/{id}/payment-methodsServer-side

List saved payment methods for a customer.

X-API-KeyGuide
Implementation details

Use on subscription confirmation pages and buyer portals when you need to show the vaulted card summary used for renewals.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
iduuidYesCustomer id.

Responses

200Saved payment-method summaries returned.

Response fields

FieldTypeRequiredDescription
iduuidYesPayment method id.
methodTypecard | stringNoPayment method type.
cardBrandstring | nullNoCard brand.
cardLastFourstring | nullNoLast four digits for card methods.
isDefaultbooleanNoWhether this method is the default renewal method.
isActivebooleanNoWhether this method can be used for future renewals. Paused methods remain visible but are not charged.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.

SDK coverage

@usethrottle/subscriptions/server · Server-side SDK plus browser hook through your backend proxy.

  • createSubscriptionsClient().listCustomerPaymentMethods(customerId)
  • useCustomerPaymentMethods(customerId)

When routed through createSubscriptionProxyHandler, payment-method reads are resolved from the authenticated externalCustomerId instead of trusting the browser-supplied customer id.

POST/api/v1/customers/{customerId}/payment-methods/{id}/pauseServer-side

Pause a saved payment method.

Clerk JWT or X-API-Key
Implementation details

Keeps the vaulted payment method on file but prevents renewals from charging it until it is resumed.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
customerIduuidYesCustomer id.
iduuidYesPayment method id.

Responses

200Updated payment method returned with isActive=false.

Response fields

FieldTypeRequiredDescription
iduuidYesPayment method id.
isActivebooleanNoFalse after pause.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
POST/api/v1/customers/{customerId}/payment-methods/{id}/resumeServer-side

Resume a saved payment method.

Clerk JWT or X-API-Key
Implementation details

Allows a previously paused vaulted payment method to be used for future renewals again.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
customerIduuidYesCustomer id.
iduuidYesPayment method id.

Responses

200Updated payment method returned with isActive=true.

Response fields

FieldTypeRequiredDescription
iduuidYesPayment method id.
isActivebooleanNoTrue after resume.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
POST/api/v1/subscriptions/{id}/change-planServer-side

Change a subscription plan immediately or at period end.

X-API-KeyGuide
Implementation details

Use effective: "now" for upgrades (charges the stored card immediately, resets the billing period). Use effective: "period_end" for downgrades (sets pending_* fields, applies on the next renewal). Returns the updated subscription.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Path parameters

FieldTypeRequiredDescription
iduuidYesSubscription id.

Request body

FieldTypeRequiredDescription
planReferencestringYesYour plan id from your plan catalog.
planNamestringNoBuyer-facing plan name.
intervalweekly | monthly | quarterly | yearlyYesBilling interval for the new plan.
amountintegerYesRecurring amount in minor units for the new plan.
effective"now" | "period_end"Yes"now" charges the card and applies immediately (upgrade path). "period_end" defers the change to next renewal (downgrade path).

Responses

200Updated subscription returned.

Response fields

FieldTypeRequiredDescription
iduuidYesSubscription id.
statusstringYesCurrent status.
pendingPlanReferencestring | nullNoSet when effective: "period_end". Contains the deferred plan id. Null for effective: "now".
pendingPlanNamestring | nullNoDeferred plan display name. Null when no change is pending.
pendingIntervalstring | nullNoDeferred billing interval. Null when no change is pending.
pendingAmountinteger | nullNoDeferred amount in minor units. Null when no change is pending.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
400invalid_subscription_stateplanReference is already equal to the current plan reference.Only call change-plan when the plan is actually changing.
402payment_failedeffective: "now" was used but the stored card charge was declined by the processor.Surface the failure to the buyer and let them update their payment method.
404not_foundNo subscription found for the given id.Confirm the subscription id and API key belong to the same application.
Immediate upgrade
curl -X POST https://api.usethrottle.dev/api/v1/subscriptions/sub_abc/change-plan \
  -H "x-api-key: $THROTTLE_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "planReference": "pro_yearly",
    "planName": "Pro Yearly",
    "interval": "yearly",
    "amount": 29900,
    "effective": "now"
  }'
Scheduled downgrade
curl -X POST https://api.usethrottle.dev/api/v1/subscriptions/sub_abc/change-plan \
  -H "x-api-key: $THROTTLE_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "planReference": "starter_monthly",
    "planName": "Starter Monthly",
    "interval": "monthly",
    "amount": 999,
    "effective": "period_end"
  }'

Production notes

  • effective: "now" is the upgrade path. It charges the stored card for the full new plan amount, resets the billing period from now, emits subscription.plan_changed, and clears any pending_* fields.
  • effective: "period_end" is the downgrade path. No charge is made. The pending_* fields are written, subscription.plan_change_scheduled fires, and the renewal cron applies the change on the next period end.
  • A pending change can be cancelled with DELETE /api/v1/subscriptions/:id/pending-change.
  • A new change-plan call overwrites any existing pending_* fields.
  • cancelAtPeriodEnd takes precedence: if the subscription is already scheduled to cancel at period end, the pending change will never apply unless you first unset the cancel flag.
DELETE/api/v1/subscriptions/{id}/pending-changeServer-side

Cancel a scheduled plan change.

X-API-KeyGuide
Implementation details

Clears the pending_* fields set by a prior change-plan call with effective: "period_end". The subscription continues on its current plan. Emits subscription.updated.

Headers

FieldTypeRequiredDescription
x-api-keystringYesYour Throttle secret API key. Keep this on your backend only.

Path parameters

FieldTypeRequiredDescription
iduuidYesSubscription id.

Responses

200Updated subscription returned with all pending_* fields null.

Response fields

FieldTypeRequiredDescription
iduuidYesSubscription id.
pendingPlanReferencenullNoAlways null after clear.
pendingPlanNamenullNoAlways null after clear.
pendingIntervalnullNoAlways null after clear.
pendingAmountnullNoAlways null after clear.

Common errors

StatusCodeCauseFix
401unauthorizedMissing, malformed, or revoked API key.Send a valid secret key from your backend and rotate the key if it may have leaked.
422validation_errorA required field is missing or a field does not match the expected type, enum, or format.Compare the body against the field table. Amounts are integer minor units and UUID fields must be valid UUIDs.
404not_foundNo subscription found for the given id.Confirm the subscription id and API key belong to the same application.
Cancel pending change
curl -X DELETE https://api.usethrottle.dev/api/v1/subscriptions/sub_abc/pending-change \
  -H "x-api-key: $THROTTLE_API_KEY"

Production notes

  • Safe to call even when no pending change exists — the call is a no-op and returns the current subscription.
  • Does not affect cancelAtPeriodEnd. Use PATCH /api/v1/subscriptions/:id with cancelAtPeriodEnd: false to cancel a scheduled cancellation.

Workspace Environments

Manage the workspace-wide environment catalog. Each workspace has one immutable production environment; every custom environment is non-production and routes to sandbox-provider credentials. These routes are selected by workspace id and do not require X-Throttle-Environment-Id.

GET/api/v1/workspaces/{workspaceId}/environmentsSetup

List workspace environments.

Clerk JWTGuide
Implementation details

Returns active workspace environments by default. Add includeArchived=true for settings, audit, or recovery screens.

Headers

FieldTypeRequiredDescription
authorizationBearer <dashboard-session>YesClerk dashboard session token. API keys cannot call workspace-level routes.

Path parameters

FieldTypeRequiredDescription
workspaceIduuidYesWorkspace id.

Query parameters

FieldTypeRequiredDescription
includeArchivedtrue | falseNoWhen true, includes archived custom environments.
Default: false

Responses

200Workspace environments returned.

Response fields

FieldTypeRequiredDescription
iduuidYesEnvironment id.
slugstringYesEnvironment slug used in API key prefixes.
namestringYesHuman-readable environment name.
kindproduction | non_productionYesProduction is the only production kind.
providerEnvironmentproduction | sandboxYesProvider routing target.
statusactive | archivedYesArchived environments are hidden from normal selectors.
isSystembooleanYesSystem environments cannot be archived.

Common errors

StatusCodeCauseFix
403application_key_workspace_routeAn API key was used for a workspace-level route.Call this route from the dashboard or another Clerk-authenticated setup flow.
POST/api/v1/workspaces/{workspaceId}/environmentsSetup

Create a custom non-production environment.

Clerk JWTGuide
Implementation details

Creates a new sandbox-provider environment such as UAT, staging, or QA. Production is created by the system and cannot be created through this endpoint. Existing applications in the workspace receive fresh per-environment settings containers immediately.

Headers

FieldTypeRequiredDescription
authorizationBearer <dashboard-session>YesClerk dashboard session token. API keys cannot call workspace-level routes.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Path parameters

FieldTypeRequiredDescription
workspaceIduuidYesWorkspace id.

Request body

FieldTypeRequiredDescription
slugstringYesUnique workspace slug. It is normalized to lowercase kebab-case and cannot be production.
namestringYesDisplay name shown in the dashboard selector and settings.

Responses

201Custom environment created.

Common errors

StatusCodeCauseFix
400reserved_environment_slugSlug is production.Use a non-production slug such as uat, staging, qa, or preview.
409environment_slug_takenAnother environment in the workspace already uses that slug.Pick a unique slug.
DELETE/api/v1/workspaces/{workspaceId}/environments/{environmentId}Setup

Archive a custom environment.

Clerk JWTGuide
Implementation details

Archives a non-system workspace environment. Historical rows keep their environment id; the environment is removed from normal selectors and new work should use another active environment. Production cannot be archived or deleted.

Headers

FieldTypeRequiredDescription
authorizationBearer <dashboard-session>YesClerk dashboard session token. API keys cannot call workspace-level routes.

Path parameters

FieldTypeRequiredDescription
workspaceIduuidYesWorkspace id.
environmentIduuidYesEnvironment id to archive.

Responses

200Environment archived.

Common errors

StatusCodeCauseFix
400system_environment_lockedThe requested environment is production or another system environment.Only archive custom non-production environments.
404environment_not_foundEnvironment id is unknown for this workspace.Refresh the environment list and retry.

Auth and API Keys

API keys are workspace credentials minted from the dashboard. Two types exist: secret keys (sk_) for server-side use — they may hold any granted scope, including the wildcard — and publishable keys (pk_) that are safe to embed in browser/frontend code and may hold ONLY the stateless compute scopes shipping_quotes:write and tax_calculations:write. Both carry the workspace environment slug (for example sk_uat_ or sk_production_) that pins the key to one environment. Never expose a secret key in browser code.

GET/api/v1/api-keysSetup

List active API keys for the current merchant.

Clerk JWT or X-API-Key
Implementation details

Use in dashboard or setup tooling. Runtime storefront code should not list keys.

Headers

FieldTypeRequiredDescription
authorization or x-api-keystringYesClerk JWT for dashboard flows or secret key for backend setup tooling.

Responses

200Active key metadata. Raw secret values are never returned.
POST/api/v1/api-keysSetup

Create a secret (sk_) or publishable (pk_) API key.

Clerk JWTGuide
Implementation details

Mint a new key for the selected workspace environment. To mint a browser-safe publishable (pk_) key, include the sentinel string "publishable" as the first entry of the scopes array; otherwise a server-side secret (sk_) key is created. The minted key inherits the request environment selected by X-Throttle-Environment-Id, so the raw value includes the environment slug, for example sk_uat_/pk_uat_ or sk_production_/pk_production_. Requested scopes are validated against the @core/scopes registry: unknown scopes, staff-only scopes (the admin:* family), and — for publishable keys — any scope outside shipping_quotes:write / tax_calculations:write are rejected with 400 invalid_scope. The raw key is returned once; store it securely and never ship a secret key to the browser. Only Clerk-authenticated dashboard callers may create keys (an sk_ key cannot mint another key — 403 forbidden).

Headers

FieldTypeRequiredDescription
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Request body

FieldTypeRequiredDescription
namestringYesKey label.
scopesstring[]YesScopes assigned to the key. Secret keys accept any granted scope or the wildcard "*". To mint a publishable (pk_) key, prepend the sentinel "publishable" to the array; a pk_ key then accepts only shipping_quotes:write and tax_calculations:write (never the wildcard).

Responses

201Key created.

Response fields

FieldTypeRequiredDescription
rawKeystringYesRaw key, prefixed by type + environment slug (for example sk_uat_ or pk_production_). Returned once.
id, name, scopesstring, string, arrayNoKey metadata.

Common errors

StatusCodeCauseFix
400invalid_scopeA requested scope is unknown, is staff-only (admin:*), or — for a publishable key — is not one of shipping_quotes:write / tax_calculations:write (or includes the wildcard).Pick scopes from the scopes reference. For a pk_ key request only shipping_quotes:write and/or tax_calculations:write.
DELETE/api/v1/api-keys/{id}Setup

Revoke an API key.

Clerk JWT
Implementation details

Use when rotating credentials or removing access for an integration. Revoked keys can no longer call secret-key endpoints.

Path parameters

FieldTypeRequiredDescription
iduuidYesAPI key id.

Responses

204Key revoked. No JSON body is returned.

Common errors

StatusCodeCauseFix
404not_foundThe key id is unknown or belongs to another merchant.Refresh the key list and retry with a valid key id.

Workspace Invitations

Create, list, resend, revoke, and accept workspace membership invitations. Invitations are signed 7-day JWTs sent by email; the accept endpoint binds the Clerk user to the workspace.

POST/api/v1/workspaces/{workspaceId}/invitesSetup

Create a workspace invitation.

Clerk JWTGuide
Implementation details

Sends an invitation email to the target address. The invitee must accept with a Clerk account whose email matches exactly. Requires workspace:invite permission (or workspace:invite-admin when granting workspace_admin role). Owners and workspace admins can set environmentGrants; application admins default to all_non_production for app-scoped invites.

Path parameters

FieldTypeRequiredDescription
workspaceIduuidYesWorkspace id.

Request body

FieldTypeRequiredDescription
emailstringYesInvitee email address.
workspaceRolestringNoWorkspace-level role to grant on accept. One of workspace_admin. Omit for application-only access.
applicationRolesarrayNoPer-application role assignments. Each entry is { applicationId, role } where role is admin | developer | finance | viewer.
environmentGrantsobjectNoWorkspace-wide environment access. Shape: { grantType: all | all_non_production | production_only | selected, environmentIds?: uuid[] }. selected requires at least one active environment id.

Responses

201Invitation created and email sent.

Response fields

FieldTypeRequiredDescription
iduuidNoInvitation id.
emailstringNoInvitee email.
statusstringNoAlways pending on creation.
expiresAtISO 8601NoToken expiry, 7 days out.

Common errors

StatusCodeCauseFix
403permission_deniedCaller lacks workspace:invite or workspace:invite-admin.Use an owner or workspace_admin token.
403environment_grants_forbiddenA non-owner/non-workspace-admin tried to set explicit environment grants.Ask an owner or workspace admin to set environment access.
400invalid_environment_grantsselected was sent without environmentIds, or ids were sent for a non-selected grant type.Send a valid grantType and include environmentIds only for selected grants.
409already_memberThe email address already belongs to an active workspace member.Use the member management endpoints to update roles instead.
GET/api/v1/workspaces/{workspaceId}/invitesSetup

List workspace invitations.

Clerk JWT
Implementation details

Returns all invitations for the workspace, including pending, accepted, revoked, and expired. Filterable by status.

Path parameters

FieldTypeRequiredDescription
workspaceIduuidYesWorkspace id.

Query parameters

FieldTypeRequiredDescription
statusstringNoFilter by invitation status. One of pending | accepted | revoked | expired.

Responses

200Invitation list.

Response fields

FieldTypeRequiredDescription
itemsarrayNoArray of invitation objects.
totalintegerNoTotal matching invitations.
POST/api/v1/workspaces/{workspaceId}/invites/{id}/resendSetup

Resend a pending invitation.

Clerk JWT
Implementation details

Rotates the invitation token (old token is immediately invalidated) and sends a new email with a fresh 7-day expiry.

Path parameters

FieldTypeRequiredDescription
workspaceIduuidYesWorkspace id.
iduuidYesInvitation id.

Responses

200Token rotated, email resent.

Response fields

FieldTypeRequiredDescription
expiresAtISO 8601NoNew token expiry.

Common errors

StatusCodeCauseFix
409invite_not_pendingInvitation is already accepted, revoked, or expired.Create a new invitation.
POST/api/v1/workspaces/{workspaceId}/invites/{id}/revokeSetup

Revoke a pending invitation.

Clerk JWT
Implementation details

Kills the invitation token immediately. The invitee can no longer use the email link to join.

Path parameters

FieldTypeRequiredDescription
workspaceIduuidYesWorkspace id.
iduuidYesInvitation id.

Responses

204Invitation revoked. No JSON body.
POST/api/v1/invites/acceptSetup

Accept a workspace invitation.

Clerk JWT
Implementation details

Validates the signed token, verifies the Clerk user email matches the invited address, creates the workspace member record, and applies role assignments. The token is consumed on success.

Request body

FieldTypeRequiredDescription
tokenstringYesSigned JWT from the invite email link.

Responses

200Member joined.

Response fields

FieldTypeRequiredDescription
workspaceIduuidNoThe joined workspace.
memberIduuidNoNew workspace member record id.

Common errors

StatusCodeCauseFix
400invite_expiredToken TTL has elapsed.Ask an admin to resend the invitation.
400invite_email_mismatchClerk account email does not match the invited address.Sign in with the exact email address the invitation was sent to.
409already_memberCaller is already a member of this workspace.No action needed; access is already granted.

Workspace Members

List, inspect, update, and remove workspace members. Member records hold workspace-level role assignments, per-application role assignments, and workspace-wide environment grants.

GET/api/v1/workspaces/{workspaceId}/membersSetup

List workspace members.

Clerk JWTGuide
Implementation details

Returns all active members with their workspace role, per-application role assignments, and environment grants. Requires workspace:edit-member or workspace:remove-member permission.

Path parameters

FieldTypeRequiredDescription
workspaceIduuidYesWorkspace id.

Responses

200Member list.

Response fields

FieldTypeRequiredDescription
itemsarrayNoArray of member objects.
items[].environmentGrantsobjectNoEnvironment grant summary: { grantType, environmentIds }. Owners resolve to all.
totalintegerNoTotal member count.
GET/api/v1/workspaces/{workspaceId}/members/meSetup

Get the calling user's membership.

Clerk JWT
Implementation details

Returns the workspace role, application role assignments, and environment grants for the authenticated caller. No elevated permissions required.

Path parameters

FieldTypeRequiredDescription
workspaceIduuidYesWorkspace id.

Responses

200Caller's membership record.

Response fields

FieldTypeRequiredDescription
memberIduuidNoMembership record id.
workspaceRolestringNoowner | workspace_admin | null.
applicationRolesarrayNoPer-application role assignments.
environmentGrantsobjectNoEnvironment grant summary for the calling member.
PATCH/api/v1/workspaces/{workspaceId}/members/{memberId}Setup

Update a member role.

Clerk JWT
Implementation details

Change the workspace-level role, update per-application role assignments, or replace environment grants. Send only the fields you want to change. Requires workspace:edit-member; only owner/workspace_admin callers may set environmentGrants.

Path parameters

FieldTypeRequiredDescription
workspaceIduuidYesWorkspace id.
memberIduuidYesMember id.

Request body

FieldTypeRequiredDescription
workspaceRolestringNoNew workspace role. One of workspace_admin or null to remove.
applicationRolesarrayNoPer-application role assignments to upsert. Each entry is { applicationId, role }.
environmentGrantsobjectNoReplace environment access. Shape: { grantType: all | all_non_production | production_only | selected, environmentIds?: uuid[] }.

Responses

200Updated member record.

Common errors

StatusCodeCauseFix
403permission_deniedCaller cannot grant a role higher than their own.Use an owner or workspace_admin token.
403environment_grants_forbiddenCaller cannot manage environment grants.Use an owner or workspace_admin token.
400invalid_environment_grantsEnvironment grants were malformed.For selected grants, include at least one environment id; omit ids for other grant types.
DELETE/api/v1/workspaces/{workspaceId}/members/{memberId}Setup

Remove a member from the workspace.

Clerk JWT
Implementation details

Revokes all application roles and removes the workspace membership record in one call. Requires workspace:remove-member.

Path parameters

FieldTypeRequiredDescription
workspaceIduuidYesWorkspace id.
memberIduuidYesMember id.

Responses

204Member removed. No JSON body.

Common errors

StatusCodeCauseFix
403cannot_remove_ownerAttempt to remove the workspace owner.Transfer ownership first, then remove the former owner.
DELETE/api/v1/workspaces/{workspaceId}/members/{memberId}/applications/{applicationId}Setup

Revoke a member's access to one application.

Clerk JWT
Implementation details

Removes the per-application role for the specified application. Workspace membership and roles on other applications are unchanged. Requires application:edit-app-member on the target application.

Path parameters

FieldTypeRequiredDescription
workspaceIduuidYesWorkspace id.
memberIduuidYesMember id.
applicationIduuidYesApplication to revoke access on.

Responses

204Application role revoked. No JSON body.
GET/api/v1/auth/permissionsSetup

Resolve permissions for the authenticated caller.

Clerk JWTGuide
Implementation details

Returns every permission key and whether it resolves to true for the caller. Pass x-application-id to include application-level role flags. Useful for building UI conditionals.

Responses

200Permissions map.

Response fields

FieldTypeRequiredDescription
workspaceRolestringNoCaller workspace role or null.
appRolestringNoCaller application role on x-application-id or null.
permissionsobjectNoMap of permission key → boolean.

Connectors

Manage payment-provider connections and configure card-transaction routing rules. Routing lets you define which providers are tried, in which order, and for which buyer regions. These are dashboard/merchant-facing routes; all require a Clerk JWT and the connectors:read or connectors:write scope.

GET/api/v1/payment-routingSetup

Get the card-transaction routing config.

Clerk JWT
Implementation details

Returns the current routing configuration for the application: a set of condition-based rules and a default cascade. Rules are evaluated in order; the first rule whose conditions all match wins and its cascade is used. Conditions within a rule are AND-ed. The default cascade applies to any transaction not matched by a rule. Within each cascade, providers are tried in order — if the first provider fails, the next is attempted automatically. Routing is now supported in production environments.

Headers

FieldTypeRequiredDescription
authorizationBearer <dashboard-session>YesClerk dashboard session token. API keys cannot call workspace-level routes.

Responses

200Current routing config.

Response fields

FieldTypeRequiredDescription
data.rulesarrayYesOrdered list of condition-based routing rules. Each rule is evaluated in order; the first rule whose conditions all match is applied.
data.rules[].conditionsarrayYesArray of conditions that must all be satisfied (AND-ed) for this rule to match. Each condition matches against a specific transaction attribute.
data.rules[].conditions[].typestringYesCondition type: "country" (buyer country), "cardScheme" (card brand), "cardSource" (payment source), "cardType" (credit/debit/prepaid), "cardCountry" (card issuer country), "paymentSource" (payment initiation source), "amount" (transaction amount), "currency" (transaction currency), or "metadata" (transaction metadata key/value matching).
data.rules[].conditions[].opstringYesOperator: for set conditions (country/cardScheme/cardSource/cardType/cardCountry/paymentSource/currency): "is_one_of" or "is_not_one_of". For amount conditions: "gt" (greater than), "lt" (less than), or "between". For metadata conditions: "includes" or "excludes".
data.rules[].conditions[].valuesstring[]NoArray of values for set conditions. For country: ISO 3166-1 alpha-2 codes. For cardScheme: visa, mastercard, amex, etc. For cardSource: raw, token, applepay, googlepay, network-token. For cardType: credit, debit, prepaid. For cardCountry: ISO 3166-1 alpha-2 codes representing the card issuer country (e.g. "US", "GB"). For paymentSource: ecommerce, moto, recurring, installment, card_on_file. For currency: ISO 4217 codes. For metadata conditions: string values to match against the metadata key.
data.rules[].conditions[].keystringNoMetadata key to match against. Required for metadata conditions. Throttle automatically stamps "throttle_order_type" on every transaction ("one_off" for one-off checkouts, "recurring" for subscription renewals). Any metadata the merchant sends at checkout is also routable by its key.
data.rules[].conditions[].currencystringNoCurrency for amount conditions (e.g., "USD"). Required for amount conditions.
data.rules[].conditions[].minnumberNoMinimum amount in major units (e.g., dollars, not cents) for "gt" or "between" operators.
data.rules[].conditions[].maxnumberNoMaximum amount in major units for "lt" or "between" operators.
data.rules[].cascadestring[]YesOrdered list of connector IDs to use when this rule matches. First entry is attempted first; subsequent entries are automatic fail-over.
data.defaultCascadestring[]YesOrdered list of connector IDs tried for any transaction not matched by any rule. First entry is attempted first; subsequent entries are automatic fail-over.

Common errors

StatusCodeCauseFix
403permission_deniedCaller does not have the application:settings permission.Use a Clerk session with admin or owner role on the target application.
502gr4vy_upstream_errorThe Gr4vy flows API returned an unexpected error.Retry after a short delay. Check Gr4vy status if the error persists.
Get routing config
curl https://api.usethrottle.dev/api/v1/payment-routing \
  -H "authorization: Bearer <clerk-session-token>" \
  -H "x-application-id: <application-uuid>" \
  -H "x-throttle-environment-id: <environment-uuid>"
Example response
{
  "data": {
    "rules": [
      {
        "conditions": [
          { "type": "country", "op": "is_one_of", "values": ["CA", "MX"] }
        ],
        "cascade": ["connector-id-north-america", "connector-id-backup"]
      }
    ],
    "defaultCascade": ["connector-id-stripe", "connector-id-backup"]
  }
}

Production notes

  • Routing is supported in both production and non-production environments.
  • Rules are evaluated in order; the first rule whose conditions all match is applied.
  • Conditions within a rule are AND-ed together.
  • Use GET /api/v1/routing-connectors to list connector IDs eligible for a cascade.
PUT/api/v1/payment-routingSetup

Replace the card-transaction routing config.

Clerk JWT
Implementation details

Atomically replaces the full routing configuration using condition-based rules. Supply the complete desired state; the previous config is discarded and rebuilt from the supplied body. All connector IDs must be active connectors for the application. Condition values must conform to the allowed vocabulary for each condition type. Routing is now supported in production environments.

Headers

FieldTypeRequiredDescription
authorizationBearer <dashboard-session>YesClerk dashboard session token. API keys cannot call workspace-level routes.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Request body

FieldTypeRequiredDescription
rulesarrayYesArray of condition-based routing rules. May be empty to use only the default cascade globally. Rules are evaluated in order; the first rule whose conditions all match is applied.
rules[].conditionsarrayYesArray of conditions for this rule. All conditions must be satisfied (AND-ed) for the rule to match. May be empty.
rules[].conditions[].typestringYesCondition type: "country", "cardScheme", "cardSource", "cardType", "cardCountry", "paymentSource", "amount", or "metadata".
rules[].conditions[].opstringYesOperator. For set types (country/cardScheme/cardSource/cardType/cardCountry/paymentSource): "is_one_of" or "is_not_one_of". For amount: "gt" (greater than), "lt" (less than), or "between". For metadata: "includes" or "excludes".
rules[].conditions[].valuesstring[]NoFor set conditions: array of allowed values. For country: ISO 3166-1 alpha-2 codes (US, CA, GB, etc.). For cardScheme: visa, mastercard, amex, discover, diners-club, jcb, maestro, unionpay, etc. For cardSource: raw, token, applepay, googlepay, network-token. For cardType: credit, debit, prepaid. For cardCountry: ISO 3166-1 alpha-2 codes representing the card issuer country (e.g. "US", "GB"). For paymentSource: ecommerce, moto, recurring, installment, card_on_file. For currency: ISO 4217 codes. For metadata conditions: string values to match against the metadata key.
rules[].conditions[].keystringNoMetadata key to match against. Required for metadata conditions. Throttle automatically stamps "throttle_order_type" on every transaction ("one_off" for one-off checkouts, "recurring" for subscription renewals). Any metadata the merchant sends at checkout is also routable by its key.
rules[].conditions[].currencystringNoCurrency code for amount conditions (e.g., "USD"). Required for amount type.
rules[].conditions[].minnumberNoMinimum amount in major units for "gt" or "between" operators. Required for those operators.
rules[].conditions[].maxnumberNoMaximum amount in major units for "lt" or "between" operators. Required for those operators.
rules[].cascadestring[]YesOrdered list of connector IDs for this rule. Must contain at least one entry and must not have duplicates.
defaultCascadestring[]YesOrdered connector IDs tried for any transaction not matched by any rule. Must contain at least one entry and must not have duplicates.

Responses

200Updated routing config returned.

Response fields

FieldTypeRequiredDescription
data.rulesarrayYesThe persisted rules after the update.
data.defaultCascadestring[]YesThe persisted default cascade after the update.

Common errors

StatusCodeCauseFix
422routing_default_requireddefaultCascade is empty.Include at least one active connector ID in defaultCascade.
422routing_unknown_connectorA connector ID in a cascade does not exist or is not active for this application.List available connectors with GET /api/v1/routing-connectors and use only those IDs.
422routing_duplicate_connectorA connector ID appears more than once within the same cascade.Each connector may appear at most once per cascade.
422routing_empty_cascadeA rule cascade is empty.Each rule must include at least one connector ID.
422routing_rule_no_conditionsA routing rule has no conditions.Each rule must include at least one condition.
422routing_empty_condition_valuesA set-type condition (country, cardScheme, cardSource, cardType) has an empty values array.Include at least one value in the condition values array.
422routing_invalid_countryA country condition value is not a valid ISO 3166-1 alpha-2 code.Use two-letter uppercase country codes, e.g. "US", "CA".
422routing_invalid_currencyAn amount condition currency is not a valid ISO-4217 code.Use three-letter uppercase currency codes, e.g. "USD", "EUR".
422routing_invalid_amountAn amount condition is missing a required field (min for gt, max for lt, both for between) or a value is not a positive number.Provide the required numeric fields for the amount operator and ensure all values are positive.
422routing_amount_range_invalidAn amount between condition has min >= max.Ensure min is strictly less than max.
422routing_invalid_schemeA cardScheme condition value is not in the allowed card scheme vocabulary.Use one of the documented card scheme values (e.g. "visa", "mastercard", "amex").
422routing_invalid_card_sourceA cardSource condition value is not in the allowed card source vocabulary.Use one of: applepay, googlepay, network-token, raw, token.
422routing_invalid_card_typeA cardType condition value is not in the allowed card type vocabulary.Use one of: credit, debit, prepaid.
422routing_invalid_conditionAn unsupported condition type was supplied.Use one of: country, cardScheme, cardSource, cardType, cardCountry, paymentSource, amount.
502gr4vy_upstream_errorThe Gr4vy flows API returned an unexpected error.Retry after a short delay. The routing config was not partially applied.
Set routing config
curl -X PUT https://api.usethrottle.dev/api/v1/payment-routing \
  -H "authorization: Bearer <clerk-session-token>" \
  -H "x-application-id: <application-uuid>" \
  -H "x-throttle-environment-id: <environment-uuid>" \
  -H "content-type: application/json" \
  -d '{
    "rules": [
      {
        "conditions": [
          { "type": "country", "op": "is_one_of", "values": ["CA", "MX"] }
        ],
        "cascade": ["connector-id-north-america", "connector-id-backup"]
      }
    ],
    "defaultCascade": ["connector-id-stripe", "connector-id-backup"]
  }'

Production notes

  • This is a full replacement, not a patch. Omitting a rule removes it.
  • Rules are evaluated in order; the first rule whose conditions all match is applied.
  • Conditions within a rule are AND-ed together.
  • The fail-over order within each cascade is deterministic: the first connector in the array is attempted first, and subsequent entries are tried only if earlier ones fail.
  • Routing is supported in both production and non-production environments.
GET/api/v1/routing-connectorsSetup

List connectors eligible for a routing cascade.

Clerk JWT
Implementation details

Returns the active connectors that may be referenced in the defaultCascade or any rule cascade arrays. Only connectors with an active status are included. Use the returned id values when constructing or validating a routing config.

Headers

FieldTypeRequiredDescription
authorizationBearer <dashboard-session>YesClerk dashboard session token. API keys cannot call workspace-level routes.

Responses

200List of available connectors.

Response fields

FieldTypeRequiredDescription
data[].idstringYesConnector ID to use in cascade arrays.
data[].displayNamestringYesHuman-readable connector label.
data[].methodstringNoPayment method type such as card.

Common errors

StatusCodeCauseFix
403permission_deniedCaller does not have the application:settings permission.Use a Clerk session with admin or owner role on the target application.
List available connectors
curl https://api.usethrottle.dev/api/v1/routing-connectors \
  -H "authorization: Bearer <clerk-session-token>" \
  -H "x-application-id: <application-uuid>" \
  -H "x-throttle-environment-id: <environment-uuid>"
Example response
{
  "data": [
    { "id": "connector-id-stripe", "displayName": "Stripe (live)", "method": "card" },
    { "id": "connector-id-backup", "displayName": "Backup processor", "method": "card" }
  ]
}

Production notes

  • This endpoint always reflects the current active connectors. Re-fetch before building a new routing config to avoid referencing deleted or inactive connectors.
GET/api/v1/routing-payment-methodsSetup

List Gr4vy payment methods available to routing and decline rules.

Clerk JWT
Implementation details

Returns the payment methods Gr4vy supports for this environment. Use a returned id as the value of a paymentMethod condition (Other-transaction decline rules) or as the method of an Other-transaction routing rule. Card methods (card, network-token) are excluded — card routing and decline use card-specific conditions instead.

Headers

FieldTypeRequiredDescription
authorizationBearer <dashboard-session>YesClerk dashboard session token. API keys cannot call workspace-level routes.

Responses

200List of available Gr4vy payment methods.

Response fields

FieldTypeRequiredDescription
data[].idstringYesPayment method id to use as a paymentMethod condition value or an Other-routing rule method (e.g. "paypal", "ideal", "sepa").
data[].labelstringYesHuman-readable payment method label.

Common errors

StatusCodeCauseFix
403permission_deniedCaller does not have the application:settings permission.Use a Clerk session with admin or owner role on the target application.
502gr4vy_upstream_errorThe Gr4vy payment-method-definitions API returned an unexpected error.Retry after a short delay. Check Gr4vy status if the error persists.
List available payment methods
curl https://api.usethrottle.dev/api/v1/routing-payment-methods \
  -H "authorization: Bearer <clerk-session-token>" \
  -H "x-application-id: <application-uuid>" \
  -H "x-throttle-environment-id: <environment-uuid>"
Example response
{
  "data": [
    { "id": "paypal", "label": "PayPal" },
    { "id": "ideal", "label": "iDEAL" },
    { "id": "sepa", "label": "SEPA" }
  ]
}

Production notes

  • Card and network-token methods are excluded; card routing and decline use card-specific conditions (cardScheme, cardType, cardCountry, etc.).
GET/api/v1/card-declineSetup

Get the card-transaction decline rules.

Clerk JWT
Implementation details

Returns the current set of decline rules for card transactions. Rules are evaluated in order before routing occurs; the first rule whose conditions all match rejects the transaction outright and, when an errorCode is configured, returns that code to the integration. Conditions within a rule are AND-ed. A transaction that matches no decline rule proceeds to the routing step.

Headers

FieldTypeRequiredDescription
authorizationBearer <dashboard-session>YesClerk dashboard session token. API keys cannot call workspace-level routes.

Responses

200Current card-decline rules.

Response fields

FieldTypeRequiredDescription
data.rulesarrayYesOrdered list of decline rules. Each rule is evaluated in order; the first rule whose conditions all match causes the transaction to be declined.
data.rules[].conditionsarrayYesArray of conditions that must all be satisfied (AND-ed) for this rule to match. Allowed condition types: country, cardScheme, cardSource, cardType, cardCountry, amount, currency, metadata.
data.rules[].conditions[].typestringYesCondition type: "country" (buyer country), "cardScheme" (card brand), "cardSource" (payment source), "cardType" (credit/debit/prepaid), "cardCountry" (card issuer country), "amount" (transaction amount), "currency" (transaction currency), or "metadata" (transaction metadata key/value matching).
data.rules[].conditions[].opstringYesOperator: for set conditions (country/cardScheme/cardSource/cardType/cardCountry/currency): "is_one_of" or "is_not_one_of". For amount: "gt", "lt", or "between". For metadata: "includes" or "excludes".
data.rules[].conditions[].valuesstring[]NoArray of values for set conditions. For country: ISO 3166-1 alpha-2 codes. For cardScheme: visa, mastercard, amex, etc. For cardSource: raw, token, applepay, googlepay, network-token. For cardType: credit, debit, prepaid. For cardCountry: ISO 3166-1 alpha-2 codes representing the card issuer country (e.g. "US", "GB"). For currency: ISO 4217 codes. For metadata conditions: string values to match against the metadata key.
data.rules[].conditions[].keystringNoMetadata key to match against. Required for metadata conditions.
data.rules[].conditions[].currencystringNoCurrency for amount conditions (e.g., "USD"). Required for amount conditions.
data.rules[].conditions[].minnumberNoMinimum amount in major units for "gt" or "between" operators.
data.rules[].conditions[].maxnumberNoMaximum amount in major units for "lt" or "between" operators.
data.rules[].errorCodestringNoOptional error code returned to the integration when this rule declines the transaction. Must match ^flow_[a-z_]+$ (e.g. "flow_high_risk_country"). If omitted, a generic decline code is returned.

Common errors

StatusCodeCauseFix
403permission_deniedCaller does not have the application:settings permission.Use a Clerk session with admin or owner role on the target application.
502gr4vy_upstream_errorThe Gr4vy flows API returned an unexpected error.Retry after a short delay. Check Gr4vy status if the error persists.
Get card-decline rules
curl https://api.usethrottle.dev/api/v1/card-decline \
  -H "authorization: Bearer <clerk-session-token>" \
  -H "x-application-id: <application-uuid>" \
  -H "x-throttle-environment-id: <environment-uuid>"
Example response
{
  "data": {
    "rules": [
      {
        "conditions": [
          { "type": "country", "op": "is_one_of", "values": ["RU", "KP"] }
        ],
        "errorCode": "flow_high_risk_country"
      }
    ]
  }
}

Production notes

  • Decline rules are evaluated before routing. A matched rule rejects the transaction immediately.
  • Rules are evaluated in order; the first matching rule wins.
  • Conditions within a rule are AND-ed together.
  • errorCode is optional. When set it must match ^flow_[a-z_]+$.
PUT/api/v1/card-declineSetup

Replace the card-transaction decline rules.

Clerk JWT
Implementation details

Atomically replaces the full set of card-transaction decline rules. Supply the complete desired state; previous rules are discarded. A matched rule rejects the transaction before routing; the optional errorCode is returned to the integration. Each rule requires at least one condition.

Headers

FieldTypeRequiredDescription
authorizationBearer <dashboard-session>YesClerk dashboard session token. API keys cannot call workspace-level routes.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Request body

FieldTypeRequiredDescription
rulesarrayYesArray of decline rules. May be empty to disable all decline rules. Rules are evaluated in order.
rules[].conditionsarrayYesArray of conditions for this rule. All conditions must be satisfied (AND-ed) for the rule to match. Must contain at least one condition.
rules[].conditions[].typestringYesCondition type: "country", "cardScheme", "cardSource", "cardType", "cardCountry", "amount", or "metadata".
rules[].conditions[].opstringYesOperator. For set types (country/cardScheme/cardSource/cardType/cardCountry): "is_one_of" or "is_not_one_of". For amount: "gt", "lt", or "between". For metadata: "includes" or "excludes".
rules[].conditions[].valuesstring[]NoFor set conditions: array of allowed values. For country: ISO 3166-1 alpha-2 codes. For cardScheme: visa, mastercard, amex, discover, diners-club, jcb, maestro, unionpay, etc. For cardSource: raw, token, applepay, googlepay, network-token. For cardType: credit, debit, prepaid. For cardCountry: ISO 3166-1 alpha-2 codes representing the card issuer country (e.g. "US", "GB"). For metadata: string values to match against the metadata key.
rules[].conditions[].keystringNoMetadata key to match against. Required for metadata conditions.
rules[].conditions[].currencystringNoCurrency code for amount conditions (e.g., "USD"). Required for amount type.
rules[].conditions[].minnumberNoMinimum amount in major units for "gt" or "between" operators. Required for those operators.
rules[].conditions[].maxnumberNoMaximum amount in major units for "lt" or "between" operators. Required for those operators.
rules[].errorCodestringNoOptional error code returned to the integration when this rule fires. Must match ^flow_[a-z_]+$ (e.g. "flow_high_risk_country"). No free-text message field — errorCode only.

Responses

200Updated card-decline rules returned.

Response fields

FieldTypeRequiredDescription
data.rulesarrayYesThe persisted decline rules after the update.

Common errors

StatusCodeCauseFix
422decline_rule_no_conditionsA decline rule has no conditions.Each rule must include at least one condition.
422routing_invalid_countryA country condition value is not a valid ISO 3166-1 alpha-2 code.Use two-letter uppercase country codes, e.g. "US", "CA".
422routing_invalid_currencyAn amount condition currency is not a valid ISO-4217 code.Use three-letter uppercase currency codes, e.g. "USD", "EUR".
422routing_invalid_amountAn amount condition is missing a required field or a value is not a positive number.Provide the required numeric fields for the amount operator and ensure all values are positive.
422routing_amount_range_invalidAn amount between condition has min >= max.Ensure min is strictly less than max.
422routing_invalid_schemeA cardScheme condition value is not in the allowed card scheme vocabulary.Use one of the documented card scheme values (e.g. "visa", "mastercard", "amex").
422routing_invalid_card_sourceA cardSource condition value is not in the allowed card source vocabulary.Use one of: applepay, googlepay, network-token, raw, token.
422routing_invalid_card_typeA cardType condition value is not in the allowed card type vocabulary.Use one of: credit, debit, prepaid.
502gr4vy_upstream_errorThe Gr4vy flows API returned an unexpected error.Retry after a short delay. The decline rules were not partially applied.
Set card-decline rules
curl -X PUT https://api.usethrottle.dev/api/v1/card-decline \
  -H "authorization: Bearer <clerk-session-token>" \
  -H "x-application-id: <application-uuid>" \
  -H "x-throttle-environment-id: <environment-uuid>" \
  -H "content-type: application/json" \
  -d '{
    "rules": [
      {
        "conditions": [
          { "type": "country", "op": "is_one_of", "values": ["RU", "KP"] }
        ],
        "errorCode": "flow_high_risk_country"
      },
      {
        "conditions": [
          { "type": "cardType", "op": "is_one_of", "values": ["prepaid"] },
          { "type": "amount", "op": "gt", "currency": "USD", "min": 500 }
        ]
      }
    ]
  }'

Production notes

  • This is a full replacement, not a patch. Omitting a rule removes it.
  • Rules are evaluated in order before routing; the first matching rule declines the transaction.
  • Conditions within a rule are AND-ed together.
  • errorCode must match ^flow_[a-z_]+$ when provided. There is no free-text message field.
  • Send an empty rules array to remove all decline rules.
GET/api/v1/other-routingSetup

Get the non-card ("Other transactions") routing config.

Clerk JWT
Implementation details

Returns the current routing configuration for non-card payment methods (e.g. PayPal, iDEAL, SEPA). Rules are evaluated in order; the first rule whose method and conditions all match determines the connector cascade used. Unmatched non-card transactions fall through to the Gr4vy default (first active connection for the payment method and currency).

Headers

FieldTypeRequiredDescription
authorizationBearer <dashboard-session>YesClerk dashboard session token. API keys cannot call workspace-level routes.

Responses

200Current non-card routing config.

Response fields

FieldTypeRequiredDescription
data.rulesarrayYesOrdered list of non-card routing rules. Each rule is evaluated in order; the first rule whose method and conditions all match is applied.
data.rules[].methodstringYesPayment method this rule applies to (e.g. "paypal", "ideal", "sepa"). Only transactions of this method are tested against this rule's conditions.
data.rules[].conditionsarrayYesArray of conditions that must all be satisfied (AND-ed) for this rule to match. Allowed condition types: country, currency, amount, metadata. Card conditions (cardScheme, cardSource, cardType) are not permitted here.
data.rules[].conditions[].typestringYesCondition type: "country" (buyer country), "currency" (transaction currency), "amount" (transaction amount), or "metadata" (transaction metadata key/value matching). Card-specific condition types are not permitted for non-card routing rules.
data.rules[].conditions[].opstringYesOperator: for set conditions (country/currency): "is_one_of" or "is_not_one_of". For amount: "gt", "lt", or "between". For metadata: "includes" or "excludes".
data.rules[].conditions[].valuesstring[]NoArray of values for set conditions. For country: ISO 3166-1 alpha-2 codes. For currency: ISO 4217 codes (e.g. "USD", "EUR"). For metadata: string values to match against the metadata key.
data.rules[].conditions[].keystringNoMetadata key to match against. Required for metadata conditions.
data.rules[].conditions[].currencystringNoCurrency for amount conditions (e.g., "USD"). Required for amount conditions.
data.rules[].conditions[].minnumberNoMinimum amount in major units for "gt" or "between" operators.
data.rules[].conditions[].maxnumberNoMaximum amount in major units for "lt" or "between" operators.
data.rules[].connectionsstring[]YesOrdered list of connector IDs of the same method as the rule. First entry is attempted first; subsequent entries are automatic fail-over. All connectors must use the same payment method as rules[].method.

Common errors

StatusCodeCauseFix
403permission_deniedCaller does not have the application:settings permission.Use a Clerk session with admin or owner role on the target application.
502gr4vy_upstream_errorThe Gr4vy flows API returned an unexpected error.Retry after a short delay. Check Gr4vy status if the error persists.
Get non-card routing config
curl https://api.usethrottle.dev/api/v1/other-routing \
  -H "authorization: Bearer <clerk-session-token>" \
  -H "x-application-id: <application-uuid>" \
  -H "x-throttle-environment-id: <environment-uuid>"
Example response
{
  "data": {
    "rules": [
      {
        "method": "paypal",
        "conditions": [
          { "type": "country", "op": "is_one_of", "values": ["US", "CA"] }
        ],
        "connections": ["connector-id-paypal-primary", "connector-id-paypal-backup"]
      }
    ]
  }
}

Production notes

  • Rules are evaluated in order; the first rule whose method and conditions all match is applied.
  • Conditions within a rule are AND-ed together.
  • Card-specific condition types (cardScheme, cardSource, cardType) are not permitted. Use method to identify the payment method.
  • Unmatched non-card transactions use the Gr4vy default (first active connection for that method and currency). There is no pinned default cascade for this config.
  • Use GET /api/v1/routing-connectors to discover connector IDs and their associated payment methods.
PUT/api/v1/other-routingSetup

Replace the non-card ("Other transactions") routing config.

Clerk JWT
Implementation details

Atomically replaces the full routing configuration for non-card payment methods. Supply the complete desired state; previous rules are discarded. Each rule must declare a payment method and at least one connector of that method. Card conditions (cardScheme, cardSource, cardType) are not permitted — use the method field instead.

Headers

FieldTypeRequiredDescription
authorizationBearer <dashboard-session>YesClerk dashboard session token. API keys cannot call workspace-level routes.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Request body

FieldTypeRequiredDescription
rulesarrayYesArray of non-card routing rules. May be empty to disable custom non-card routing. Rules are evaluated in order.
rules[].methodstringYesPayment method this rule targets (e.g. "paypal", "ideal", "sepa"). Must be a non-card method. All connections in this rule must be of the same method.
rules[].conditionsarrayYesArray of conditions for this rule. All conditions must be satisfied (AND-ed) for the rule to match. May be empty (matches all transactions of the given method).
rules[].conditions[].typestringYesCondition type: "country", "currency", "amount", or "metadata". Card-specific types (cardScheme, cardSource, cardType) are not permitted.
rules[].conditions[].opstringYesOperator. For set types (country/currency): "is_one_of" or "is_not_one_of". For amount: "gt", "lt", or "between". For metadata: "includes" or "excludes".
rules[].conditions[].valuesstring[]NoFor set conditions: array of allowed values. For country: ISO 3166-1 alpha-2 codes. For currency: ISO 4217 codes (e.g. "USD", "EUR"). For metadata: string values to match against the metadata key.
rules[].conditions[].keystringNoMetadata key to match against. Required for metadata conditions.
rules[].conditions[].currencystringNoCurrency code for amount conditions (e.g., "USD"). Required for amount type.
rules[].conditions[].minnumberNoMinimum amount in major units for "gt" or "between" operators. Required for those operators.
rules[].conditions[].maxnumberNoMaximum amount in major units for "lt" or "between" operators. Required for those operators.
rules[].connectionsstring[]YesOrdered list of connector IDs for this rule. All connectors must use the same payment method as rules[].method. Must contain at least one entry.

Responses

200Updated non-card routing config returned.

Response fields

FieldTypeRequiredDescription
data.rulesarrayYesThe persisted non-card routing rules after the update.

Common errors

StatusCodeCauseFix
422other_routing_method_requiredA rule is missing the method field.Provide a non-card payment method string (e.g. "paypal", "ideal") for each rule.
422other_routing_empty_connectionsA rule has an empty connections array.Each rule must include at least one connector ID in connections.
422other_routing_method_mismatchA connection's payment method does not match the rule's method field.Ensure every connector ID in a rule's connections uses the same payment method as the rule's method field.
422other_routing_unknown_connectorA connector ID in connections does not exist or is not active for this application.List available connectors with GET /api/v1/routing-connectors and use only active connector IDs.
422routing_invalid_countryA country condition value is not a valid ISO 3166-1 alpha-2 code.Use two-letter uppercase country codes, e.g. "US", "CA".
422routing_invalid_currencyA currency condition or amount condition currency is not a valid ISO-4217 code.Use three-letter uppercase currency codes, e.g. "USD", "EUR".
422routing_invalid_amountAn amount condition is missing a required field or a value is not a positive number.Provide the required numeric fields for the amount operator and ensure all values are positive.
422routing_amount_range_invalidAn amount between condition has min >= max.Ensure min is strictly less than max.
502gr4vy_upstream_errorThe Gr4vy flows API returned an unexpected error.Retry after a short delay. The routing config was not partially applied.
Set non-card routing config
curl -X PUT https://api.usethrottle.dev/api/v1/other-routing \
  -H "authorization: Bearer <clerk-session-token>" \
  -H "x-application-id: <application-uuid>" \
  -H "x-throttle-environment-id: <environment-uuid>" \
  -H "content-type: application/json" \
  -d '{
    "rules": [
      {
        "method": "paypal",
        "conditions": [
          { "type": "country", "op": "is_one_of", "values": ["US", "CA"] }
        ],
        "connections": ["connector-id-paypal-primary", "connector-id-paypal-backup"]
      },
      {
        "method": "ideal",
        "conditions": [],
        "connections": ["connector-id-ideal-primary"]
      }
    ]
  }'

Production notes

  • This is a full replacement, not a patch. Omitting a rule removes it.
  • Rules are evaluated in order; the first rule whose method and conditions all match is applied.
  • Conditions within a rule are AND-ed together.
  • Card-specific condition types (cardScheme, cardSource, cardType) are not permitted. The method field identifies the payment method.
  • Unmatched non-card transactions use the Gr4vy default. There is no pinned default cascade.
  • Send an empty rules array to remove all custom non-card routing rules.
GET/api/v1/other-declineSetup

Get the non-card transaction decline rules.

Clerk JWT
Implementation details

Returns the current set of decline rules for non-card payment method transactions. Rules are evaluated in order before routing occurs; the first rule whose conditions all match rejects the transaction. Allowed condition types are paymentMethod, country, currency, amount, and metadata.

Headers

FieldTypeRequiredDescription
authorizationBearer <dashboard-session>YesClerk dashboard session token. API keys cannot call workspace-level routes.

Responses

200Current non-card decline rules.

Response fields

FieldTypeRequiredDescription
data.rulesarrayYesOrdered list of non-card decline rules. The first rule whose conditions all match causes the transaction to be declined.
data.rules[].conditionsarrayYesArray of conditions that must all be satisfied (AND-ed) for this rule to match. Allowed condition types: paymentMethod, country, currency, amount, metadata.
data.rules[].conditions[].typestringYesCondition type: "paymentMethod" (specific non-card method), "country" (buyer country), "currency" (transaction currency), "amount" (transaction amount), or "metadata" (transaction metadata key/value matching).
data.rules[].conditions[].opstringYesOperator: for paymentMethod/country/currency conditions: "is_one_of" or "is_not_one_of". For amount: "gt", "lt", or "between". For metadata: "includes" or "excludes".
data.rules[].conditions[].valuesstring[]NoArray of values for set conditions. For paymentMethod: non-card method names (e.g. "paypal", "ideal", "sepa"). For country: ISO 3166-1 alpha-2 codes. For currency: ISO 4217 codes. For metadata: string values to match against the metadata key.
data.rules[].conditions[].keystringNoMetadata key to match against. Required for metadata conditions.
data.rules[].conditions[].currencystringNoCurrency for amount conditions (e.g., "USD"). Required for amount conditions.
data.rules[].conditions[].minnumberNoMinimum amount in major units for "gt" or "between" operators.
data.rules[].conditions[].maxnumberNoMaximum amount in major units for "lt" or "between" operators.
data.rules[].errorCodestringNoOptional error code returned to the integration when this rule declines the transaction. Must match ^flow_[a-z_]+$. If omitted, a generic decline code is returned.

Common errors

StatusCodeCauseFix
403permission_deniedCaller does not have the application:settings permission.Use a Clerk session with admin or owner role on the target application.
502gr4vy_upstream_errorThe Gr4vy flows API returned an unexpected error.Retry after a short delay. Check Gr4vy status if the error persists.
Get non-card decline rules
curl https://api.usethrottle.dev/api/v1/other-decline \
  -H "authorization: Bearer <clerk-session-token>" \
  -H "x-application-id: <application-uuid>" \
  -H "x-throttle-environment-id: <environment-uuid>"
Example response
{
  "data": {
    "rules": [
      {
        "conditions": [
          { "type": "paymentMethod", "op": "is_one_of", "values": ["paypal"] },
          { "type": "country", "op": "is_one_of", "values": ["RU"] }
        ],
        "errorCode": "flow_high_risk_country"
      }
    ]
  }
}

Production notes

  • Decline rules are evaluated before routing. A matched rule rejects the transaction immediately.
  • Rules are evaluated in order; the first matching rule wins.
  • Conditions within a rule are AND-ed together.
  • The paymentMethod condition type uses "is_one_of" or "is_not_one_of" operators.
  • errorCode is optional. When set it must match ^flow_[a-z_]+$.
PUT/api/v1/other-declineSetup

Replace the non-card transaction decline rules.

Clerk JWT
Implementation details

Atomically replaces the full set of decline rules for non-card payment method transactions. Supply the complete desired state; previous rules are discarded. Each rule requires at least one condition. Allowed condition types are paymentMethod, country, currency, amount, and metadata.

Headers

FieldTypeRequiredDescription
authorizationBearer <dashboard-session>YesClerk dashboard session token. API keys cannot call workspace-level routes.
content-typeapplication/jsonYesRequired when the request includes a JSON body.

Request body

FieldTypeRequiredDescription
rulesarrayYesArray of non-card decline rules. May be empty to disable all non-card decline rules. Rules are evaluated in order.
rules[].conditionsarrayYesArray of conditions for this rule. All conditions must be satisfied (AND-ed) for the rule to match. Must contain at least one condition.
rules[].conditions[].typestringYesCondition type: "paymentMethod", "country", "currency", "amount", or "metadata".
rules[].conditions[].opstringYesOperator. For paymentMethod/country/currency: "is_one_of" or "is_not_one_of". For amount: "gt", "lt", or "between". For metadata: "includes" or "excludes".
rules[].conditions[].valuesstring[]NoFor set conditions: array of allowed values. For paymentMethod: non-card method names (e.g. "paypal", "ideal", "sepa"). For country: ISO 3166-1 alpha-2 codes. For currency: ISO 4217 codes. For metadata: string values to match against the metadata key.
rules[].conditions[].keystringNoMetadata key to match against. Required for metadata conditions.
rules[].conditions[].currencystringNoCurrency code for amount conditions (e.g., "USD"). Required for amount type.
rules[].conditions[].minnumberNoMinimum amount in major units for "gt" or "between" operators. Required for those operators.
rules[].conditions[].maxnumberNoMaximum amount in major units for "lt" or "between" operators. Required for those operators.
rules[].errorCodestringNoOptional error code returned to the integration when this rule fires. Must match ^flow_[a-z_]+$. No free-text message field — errorCode only.

Responses

200Updated non-card decline rules returned.

Response fields

FieldTypeRequiredDescription
data.rulesarrayYesThe persisted non-card decline rules after the update.

Common errors

StatusCodeCauseFix
422decline_rule_no_conditionsA decline rule has no conditions.Each rule must include at least one condition.
422routing_invalid_countryA country condition value is not a valid ISO 3166-1 alpha-2 code.Use two-letter uppercase country codes, e.g. "US", "CA".
422routing_invalid_currencyA currency condition or amount condition currency is not a valid ISO-4217 code.Use three-letter uppercase currency codes, e.g. "USD", "EUR".
422routing_invalid_amountAn amount condition is missing a required field or a value is not a positive number.Provide the required numeric fields for the amount operator and ensure all values are positive.
422routing_amount_range_invalidAn amount between condition has min >= max.Ensure min is strictly less than max.
502gr4vy_upstream_errorThe Gr4vy flows API returned an unexpected error.Retry after a short delay. The decline rules were not partially applied.
Set non-card decline rules
curl -X PUT https://api.usethrottle.dev/api/v1/other-decline \
  -H "authorization: Bearer <clerk-session-token>" \
  -H "x-application-id: <application-uuid>" \
  -H "x-throttle-environment-id: <environment-uuid>" \
  -H "content-type: application/json" \
  -d '{
    "rules": [
      {
        "conditions": [
          { "type": "paymentMethod", "op": "is_one_of", "values": ["paypal"] },
          { "type": "country", "op": "is_one_of", "values": ["RU", "KP"] }
        ],
        "errorCode": "flow_high_risk_country"
      }
    ]
  }'

Production notes

  • This is a full replacement, not a patch. Omitting a rule removes it.
  • Rules are evaluated in order before routing; the first matching rule declines the transaction.
  • Conditions within a rule are AND-ed together.
  • The paymentMethod condition type uses "is_one_of" or "is_not_one_of" to target specific non-card methods.
  • errorCode must match ^flow_[a-z_]+$ when provided. There is no free-text message field.
  • Send an empty rules array to remove all non-card decline rules.