agenta CLI call underneath.
Building in TypeScript or Node.js? Use
@agentaos/pay instead of raw HTTP. It wraps every endpoint on this page with typed methods, camelCases responses for you, retries on 5xx, and signs/verifies webhooks. This section documents the wire format the SDK talks to, useful if you’re integrating from another language or debugging a raw request.Base URL
POST /gateway/payment-links means POST https://api.agentaos.ai/api/v1/gateway/payment-links.
Authentication
Send your secret key in thex-api-key header on every request.
string
required
Your secret key. In the dashboard, open Developers → API keys in the sidebar and click Generate Test Key (in test mode) or Generate Live Key (in live mode).
401 Unauthorized, with the message Missing or invalid authentication. Server-to-server calls always send the key in x-api-key; API keys have no bearer-token form. A key stops working when the person who created it is no longer an owner or admin of the business. The server then returns 401 with the code key_no_longer_valid:
401
Authorization: Bearer: the agenta CLI signs in through your browser and sends a session token as Authorization: Bearer <token>, not an API key. A request made with a session token runs in test mode unless it sends the header X-Environment: live. Use an API key for your own servers and scripts.
Acting for a business
A platform can call any endpoint as a business it manages. Send the business’s id in theAgentaOS-Account header, and the request runs as that business: the checkout, product or invoice is the business’s, not yours.
string
The id of a business you manage. Leave it out, or send your own id, to act as yourself.
403:
403
400 with the message AgentaOS-Account must name a business.
The SDK sends this header for you with { business } and the CLI with --business <id>. See Acting for a business.
Test and live keys
The key’s prefix sets the mode of the request. There is no mode parameter.
Test data and live data are separate. A test key reads and writes only records created with a test key, and a live key only records created with a live key. A record from the other mode returns
404, as if it did not exist. See Test mode and testing.
Request format
Send request bodies as JSON withContent-Type: application/json. Body fields are camelCase, for example successUrl, billingInterval and trialPeriodDays. The server rejects a field that the endpoint does not define with a 400, so check the spelling of every field. A body larger than 512 KB is rejected.
Pagination
The list endpointsGET /gateway/payment-links, /sessions, /subscriptions, /customers, /invoices and /all-transactions page with limit and offset and return the same envelope. There is no cursor.
number
default:"20"
Items per page. The server caps it at 100 on payment links, checkouts, subscriptions and customers, and at 1000 on invoices and transactions. A larger value returns the capped number of items without an error.
number
default:"0"
The number of items to skip. For the next page, add the number of items you received to the current offset.
Pagination envelope
array
The page of results. The shape depends on the resource.
number
The number of matching items across all pages.
boolean
true when offset plus the number of items on this page is less than total.GET /gateway/businesses is not paged. It returns a plain array.
Naming convention
Most response fields aresnake_case. A few computed fields are camelCase, and two resources are camelCase throughout. Responses have three kinds of fields:
Stored fields → snake_case
Stored fields → snake_case
A field stored on the record comes back in snake_case:
created_at, amount_override, billing_interval, buyer_email, tax_rate_id, and so on. This is the majority of fields on Payment Links, Checkouts, and Invoices.Computed convenience fields → camelCase, added on top
Computed convenience fields → camelCase, added on top
The server computes these fields when it builds the response. They are camelCase and have no snake_case form:
checkoutUrlon Checkouts and Payment Linksmoney(an object:currency,grossMinor,feeMinor,vatMinor,netMinor) on Transactionsearnings(an object:currency,grossMinor,agentaosFeeMinor,vatMinor,netMinor) on a single retrieved Invoice, same shape asmoneyexcept the fee field is namedagentaosFeeMinorinstead offeeMinor
Fully camelCase resources
Fully camelCase resources
Two resources have no snake_case fields: Subscriptions (
GET /gateway/subscriptions, POST /gateway/subscriptions/:id/cancel) and Customers (GET /gateway/customers). Every field on these two is camelCase.Money model
AgentaOS writes money in three forms.Decimal currency units (number)
Decimal currency units (number)
An amount you send is a decimal number in currency units:
49.99 means €49.99, never cents. The same holds for a plainly named amount in a response: a Payment Link’s amount, a Checkout’s amount_override, and an Invoice’s amount, fiat_amount and tax_amount.Integer minor units (number)
Integer minor units (number)
A field whose name ends in
Minor is an integer count of the smallest currency unit: 1999 means €19.99. Examples are unitAmountMinor on a Subscription, dueTodayMinor on a plan-change quote, amountMinor on a credit, and the fields of the money breakdown on a Transaction and the earnings breakdown on a retrieved Invoice.On webhooks
On webhooks
In a webhook event’s
data, amount is a string in currency units, e.g. "49.99", so the value keeps its trailing zeros. amount_minor on subscription and dispute events is an integer in minor units, like the Minor fields above. The SDK’s webhooks.verify() returns it as amountMinor.Errors
An error response is JSON. Every response, success or error, has anx-request-id header, and an error body repeats it as requestId. Include it when you contact support.
400
number
The HTTP status code.
string | string[]
Human-readable text. A validation failure returns an array, one entry per problem.
string
ISO 8601 time of the error.
string
The same value as the
x-request-id header.string
A short category, such as
Bad Request. Most errors have it; some, such as a 429, do not.array
On a validation
400 only: one { field, message } per invalid field.string
On some errors only: a stable, machine-readable code, such as
key_no_longer_valid or account_on_hold. Branch on code when it is present, and on statusCode when it is not. Never branch on message, which can change.Rate limits
The server counts requests per client IP address and per endpoint. The default limit is 60 requests per 60 seconds on each endpoint. These endpoints have a lower limit of 10 requests per 60 seconds:POST /gateway/businessesPOST /gateway/businesses/:id/invitationPOST /gateway/businesses/:id/verification-link
X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (seconds until the count resets). Over the limit, the server returns 429 with a Retry-After header, in seconds:
429
Retry-After, then send the request again. The SDK does this for you when Retry-After is 60 seconds or less.
The count is per IP address and endpoint, so all the checkouts your server creates share one budget: 60 POST /gateway/sessions calls per minute, across all your buyers. Create a checkout when a buyer asks to pay, not on every page view.
Idempotency
Two endpoints read theIdempotency-Key header:
No other endpoint reads the header. If a create request times out and you send it again, for example
POST /gateway/payment-links, the server can create the record twice. Before you retry such a request, list the resource and check whether the first request succeeded.
The SDK sends a new random Idempotency-Key on every POST call, and uses the same key when it retries that call after a 429, a 5xx or a network error. You cannot choose the key: RequestOptions has no idempotencyKey. The one exception is subscriptions.credit(), which requires you to pass idempotencyKey. On the two endpoints above, a retry is safe. On other endpoints, the retry can create a duplicate.
The server does not answer a repeated key with 409: it returns the first result. A 409 Conflict means the request conflicts with the record’s current state, for example a checkout changed by another request, or a product at its purchase limit. The SDK throws every 409 as IdempotencyError, whatever the cause, so read its message.
Versioning
The API version is in the path: every endpoint is under/api/v1. The SDK (@agentaos/pay) and the CLI (agentaos) are published on npm with semantic version numbers. Pin the version you tested with, and read the changelog before you upgrade.
Next steps
Payment Links
Create, list, update, and cancel reusable payment links.
Checkouts
Create a one-time checkout session, standalone or from a link.
Webhooks
Events, payload shapes, and signature verification.
TypeScript SDK
Skip the wire format entirely and use typed methods.