AgentaOS Subscriptions API
Merchant-side read and management surface for recurring plans. Created automatically when a buyer pays a `type: subscription` payment link.
Merchant-side read and management surface for recurring plans. Created automatically when a buyer pays a `type: subscription` payment link.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/agentaos-ai:agentaos-ai-subscriptions-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Agentaos Ai Subscriptions API
version: 1.0.0
contact:
name: AgentaOS
url: https://agentaos.ai
license:
name: Proprietary
url: https://agentaos.ai
description: 'Operations tagged Subscriptions across 2 of this provider''s published API definitions: agentaos-ai-openapi.json, openapi.json. Each path carries the servers of the definition it was published in.'
servers:
- url: https://api.agentaos.ai/api/v1
description: Production
security:
- ApiKeyAuth: []
tags:
- name: Subscriptions
description: 'Merchant-side read and management surface for recurring plans. Created automatically when a buyer pays a `type: subscription` payment link.'
paths:
/gateway/subscriptions:
get:
tags:
- Subscriptions
operationId: listSubscriptions
summary: List subscriptions
description: 'Paginated. A subscription is created automatically when a buyer pays a payment link with `type: "subscription"` at checkout: there is no `POST` create endpoint by design. Every field on this resource is camelCase on the wire.'
parameters:
- $ref: '#/components/parameters/Limit100'
- $ref: '#/components/parameters/Offset'
responses:
'200':
description: A page of subscriptions.
content:
application/json:
schema:
$ref: '#/components/schemas/SubscriptionListResponse'
'401':
$ref: '#/components/responses/Unauthorized'
servers:
- url: https://api.agentaos.ai/api/v1
description: Production
/gateway/subscriptions/{id}/cancel:
post:
tags:
- Subscriptions
operationId: cancelSubscription
summary: Cancel a subscription
description: 'Cancels at the end of the current paid period: the subscriber keeps what they already paid for, no refund. There is no immediate cancellation; `atPeriodEnd: false` returns `400`. Calling cancel again on an already-`canceled` subscription is a no-op. Returns `400` if the subscription never completed a first successful charge (`stripeSubscriptionId` is `null`).'
parameters:
- $ref: '#/components/parameters/SubscriptionId'
requestBody:
required: false
content:
application/json:
schema:
$ref: '#/components/schemas/CancelSubscriptionRequest'
example:
atPeriodEnd: true
responses:
'200':
description: The subscription's updated cancellation state.
content:
application/json:
schema:
$ref: '#/components/schemas/CancelSubscriptionResponse'
example:
status: active
currentPeriodEnd: '2026-09-06T12:00:00.000Z'
cancelAtPeriodEnd: true
effectiveCancelDate: '2026-09-06T12:00:00.000Z'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
servers:
- url: https://api.agentaos.ai/api/v1
description: Production
/gateway/subscriptions/{id}/plan-change/preview:
get:
tags:
- Subscriptions
operationId: previewSubscriptionPlanChange
summary: Preview a plan change
description: 'Quote moving a subscription to another plan. Read-only: nothing is charged or scheduled. The target must be a different subscription product in the same currency and billing interval, and the subscription must be `active` or `trialing`. An upgrade (higher price) is charged now, prorated; a downgrade switches at the current period end with nothing due today. Pass the returned `prorationDate` to the apply call so the charge matches this quote.'
parameters:
- name: id
in: path
required: true
description: Subscription id.
schema:
type: string
format: uuid
- name: targetLinkId
in: query
required: true
description: The target product's payment-link id.
schema:
type: string
format: uuid
responses:
'200':
description: The quote. Money fields are integer minor units.
content:
application/json:
schema:
$ref: '#/components/schemas/PlanChangePreview'
example:
direction: upgrade
currency: eur
dueTodayMinor: 1234
dueTodayVatMinor: 239
effectiveAt: '2026-09-03T10:31:25.000Z'
nextInvoiceMinor: 4900
nextInvoiceVatMinor: 1176
nextInvoiceAt: '2026-10-03T10:45:13.000Z'
prorationDate: 1788434542
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
servers:
- url: https://api.agentaos.ai/api/v1
description: Production
/gateway/subscriptions/{id}/plan-change:
post:
tags:
- Subscriptions
operationId: changeSubscriptionPlan
summary: Change the plan
description: Apply a plan change quoted by the preview. Echo the preview's `prorationDate` so the amount charged matches the quote. An upgrade charges the prorated difference on the saved card now and the response carries the new per-cycle amount; a downgrade is scheduled for the current period end (`effectiveAt`) and charges nothing today. Idempotent on (subscription, target plan, prorationDate). Same plan, a non-active subscription, a different currency, or a different billing interval return `400`.
parameters:
- name: id
in: path
required: true
description: Subscription id.
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PlanChangeRequest'
example:
targetLinkId: c9e44cf2-b3c3-465c-8ab8-de0706be4974
prorationDate: 1788434542
responses:
'200':
description: The applied change. Shape depends on `direction`.
content:
application/json:
schema:
$ref: '#/components/schemas/PlanChangeResponse'
examples:
upgrade:
value:
direction: upgrade
applied: true
status: active
unitAmountMinor: 4900
currency: eur
downgrade:
value:
direction: downgrade
applied: true
effectiveAt: '2026-10-03T10:45:13.000Z'
unitAmountMinor: 2900
currency: eur
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
servers:
- url: https://api.agentaos.ai/api/v1
description: Production
/gateway/subscriptions/{id}/credits:
post:
tags:
- Subscriptions
operationId: grantSubscriptionCredit
summary: Give a subscriber credit
description: 'Puts credit on the subscriber''s account with you. It comes off their next invoice, reducing what their card is charged; no money moves out, and no receipt already issued changes. The credit belongs to the CUSTOMER, so if the same buyer has two subscriptions with you in the same currency it goes to whichever invoice falls due first. The amount is positive integer minor units and may cover the whole of the next invoice — at most its amount due. A credit that covers it in full charges the card nothing, and that month is still recorded as a sale of zero with an invoice and a receipt saying the credit covered it. More than the amount due is refused, and the error names the largest amount you can give. The currency is the subscription''s; there is no currency field. Only an owner or admin may do this, from a signed-in session: an API key cannot, because the credit must name the person who gave it.'
security:
- SessionAuth: []
parameters:
- $ref: '#/components/parameters/SubscriptionId'
- name: Idempotency-Key
in: header
required: true
description: Required, not optional. Mint one string per credit you mean to give, and send the same one again if the call times out and you retry. Nothing on our side survives a retry to recognise it by, so a retry without a key credits the subscriber a second time. Two different keys for the same amount give two credits, which is how you deliberately credit someone twice.
schema:
type: string
maxLength: 200
example: credit-2026-09-14-downtime-acme
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/GrantCreditRequest'
example:
amountMinor: 500
reason: Two days of downtime in August
responses:
'201':
description: The credit was given.
content:
application/json:
schema:
$ref: '#/components/schemas/SubscriptionCredit'
example:
id: cbtxn_1NXyZ2eZvKYlo2C0
amountMinor: 500
currency: eur
reason: Two days of downtime in August
creditBalanceMinor: 500
nextInvoiceMinor: 1900
nextInvoiceDueAfterCreditMinor: 1400
nextInvoiceAt: '2026-10-01T00:00:00.000Z'
createdBy: 3f1c2d4e-5a6b-4c7d-8e9f-0a1b2c3d4e5f
createdAt: '2026-09-14T10:00:00.000Z'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
get:
tags:
- Subscriptions
operationId: getSubscriptionCredits
summary: List credits given to a subscriber
description: 'Every credit given for this subscription, newest first, and what is left unspent. `balanceMinor` is the customer''s whole unspent credit with you, which may include credit given for another of their subscriptions. `createdBy` is the id of the person who gave it. `currency` is the subscription''s, and every minor-unit figure on the page is counted in it. Owner or admin, signed-in session only: an API key is refused here, same as on the grant.'
security:
- SessionAuth: []
parameters:
- $ref: '#/components/parameters/SubscriptionId'
responses:
'200':
description: The credits given for this subscription.
content:
application/json:
schema:
$ref: '#/components/schemas/SubscriptionCreditListResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
servers:
- url: https://api.agentaos.ai/api/v1
description: Production
/gateway/subscriptions/{id}/invoices:
get:
tags:
- Subscriptions
operationId: getSubscriptionInvoices
summary: List a subscription's billing history
description: 'Every invoice minted at a renewal cycle for this subscription, newest first. Bounded (latest 100); not paginated. `amount`/`currency` is one already-resolved figure per invoice: the linked capture''s settlement earnings when one is available in the invoice''s own fiat currency, falling back to the merchant''s fiat amount, then to the settlement-token amount. Every field on this resource is camelCase on the wire.'
parameters:
- $ref: '#/components/parameters/SubscriptionId'
responses:
'200':
description: The subscription's billing history.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/SubscriptionInvoice'
example:
- id: 8f3e2b3a-1c2d-4e5f-9a0b-1c2d3e4f5a6b
invoiceNumber: INV-2026-0042
status: paid
issuedAt: '2026-08-13T13:08:48.000Z'
amount: 19.99
currency: EUR
disputed: false
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
servers:
- url: https://api.agentaos.ai/api/v1
description: Production
/gateway/subscriptions/{id}/resume:
post:
tags:
- Subscriptions
operationId: resumeSubscription
summary: Resume a subscription scheduled to cancel
description: Undoes a scheduled cancel-at-period-end before the current period elapses. Only valid on a live subscription that is currently scheduled to cancel; returns `400` if it was never scheduled to cancel or has already gone terminal.
parameters:
- $ref: '#/components/parameters/SubscriptionId'
responses:
'200':
description: The subscription's updated (resumed) state.
content:
application/json:
schema:
$ref: '#/components/schemas/ResumeSubscriptionResponse'
example:
status: active
currentPeriodEnd: '2026-09-06T12:00:00.000Z'
cancelAtPeriodEnd: false
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
servers:
- url: https://api.agentaos.ai/api/v1
description: Production
components:
parameters:
SubscriptionId:
name: id
in: path
required: true
description: Subscription UUID (the `id` field from the list response, not `stripeSubscriptionId`).
schema:
type: string
format: uuid
Offset:
name: offset
in: query
required: false
description: Number of items to skip, for the next page.
schema:
type: integer
default: 0
minimum: 0
Limit100:
name: limit
in: query
required: false
description: Items per page. Capped server-side at 100.
schema:
type: integer
default: 20
minimum: 1
maximum: 100
schemas:
SubscriptionCredit:
type: object
description: A credit you gave, with both figures it changes. Money is integer minor units.
properties:
id:
type: string
description: The credit's id at the payment processor. There is no id of ours.
amountMinor:
type: integer
description: What you gave, positive.
currency:
type: string
description: The subscription's, lower-case.
reason:
type: string
creditBalanceMinor:
type: integer
description: All unspent credit on this customer's account with you.
nextInvoiceMinor:
type: integer
description: What their next invoice would have taken before this credit.
nextInvoiceDueAfterCreditMinor:
type: integer
description: What it will take now.
nextInvoiceAt:
type: string
format: date-time
createdBy:
type: string
format: uuid
description: The person who gave it.
createdAt:
type: string
format: date-time
required:
- id
- amountMinor
- currency
- reason
- creditBalanceMinor
- nextInvoiceMinor
- nextInvoiceDueAfterCreditMinor
- nextInvoiceAt
- createdBy
- createdAt
PlanChangeResponse:
oneOf:
- type: object
title: Upgrade applied
properties:
direction:
type: string
enum:
- upgrade
applied:
type: boolean
enum:
- true
status:
type: string
description: Subscription status after the change.
unitAmountMinor:
type: integer
description: New per-cycle amount.
currency:
type: string
required:
- direction
- applied
- status
- unitAmountMinor
- currency
- type: object
title: Downgrade scheduled
properties:
direction:
type: string
enum:
- downgrade
applied:
type: boolean
enum:
- true
effectiveAt:
type: string
format: date-time
description: 'When the new plan starts: the current period end. Until then the subscription keeps its current plan and reports the change as `pendingPlanChange`.'
unitAmountMinor:
type: integer
description: Per-cycle amount from `effectiveAt` on.
currency:
type: string
required:
- direction
- applied
- effectiveAt
- unitAmountMinor
- currency
- type: object
title: Pending downgrade reverted
properties:
direction:
type: string
enum:
- revert
applied:
type: boolean
enum:
- true
unitAmountMinor:
type: integer
description: The current plan's per-cycle amount, unchanged.
currency:
type: string
required:
- direction
- applied
- unitAmountMinor
- currency
ResumeSubscriptionResponse:
type: object
properties:
status:
type: string
enum:
- incomplete
- incomplete_expired
- trialing
- active
- past_due
- canceled
- unpaid
- paused
currentPeriodEnd:
type:
- string
- 'null'
format: date-time
cancelAtPeriodEnd:
type: boolean
required:
- status
- currentPeriodEnd
- cancelAtPeriodEnd
CancelSubscriptionRequest:
type: object
properties:
atPeriodEnd:
type: boolean
default: true
description: 'Only `true` is accepted, and it is the default: the cancellation is scheduled for the end of the current period. `false` returns `400`; there is no immediate cancellation.'
PlanChangeRequest:
type: object
properties:
targetLinkId:
type: string
format: uuid
description: The target product's payment-link id.
prorationDate:
type: integer
minimum: 1
description: From the preview response.
required:
- targetLinkId
- prorationDate
Subscription:
type: object
description: Fully camelCase on the wire.
properties:
id:
type: string
format: uuid
description: Use this as the :id path parameter to cancel.
customerEmail:
type:
- string
- 'null'
customerName:
type:
- string
- 'null'
planName:
type:
- string
- 'null'
description: The payment link's name, falling back to its description.
billingInterval:
type:
- string
- 'null'
enum:
- month
- year
- null
status:
type: string
enum:
- incomplete
- incomplete_expired
- trialing
- active
- past_due
- canceled
- unpaid
- paused
description: Mirrored directly from the card processor.
unitAmountMinor:
type: integer
description: Per-cycle price, integer minor units (1999 = EUR 19.99).
currency:
type: string
currentPeriodEnd:
type:
- string
- 'null'
format: date-time
description: null before the first cycle books.
stripeSubscriptionId:
type:
- string
- 'null'
pendingPlanChange:
description: Null unless a downgrade is scheduled; then the plan, quoted amount and date the subscription switches to. `planName`, `unitAmountMinor` and `linkId` stay what the buyer paid for until `effectiveAt`.
oneOf:
- type: 'null'
- type: object
properties:
linkId:
type: string
format: uuid
planName:
type:
- string
- 'null'
unitAmountMinor:
type: integer
description: Per-cycle amount from `effectiveAt` on, integer minor units.
effectiveAt:
type: string
format: date-time
required:
- linkId
- planName
- unitAmountMinor
- effectiveAt
required:
- id
- customerEmail
- customerName
- planName
- billingInterval
- status
- unitAmountMinor
- currency
- currentPeriodEnd
- stripeSubscriptionId
- pendingPlanChange
Error:
type: object
description: Every non-2xx response is JSON in this shape. Every response (success or error) also carries an `x-request-id` response header; send that header on your request to have your own id echoed back, otherwise the server mints one. On errors the same id is repeated in the `requestId` body field.
properties:
statusCode:
type: integer
description: Same as the HTTP status code.
code:
type: string
description: 'Present on some refusals: a stable machine-readable reason, e.g. `live_key_required`.'
message:
description: Human-readable. A validation failure (400) returns an array of per-field messages instead of one string.
anyOf:
- type: string
- type: array
items:
type: string
errors:
type: array
description: 'Present on 400 validation failures: one entry per invalid field. The flat human-readable strings stay in `message` for back-compat; this is the machine-readable, per-field view.'
items:
type: object
properties:
field:
type: string
description: Name of the invalid field, dot-notated for nested properties (e.g. `checkoutFields.0.type`).
message:
type: string
description: Validation messages for that field, joined with `, `.
required:
- field
- message
requestId:
type: string
description: Correlation id, identical to the `x-request-id` response header. Include it when contacting support. On success it is available on the header only, not the body.
timestamp:
type: string
format: date-time
required:
- statusCode
- message
- timestamp
CancelSubscriptionResponse:
type: object
properties:
status:
type: string
enum:
- incomplete
- incomplete_expired
- trialing
- active
- past_due
- canceled
- unpaid
- paused
currentPeriodEnd:
type:
- string
- 'null'
format: date-time
cancelAtPeriodEnd:
type: boolean
effectiveCancelDate:
type:
- string
- 'null'
format: date-time
required:
- status
- currentPeriodEnd
- cancelAtPeriodEnd
- effectiveCancelDate
SubscriptionCreditListResponse:
type: object
properties:
items:
type: array
items:
type: object
properties:
id:
type: string
amountMinor:
type: integer
reason:
type: string
createdBy:
type:
- string
- 'null'
format: uuid
description: The id of the person who gave it. Null when the credit was not given through AgentaOS but directly at the card processor, so there is nobody of ours to name.
createdAt:
type: string
format: date-time
required:
- id
- amountMinor
- reason
- createdBy
- createdAt
balanceMinor:
type: integer
description: Unspent credit on the CUSTOMER, which may span their subscriptions with you.
currency:
type: string
description: What every minor-unit figure on this page is counted in — the subscription's own currency, lower-case ISO 4217. Print it; don't assume one.
required:
- items
- balanceMinor
- currency
GrantCreditRequest:
type: object
properties:
amountMinor:
type: integer
minimum: 1
description: 'Positive integer minor units of the subscription''s currency, at most the next invoice''s amount due. There is no currency field: a credit in the wrong currency is accepted by the processor and then never reaches an invoice.'
reason:
type: string
maxLength: 200
description: Why you gave it. Shown back to you and on the credit at the processor.
required:
- amountMinor
- reason
SubscriptionListResponse:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/Subscription'
total:
type: integer
hasMore:
type: boolean
required:
- items
- total
- hasMore
SubscriptionInvoice:
type: object
description: One cycle's invoice on a subscription's billing history. Fully camelCase on the wire.
properties:
id:
type: string
format: uuid
invoiceNumber:
type: string
status:
type: string
enum:
- issued
- paid
- voided
issuedAt:
type: string
format: date-time
amount:
type: number
description: 'The settled amount for this cycle: the linked capture''s settlement earnings (net + fee + vat) when one is available in the invoice''s own fiat currency, else the merchant''s fiat_amount, else the settlement-token amount. Already resolved server-side — never recompute this.'
currency:
type: string
disputed:
type: boolean
description: Derived from the linked capture's dispute state, never persisted — reverts to false the instant a won dispute restores the capture. Only ever true when status is 'paid'.
required:
- id
- invoiceNumber
- status
- issuedAt
- amount
- currency
- disputed
PlanChangePreview:
type: object
description: Read-only quote for moving a subscription to another plan. Money is integer minor units.
properties:
direction:
type: string
enum:
- upgrade
- downgrade
- revert
description: '`upgrade` when the new plan costs more per cycle; `downgrade` otherwise; `revert` when the target is the current plan while a downgrade is pending (cancels it, nothing due).'
currency:
type: string
dueTodayMinor:
type: integer
description: Charged now. Always 0 for a downgrade.
dueTodayVatMinor:
type: integer
effectiveAt:
type: string
format: date-time
description: 'Upgrade: now. Downgrade: the current period end.'
nextInvoiceMinor:
type: integer
description: The next regular cycle invoice on the new plan.
nextInvoiceVatMinor:
type: integer
nextInvoiceAt:
type: string
format: date-time
prorationDate:
type: integer
description: Unix seconds. Echo it in the apply request so the charge matches this quote.
required:
- direction
- currency
- dueTodayMinor
- dueTodayVatMinor
- effectiveAt
- nextInvoiceMinor
- nextInvoiceVatMinor
- nextInvoiceAt
- prorationDate
responses:
NotFound:
description: Resource not found (or not visible to your key; the two are not distinguished).
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
statusCode: 404
message: Payment link not found
timestamp: '2026-08-06T12:00:00.000Z'
Forbidden:
description: The key is valid but the resource belongs to a different organization.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
statusCode: 403
message: Payment link belongs to another organization
timestamp: '2026-08-06T12:00:00.000Z'
BadRequest:
description: A required field is missing, out of range, or the wrong type. `ValidationPipe` also rejects any field not in the documented schema.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
statusCode: 400
message: amount is required when creating a session without a link
timestamp: '2026-08-06T12:00:00.000Z'
Unauthorized:
description: Missing or invalid `x-api-key`.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
statusCode: 401
message: Invalid API key
timestamp: '2026-08-06T12:00:00.000Z'
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: x-api-key
description: 'Your secret key, from app.agentaos.ai -> Settings -> Developers -> API Keys. The key''s prefix is both its identity and its environment: `sk_test_...` (sandbox, free, no verification) or `sk_live_...` (real money, requires business verification). A missing or invalid key returns 401.'
x-refined-from:
- agentaos-ai-openapi.json
- openapi.json