Inboxy Billing API
Stripe checkout, billing portal, and plan changes.
Stripe checkout, billing portal, and plan changes.
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/inboxy-net:inboxy-net-billing-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a 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: inboxy Billing API
version: 0.3.0
summary: Read + manage your inboxy.net inbox programmatically.
description: 'REST surface over the inboxy alias inbox. Mint aliases, list/search/read
messages, fetch attachments, manage your API keys, and emit user-initiated
mail under one of your aliases.
Mail-emitting paths (`POST /v1/messages/{id}/reply`, `POST /v1/mail/send`,
`POST /v1/mail/invite`) are recipient-locked and alias-locked server-side:
the `From:` is always one of the caller''s `@inboxy.net` aliases, the
recipient is validated against per-user caps and the abuse rules in
`packages/reply`, and every external message carries the mandatory
inboxy attribution footer. There is no arbitrary-`From:` send path.
All endpoints require a bearer API key created from the inboxy.net web UI
at `/account/keys` (mint is gated by step-up and lives only on the web — there
is no API-channel mint). Pass it as `Authorization: Bearer ik_…`.
The signed-token attachment download URLs (`/v1/attachments/{token}/download`,
`/v1/messages/raw/{token}/download`) are public-by-token — they intentionally
bypass bearer auth and are not listed here. Obtain them via the JSON
endpoints below.'
contact:
name: inboxy
url: https://inboxy.net
license:
name: Proprietary
servers:
- url: https://api.inboxy.net
description: Production
security:
- bearerAuth: []
tags:
- name: Billing
description: Stripe checkout, billing portal, and plan changes.
paths:
/v1/billing/checkout:
post:
tags:
- Billing
summary: Start a Stripe Checkout session for a paid plan
description: Requires `manage` scope. Refuses if the account already has an active subscription (`already_subscribed`, 409 — use `/v1/billing/change-plan` to switch tiers instead). `plan_id` must name a real, paid, currently-purchasable plan (`bad_request`, 400, for an unknown or free plan_id; `plan_unavailable`, 404, for a real paid plan with no `stripe_price_id` yet). The billing cycle anchor is pinned to the next 1st-of-the-month UTC boundary regardless of when checkout completes.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BillingCheckoutRequest'
responses:
'200':
description: Checkout session created — redirect the caller to `url`.
content:
application/json:
schema:
type: object
required:
- url
properties:
url:
type: string
format: uri
'400':
$ref: '#/components/responses/BadRequest'
'403':
$ref: '#/components/responses/Forbidden'
'404':
description: '`plan_unavailable` — plan exists but isn''t purchasable yet.'
'409':
description: '`already_subscribed` — use `/v1/billing/change-plan` instead.'
operationId: postV1BillingCheckout
x-operation-id-source: derived
/v1/billing/portal:
post:
tags:
- Billing
summary: Open a Stripe billing portal session for the caller
description: Requires `manage` scope. No request body. Refuses if the account has never checked out (`no_subscription`, 409 — no `stripe_customer_id` on file yet).
responses:
'200':
description: Portal session created — redirect the caller to `url`.
content:
application/json:
schema:
type: object
required:
- url
properties:
url:
type: string
format: uri
'403':
$ref: '#/components/responses/Forbidden'
'409':
description: '`no_subscription` — no billing account yet; checkout first.'
operationId: postV1BillingPortal
x-operation-id-source: derived
/v1/billing/change-plan:
post:
tags:
- Billing
summary: Switch the caller's existing subscription to a different paid plan
description: 'Requires `manage` scope. Refuses if the account has no active subscription (`no_subscription`, 409 — use `/v1/billing/checkout` to start one instead). `plan_id` must name a real, paid, currently-purchasable plan different from the account''s current one (`bad_request`, 400, for an unknown, free, unpurchasable, or already-active plan_id). Upgrades swap the subscription''s price immediately with no proration charge, billed in full next cycle (`effective: "immediately"`). Downgrades are scheduled for the next renewal so the caller keeps what they already paid for until the period ends (`effective: "at_period_end"`).'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BillingChangePlanRequest'
responses:
'200':
description: Plan change applied or scheduled.
content:
application/json:
schema:
type: object
required:
- ok
- effective
properties:
ok:
type: boolean
enum:
- true
effective:
type: string
enum:
- immediately
- at_period_end
'400':
$ref: '#/components/responses/BadRequest'
'403':
$ref: '#/components/responses/Forbidden'
'409':
description: '`no_subscription` — no active subscription; checkout first.'
operationId: postV1BillingChangePlan
x-operation-id-source: derived
components:
responses:
BadRequest:
description: Malformed request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Forbidden:
description: Token lacks the required scope.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
schemas:
BillingChangePlanRequest:
type: object
required:
- plan_id
properties:
plan_id:
type: string
description: The paid plan id to switch to. Must differ from the account's current plan.
example: pro_v1
BillingCheckoutRequest:
type: object
required:
- plan_id
properties:
plan_id:
type: string
description: A paid plan's immutable id, e.g. `standard_v1`. Free plans and unpurchasable plans (no `stripe_price_id` yet) are rejected.
example: standard_v1
Error:
type: object
required:
- error
properties:
error:
type: string
enum:
- bad_request
- unauthorized
- forbidden
- not_found
- gone
- rate_limited
- internal
- invalid_token
- blocked
message:
type: string
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: ik_…
description: Static API key. Three scopes — `read` (everything except mutations), `manage` (mutations other than sending) and `send` (`/v1/mail/send`, replies, invites). Mint at https://inboxy.net/account/keys (the web UI gates mint with step-up; there is no API-channel mint).