Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
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.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/asap-cool:asap-cool-billing-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
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: ASAP Platform Billing API
description: 'Public HTTP API for ASAP Platform (api.asap.cool).
All `/v1` responses are wrapped in a standard envelope. Success responses are `{ "data": , "meta": { "request_id", "next_cursor"?, "has_more"? } }` — the schema documented for each operation describes the inner `data` value. Errors are `{ "error": { "code", "message", "field"?, "request_id" } }`. Every response also carries an `X-Request-Id` header matching `meta.request_id` / `error.request_id`.'
license:
name: BUSL-1.1
version: 0.0.0
servers:
- url: https://api.asap.cool
description: Production
tags:
- name: Billing
description: Stripe checkout, subscription state, customer portal, and webhook receiver.
paths:
/v1/billing/checkout-session:
post:
tags:
- Billing
summary: POST /v1/billing/checkout-session
operationId: create_checkout_session
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CheckoutSessionRequest'
required: true
responses:
'200':
description: Stripe Checkout URL.
content:
application/json:
schema:
$ref: '#/components/schemas/RedirectResponse'
'401':
description: Caller is not authenticated.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
'422':
description: '`success_url` or `cancel_url` is not on the application origin (`invalid_redirect_url`).'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
'503':
description: Stripe is not configured, or no Stripe price resolved for the requested plan/interval.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
/v1/billing/invoices:
get:
tags:
- Billing
summary: GET /v1/billing/invoices
operationId: list_invoices
responses:
'200':
description: Invoices for the active org, most recent first.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/InvoiceView'
'401':
description: Caller is not authenticated.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
'403':
description: API key lacks the billing:read scope.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
/v1/billing/payment-methods:
get:
tags:
- Billing
summary: GET /v1/billing/payment-methods
operationId: list_payment_methods
responses:
'200':
description: Card payment methods attached to the org's Stripe customer.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/PaymentMethodView'
'401':
description: Caller is not authenticated.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
/v1/billing/payment-methods/default:
post:
tags:
- Billing
summary: POST /v1/billing/payment-methods/default
operationId: set_default_payment_method
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SetDefaultPaymentMethodRequest'
required: true
responses:
'204':
description: Default payment method updated.
'401':
description: Caller is not authenticated.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
'404':
description: No billing customer for the org.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
/v1/billing/payment-methods/{id}:
delete:
tags:
- Billing
summary: DELETE /v1/billing/payment-methods/{id}
operationId: detach_payment_method
parameters:
- name: id
in: path
description: Stripe payment method id (pm_…).
required: true
schema:
type: string
responses:
'204':
description: Payment method detached.
'401':
description: Caller is not authenticated.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
'409':
description: Method is still set as default for an active subscription.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
/v1/billing/portal-session:
post:
tags:
- Billing
summary: POST /v1/billing/portal-session
operationId: create_portal_session
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PortalSessionRequest'
required: true
responses:
'200':
description: Stripe Customer Portal URL.
content:
application/json:
schema:
$ref: '#/components/schemas/RedirectResponse'
'401':
description: Caller is not authenticated.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
'404':
description: No Stripe customer for the active org.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
'422':
description: '`return_url` is not on the application origin (`invalid_redirect_url`).'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
'503':
description: Stripe is not configured.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
/v1/billing/setup-intent:
post:
tags:
- Billing
summary: POST /v1/billing/setup-intent
operationId: create_setup_intent
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SetupIntentRequest'
required: true
responses:
'200':
description: Stripe SetupIntent client secret.
content:
application/json:
schema:
$ref: '#/components/schemas/SetupIntentResponse'
'401':
description: Caller is not authenticated.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
/v1/billing/subscription:
get:
tags:
- Billing
summary: GET /v1/billing/subscription
operationId: get_subscription
responses:
'200':
description: 'Subscription view, with `plan: starter` when no row exists.'
content:
application/json:
schema:
$ref: '#/components/schemas/SubscriptionView'
'401':
description: Caller is not authenticated.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
'403':
description: API key lacks the billing:read scope.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
post:
tags:
- Billing
summary: POST /v1/billing/subscription
operationId: create_subscription
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CreateSubscriptionRequest'
required: true
responses:
'200':
description: Created subscription.
content:
application/json:
schema:
$ref: '#/components/schemas/CreateSubscriptionResponse'
'401':
description: Caller is not authenticated.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
'409':
description: Org already has an active subscription.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
'422':
description: Promotion code is unknown or inactive.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
'503':
description: No Stripe price resolved for the requested plan/interval.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
patch:
tags:
- Billing
summary: PATCH /v1/billing/subscription
operationId: change_subscription_plan
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ChangePlanRequest'
required: true
responses:
'200':
description: Plan changed with proration applied.
content:
application/json:
schema:
$ref: '#/components/schemas/ChangePlanResponse'
'401':
description: Caller is not authenticated.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
'404':
description: No subscription to update.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
'503':
description: No Stripe price resolved for the requested plan/interval.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
/v1/billing/subscription/cancel:
post:
tags:
- Billing
summary: POST /v1/billing/subscription/cancel
operationId: cancel_subscription
responses:
'200':
description: Cancellation scheduled at period end.
content:
application/json:
schema:
$ref: '#/components/schemas/CancelResponse'
'401':
description: Caller is not authenticated.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
'404':
description: No subscription to cancel.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
/v1/billing/subscription/preview:
get:
tags:
- Billing
summary: GET /v1/billing/subscription/preview
operationId: preview_subscription_change
parameters:
- name: plan
in: query
description: Target plan slug (solo|studio; the retired pro|business are still accepted).
required: true
schema:
type: string
responses:
'200':
description: Proration preview for the requested plan swap.
content:
application/json:
schema:
$ref: '#/components/schemas/PreviewResponse'
'401':
description: Caller is not authenticated.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
'404':
description: No subscription to preview against.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
'503':
description: No Stripe price resolved for the requested plan/interval.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
/v1/billing/subscription/reactivate:
post:
tags:
- Billing
summary: POST /v1/billing/subscription/reactivate
operationId: reactivate_subscription
responses:
'200':
description: Pending cancellation removed.
content:
application/json:
schema:
$ref: '#/components/schemas/ChangePlanResponse'
'401':
description: Caller is not authenticated.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
'404':
description: No subscription to reactivate.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
/v1/pricing:
get:
tags:
- Billing
summary: GET /v1/pricing
operationId: get_pricing
responses:
'200':
description: 'The plan grid: prices from Stripe, ceilings and features from the plan tables.'
content:
application/json:
schema:
$ref: '#/components/schemas/PricingView'
/v1/stripe/connect/webhook:
post:
tags:
- Billing
summary: '`POST /v1/stripe/connect/webhook`'
description: 'Returns `200` on success, duplicate replay and every deliberate skip
(unknown account, foreign document, non-payment mode); `400` on signature
failure; `503` when Stripe is not configured; `500` (with the idempotency
key rolled back) on a reconciliation DB failure so Stripe retries.'
operationId: stripeConnectWebhook
requestBody:
description: Raw Stripe Connect event payload (signature-verified before parsing).
content:
application/json: {}
responses:
'200':
description: Event processed, replayed, or deliberately ignored.
'400':
description: Missing or invalid Stripe-Signature header.
'503':
description: Stripe is not configured on this instance.
/v1/stripe/webhook:
post:
tags:
- Billing
summary: '`POST /v1/stripe/webhook`'
description: 'Returns `200 OK` on success and on duplicate replays, `400` on
signature failure, `503` when Stripe is not configured.'
operationId: stripeWebhook
requestBody:
description: Raw Stripe event payload (signature-verified before parsing).
content:
application/json: {}
responses:
'200':
description: Event processed (or replayed).
'400':
description: Missing or invalid Stripe-Signature header.
'503':
description: Stripe is not configured on this instance.
/v1/usage:
get:
tags:
- Billing
summary: GET /v1/usage
operationId: get_usage
responses:
'200':
description: Plan limits and current usage for the active org.
content:
application/json:
schema:
$ref: '#/components/schemas/UsageView'
'401':
description: Caller is not authenticated.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
components:
schemas:
CeilingView:
type: object
description: One quota ceiling of a plan.
required:
- dimension
properties:
dimension:
type: string
description: Dimension slug (`contacts`, `invoices_finalized_monthly`, …).
limit:
type:
- integer
- 'null'
format: int64
description: The ceiling, or `null` when the plan grants this unlimited.
CheckoutPlan:
type: string
description: Wire-format plan slug accepted by checkout.
enum:
- solo
- studio
RedirectResponse:
type: object
description: 'Response payload for `POST /v1/billing/checkout-session` and
`POST /v1/billing/portal-session`.'
required:
- url
properties:
url:
type: string
description: Hosted URL the SPA should navigate to.
SetupIntentRequest:
type: object
description: JSON body of `POST /v1/billing/setup-intent`.
required:
- email
properties:
email:
type: string
description: Email used to seed the Stripe customer when none exists yet.
ErrorBody:
type: object
description: 'Generic error body returned by API handlers when they fail. `code` is a
stable machine-readable token; `message` is human-friendly and meant for
surfacing to end users.'
required:
- code
- message
properties:
code:
type: string
description: Stable machine token (e.g. `invalid_credentials`).
field:
type:
- string
- 'null'
description: Offending request field for validation errors, when known.
message:
type: string
description: Human-readable message.
InvoiceView:
type: object
description: One invoice row returned by `GET /v1/billing/invoices`.
required:
- id
- status
- amount_due_cents
- amount_paid_cents
- currency
- created
properties:
amount_due_cents:
type: integer
format: int64
description: Amount due in the smallest currency unit (cents).
amount_paid_cents:
type: integer
format: int64
description: Amount paid in the smallest currency unit (cents).
created:
type: integer
format: int64
description: Issue date as a Unix timestamp (seconds).
currency:
type: string
description: ISO 4217 currency code (lowercase).
hosted_invoice_url:
type:
- string
- 'null'
description: Stripe-hosted invoice URL, present once finalized.
id:
type: string
description: Stripe invoice id (`in_…`).
status:
type: string
description: Lifecycle status (`draft`, `open`, `paid`, `void`, `uncollectible`).
PreviewResponse:
type: object
description: Response of `GET /v1/billing/subscription/preview`.
required:
- amount_due_cents
- currency
- next_invoice_at
- proration_lines
properties:
amount_due_cents:
type: integer
format: int64
description: Total to charge immediately, in cents.
currency:
type: string
description: ISO 4217 lowercase currency.
next_invoice_at:
type: integer
format: int64
description: Next invoice timestamp (seconds).
proration_lines:
type: array
items:
$ref: '#/components/schemas/ProrationLineView'
description: Per-line breakdown of the proration.
BillingIntervalWire:
type: string
description: 'Billing cadence accepted by checkout and plan changes. Absent means
monthly, so a client that predates the annual offer is unaffected.'
enum:
- month
- year
LimitView:
type: object
description: One quota dimension in the usage view.
required:
- dimension
properties:
dimension:
type: string
description: Dimension slug (`contacts`, `ai_credits_monthly`, …).
limit:
type:
- integer
- 'null'
format: int64
description: Per-plan ceiling, or `null` when the plan grants this unlimited.
used:
type:
- integer
- 'null'
format: int64
description: Current usage, or `null` when not measured yet (module absent).
PriceView:
type: object
description: What a plan costs at one cadence.
required:
- amount_cents
- currency
properties:
amount_cents:
type: integer
format: int64
description: Unit amount in the currency's smallest unit — cents, never a float.
currency:
type: string
description: ISO 4217 code, lowercase.
PlanView:
type: object
description: One plan of the grid.
required:
- plan
- ceilings
- features
properties:
ceilings:
type: array
items:
$ref: '#/components/schemas/CeilingView'
description: Quota ceilings, one per dimension.
features:
type: array
items:
type: string
description: Slugs of the gated features this plan includes.
month:
oneOf:
- type: 'null'
- $ref: '#/components/schemas/PriceView'
description: 'Monthly price, or `null` when Stripe resolved none (and for Free, which
is not a Stripe price at all).'
plan:
type: string
description: Plan slug (`starter`, `solo`, `studio`).
year:
oneOf:
- type: 'null'
- $ref: '#/components/schemas/PriceView'
description: Yearly price, or `null` when Stripe resolved none.
SetDefaultPaymentMethodRequest:
type: object
description: JSON body of `POST /v1/billing/payment-methods/default`.
required:
- payment_method_id
properties:
payment_method_id:
type: string
description: '`pm_…` identifier to pin as default for invoices.'
ChangePlanResponse:
type: object
description: Response of `PATCH /v1/billing/subscription`.
required:
- subscription_id
- status
properties:
status:
type: string
description: Resulting subscription status.
subscription_id:
type: string
description: Stripe `sub_…` identifier (unchanged across plan swaps).
PortalSessionRequest:
type: object
description: JSON body of `POST /v1/billing/portal-session`.
required:
- return_url
properties:
return_url:
type: string
description: URL Stripe redirects to once the user leaves the portal; must be on the application origin.
SetupIntentResponse:
type: object
description: Response of `POST /v1/billing/setup-intent`.
required:
- client_secret
properties:
client_secret:
type: string
description: Short-lived secret consumed by `<PaymentElement>` to confirm a card.
PricingView:
type: object
description: Response of `GET /v1/pricing`.
required:
- plans
properties:
plans:
type: array
items:
$ref: '#/components/schemas/PlanView'
description: The three plans, cheapest first.
UsageView:
type: object
description: Response for `GET /v1/usage`.
required:
- plan
- limits
properties:
limits:
type: array
items:
$ref: '#/components/schemas/LimitView'
description: Per-dimension limits and usage.
plan:
type: string
description: Resolved plan slug (`starter`, `solo`, `studio`).
ProrationLineView:
type: object
description: One line of a proration preview.
required:
- description
- amount_cents
properties:
amount_cents:
type: integer
format: int64
description: Signed amount in cents (positive = charge, negative = credit).
description:
type: string
description: Human-readable description from Stripe.
CheckoutSessionRequest:
type: object
description: JSON body of `POST /v1/billing/checkout-session`.
required:
- plan
- success_url
- cancel_url
- email
properties:
cancel_url:
type: string
description: URL Stripe redirects to on cancel/back; must be on the application origin.
email:
type: string
description: 'Email used to seed the Stripe customer when none exists yet.
Caller is expected to send the org owner''s email.'
interval:
oneOf:
- type: 'null'
- $ref: '#/components/schemas/BillingIntervalWire'
description: Billing cadence (`month` / `year`); defaults to monthly.
plan:
$ref: '#/components/schemas/CheckoutPlan'
description: Target plan.
success_url:
type: string
description: URL Stripe redirects to on success; must be on the application origin.
CancelResponse:
type: object
description: Response of `POST /v1/billing/subscription/cancel`.
required:
- cancel_at
properties:
cancel_at:
type: integer
format: int64
description: Unix timestamp at which access ends (end of current period).
CreateSubscriptionRequest:
type: object
description: JSON body of `POST /v1/billing/subscription`.
required:
- plan
- payment_method_id
properties:
interval:
oneOf:
- type: 'null'
- $ref: '#/components/schemas/BillingIntervalWire'
description: Billing cadence (`month` / `year`); defaults to monthly.
payment_method_id:
type: string
description: '`pm_…` identifier of the card to charge.'
plan:
$ref: '#/components/schemas/CheckoutPlan'
description: Target plan slug.
promotion_code:
type:
- string
- 'null'
description: 'Optional customer-facing promotion code (e.g. `BIENVENUE8`). When
set and valid, the discount applies to the first invoice; an
unknown or inactive code is rejected with 422 before any charge.'
ChangePlanRequest:
type: object
description: JSON body of `PATCH /v1/billing/subscription`.
required:
- plan
properties:
interval:
oneOf:
- type: 'null'
- $ref: '#/components/schemas/BillingIntervalWire'
description: Billing cadence (`month` / `year`); defaults to monthly.
plan:
$ref: '#/components/schemas/CheckoutPlan'
description: New plan slug.
PaymentMethodView:
type: object
description: One row in `GET /v1/billing/payment-methods`.
required:
- id
- last4
- brand
- exp_month
- exp_year
- is_default
properties:
brand:
type: string
description: Brand (`visa`, `mastercard`, …).
exp_month:
type: integer
format: int32
description: Expiration month (1–12).
minimum: 0
exp_year:
type: integer
format: int32
description: Expiration year (four digits).
minimum: 0
id:
type: string
description: Stripe `pm_…` identifier.
is_default:
type: boolean
description: Whether this method is the customer's default for invoices.
last4:
type: string
description: Last four digits.
SubscriptionView:
type: object
description: Subscription view returned by `GET /v1/billing/subscription`.
required:
- plan
- cancel_at_period_end
properties:
cancel_at_period_end:
type: boolean
description: '`true` when the user has scheduled an end-of-period cancellation.'
card:
oneOf:
- type: 'null'
- $ref: '#/components/schemas/CardView'
description: Card on file, when one has been captured.
current_period_end:
type:
- integer
- 'null'
format: int64
description: '`current_period_end` as a Unix timestamp (seconds), when known.'
plan:
type: string
description: Resolved plan slug (`starter`, `solo`, `studio`).
status:
type:
- string
- 'null'
description: Stripe subscription status as a lowercase string, when a row exists.
trial_end:
type:
- integer
- 'null'
format: int64
description: 'End of the trial as a Unix timestamp (seconds), when in trial: a
Stripe trial, or the 14-day reverse trial every new org starts with
(`status` is then absent and `plan` is `solo`).'
CardView:
type: object
description: Card on file as exposed by `GET /v1/billing/subscription`.
required:
- brand
- last4
- exp_month
- exp_year
properties:
brand:
type: string
description: Card brand (`visa`, `mastercard`, …).
exp_month:
type: integer
format: int32
description: Expiration month (1–12).
exp_year:
type: integer
format: int32
description: Expiration year (four digits).
last4:
type: string
description: Last four digits.
CreateSubscriptionResponse:
type: object
description: Response of `POST /v1/billing/subscription`.
required:
- subscription_id
- status
properties:
requires_action_client_secret:
type:
- string
- 'null'
description: Set when 3DS confirmation is required — pass to `confirmCardPayment`.
status:
type: string
description: Subscription status (`active`, `incomplete`, …).
subscription_id:
type: string
description: Stripe `sub_…` identifier.
securitySchemes:
api_key:
type: http
scheme: bearer
session:
type: apiKey
in: cookie
name: asap_session