Scribiz Billing API
The Billing API from Scribiz — 5 operation(s) for billing.
The Billing API from Scribiz — 5 operation(s) for billing.
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/scribiz:scribiz-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: Scribiz Billing API
version: 1.0.0
description: 'Operations tagged Billing across 2 of this provider''s published API definitions: openapi.json, scribiz-openapi.json. Each path carries the servers of the definition it was published in.'
servers:
- description: 'The one public base for every client: https://scribiz.com/api (Better Auth at /api/auth, remote MCP at https://scribiz.com/mcp). The proxy routes both paths to this API.'
url: https://scribiz.com/api
tags:
- name: Billing
paths:
/v1/billing/checkout:
post:
description: 'Start a purchase with Stripe. Needs a signed-in session (a browser session or the session token of the device flow), not an API key. Send a plan name and nothing else: the price, the amount and the URLs are decided by the server, and a body with any other field is refused. The answer is the Stripe Checkout URL to send the buyer to; it is always a URL on stripe.com that Stripe returned. Until the owner switches payments on, and for any plan with no price set, this answers 501 `billing_not_configured`. 409 `not_on_sale` (set up but not open to the public), `already_owned` (Mac Lifetime is already on the account) or `already_subscribed` (Pro is already running: the error has `portal: true`). At most 10 starts an hour per account.'
operationId: billingCheckout
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CheckoutRequest'
description: JSON
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CheckoutStarted'
description: The Checkout page to send the buyer to.
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: unauthorized
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: session_required, bad_origin
'409':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: not_on_sale, already_owned, already_subscribed
'413':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: body_too_large
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: 'invalid_request: the plan, interval or pack is not valid (`error.field` says which).'
'429':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: rate_limited
'501':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: 'billing_not_configured: paid plans are not open for purchase yet.'
'502':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: 'stripe_unavailable: nothing was charged.'
'503':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: billing_misconfigured, busy
security:
- apiKey: []
- bearer: []
- cookie: []
- {}
summary: Start a purchase
tags:
- Billing
servers:
- description: 'The one public base for every client: https://scribiz.com/api (Better Auth at /api/auth, remote MCP at https://scribiz.com/mcp). The proxy routes both paths to this API.'
url: https://scribiz.com/api
/v1/billing/checkout/confirm:
post:
description: 'After the buyer comes back from Stripe: apply the purchase now when the webhook is late. Idempotent. A Stripe failure is `pending`, never an error. Only for the account that started that checkout (anything else is 404). At most 120 an hour per account.'
operationId: billingCheckoutConfirm
requestBody:
content:
application/json:
schema:
additionalProperties: false
properties:
sessionId:
description: The `cs_...` id from the success URL.
type: string
required:
- sessionId
type: object
description: JSON
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CheckoutConfirmed'
description: Where the purchase stands.
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: unauthorized
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: session_required, bad_origin
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: not_found
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: invalid_request
'429':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: rate_limited
'501':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: billing_not_configured
security:
- apiKey: []
- bearer: []
- cookie: []
- {}
summary: Confirm a purchase after Stripe sends the buyer back
tags:
- Billing
servers:
- description: 'The one public base for every client: https://scribiz.com/api (Better Auth at /api/auth, remote MCP at https://scribiz.com/mcp). The proxy routes both paths to this API.'
url: https://scribiz.com/api
/v1/billing/offer:
get:
description: 'What can be bought right now, with the prices. Public. `plans` holds only what the caller can buy: with nothing on sale it is empty (`configured: false` while payments are not set up at all). A signed-in preview account also sees a configured plan that is not public yet, marked `preview: true`. `mac-lifetime.amount` is what the next buyer pays (the early bird price while a place is left, otherwise the list price). Amounts are USD cents. Cached for 15 seconds for anonymous callers; at most 60 requests a minute per visitor.'
operationId: billingOffer
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/BillingOffer'
description: The offer.
'429':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: rate_limited
security:
- apiKey: []
- bearer: []
- cookie: []
- {}
summary: What is on sale
tags:
- Billing
servers:
- description: 'The one public base for every client: https://scribiz.com/api (Better Auth at /api/auth, remote MCP at https://scribiz.com/mcp). The proxy routes both paths to this API.'
url: https://scribiz.com/api
/v1/billing/portal:
post:
description: Open Stripe's billing portal for the account (receipts, card, cancelling Pro). Needs a signed-in session, not an API key. The answer is a short-lived stripe.com URL. 409 `no_billing_account` when the account has never started a checkout. At most 20 an hour per account.
operationId: billingPortal
responses:
'200':
content:
application/json:
schema:
properties:
url:
type: string
required:
- url
type: object
description: The portal URL.
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: unauthorized
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: session_required, bad_origin
'409':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: no_billing_account
'429':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: rate_limited
'501':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: billing_not_configured
'502':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: stripe_unavailable
'503':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: billing_misconfigured
security:
- apiKey: []
- bearer: []
- cookie: []
- {}
summary: Open the billing portal
tags:
- Billing
servers:
- description: 'The one public base for every client: https://scribiz.com/api (Better Auth at /api/auth, remote MCP at https://scribiz.com/mcp). The proxy routes both paths to this API.'
url: https://scribiz.com/api
/v1/billing/webhook:
post:
description: For Stripe only. Stripe signs every call (`Stripe-Signature`, HMAC-SHA256 over the timestamp and the raw body, five minute window) and a call without a good signature is refused with 400 before anything is read. No account, key or cookie is involved and nothing here is for programs. 501 `billing_not_configured` while payments are not set up.
operationId: billingWebhook
requestBody:
content:
application/json:
schema:
type: object
description: A Stripe event.
responses:
'200':
content:
application/json:
schema:
properties:
received:
const: true
type: object
description: Received.
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: invalid_signature, invalid_payload
'413':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: body_too_large
'429':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: 'rate_limited: too many bad signatures from one address.'
'500':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: 'retry_later: not handled yet, Stripe sends it again.'
'501':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: billing_not_configured
'503':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: busy
summary: Stripe's events
tags:
- Billing
servers:
- description: 'The one public base for every client: https://scribiz.com/api (Better Auth at /api/auth, remote MCP at https://scribiz.com/mcp). The proxy routes both paths to this API.'
url: https://scribiz.com/api
components:
schemas:
CheckoutConfirmed:
properties:
captionCredits:
description: Caption wallet balance for a caption purchase; null for other purchases.
type:
- integer
- 'null'
kind:
enum:
- pro
- mac-lifetime
- topup
lifetimeMac:
type: boolean
minutesTopup:
type: number
paid:
description: 'True when Stripe says the checkout was paid. A `pending` state with `paid: false` is not a payment (the checkout is still open, or Stripe could not be asked): do not tell the buyer one went through.'
type: boolean
plan:
enum:
- free
- pro
- lifetime
planUntil:
type:
- number
- 'null'
state:
enum:
- active
- pending
- expired
- failed
required:
- state
- kind
- plan
- planUntil
- lifetimeMac
- minutesTopup
- paid
type: object
Error:
properties:
error:
additionalProperties: true
properties:
code:
description: snake_case.
type: string
engineCode:
description: The engine's own code (QUOTA, SOURCE_UNAVAILABLE, ...) when there is one.
type: string
hint:
type: string
message:
type: string
required:
- code
- message
type: object
required:
- error
type: object
CheckoutRequest:
additionalProperties: false
properties:
datafastSessionId:
type: string
datafastVisitorId:
type: string
interval:
description: Pro only. Default month.
enum:
- month
- year
pack:
description: Extra minutes only.
enum:
- small
- medium
- large
plan:
enum:
- pro
- mac-lifetime
- topup
ref:
description: Where the visitor came from (1 to 40 of a-z, 0-9, dot, dash, underscore).
type: string
required:
- plan
type: object
CheckoutStarted:
properties:
amount:
description: 'What this Checkout page charges, in cents, before tax: the price the buyer will see there. Compare it with the price the page showed before sending the buyer on.'
type: integer
currency:
description: Lower case ISO code, `usd`.
type: string
earlyBird:
description: True when the page is at the Mac Lifetime early bird price.
type: boolean
expiresAt:
description: Epoch milliseconds.
type: number
sessionId:
type: string
url:
description: A Stripe Checkout URL.
type: string
required:
- url
- sessionId
- expiresAt
- amount
- currency
- earlyBird
type: object
BillingOffer:
properties:
configured:
description: False while payments are not set up at all.
type: boolean
plans:
description: Only what the caller can buy now. Empty when nothing is on sale.
properties:
mac-lifetime:
properties:
amount:
description: What the next buyer pays, in cents.
type: integer
buyers:
description: Paid purchases, net of refunds and disputes.
type: integer
currency:
const: usd
earlyBird:
properties:
left:
type: integer
places:
type: integer
type:
- object
- 'null'
listAmount:
type: integer
preview:
type: boolean
type: object
pro:
properties:
intervals:
items:
properties:
amount:
type: integer
currency:
const: usd
interval:
enum:
- month
- year
type: object
type: array
preview:
type: boolean
type: object
topup:
properties:
captionPacks:
items:
properties:
amount:
type: integer
captions:
type: integer
currency:
const: usd
id:
enum:
- captions-200
- captions-1200
- captions-5000
type: object
type: array
packs:
items:
properties:
amount:
type: integer
currency:
const: usd
id:
enum:
- small
- medium
- large
minutes:
type: integer
type: object
type: array
preview:
type: boolean
type: object
type: object
signInRequired:
type: boolean
taxAtCheckout:
type: boolean
required:
- configured
- signInRequired
- taxAtCheckout
- plans
type: object
securitySchemes:
apiKey:
description: 'An API key (sbz_live_...), as X-API-Key. Keys are made in the dashboard or by `scribiz login`. Each key has one scope, named in an operation''s security requirement. `all`: Everything a key can do: start jobs, upload, ask, cancel, the Gemini proxy and listing keys. Includes read. `mcp`: The remote MCP server at /mcp. Includes read. `read`: Read jobs and their events.'
in: header
name: X-API-Key
type: apiKey
x-scopes:
all: 'Everything a key can do: start jobs, upload, ask, cancel, the Gemini proxy and listing keys. Includes read.'
mcp: The remote MCP server at /mcp. Includes read.
read: Read jobs and their events.
bearer:
description: 'An API key (sbz_live_...) or a session token from the device flow. Each key has one scope, named in an operation''s security requirement. `all`: Everything a key can do: start jobs, upload, ask, cancel, the Gemini proxy and listing keys. Includes read. `mcp`: The remote MCP server at /mcp. Includes read. `read`: Read jobs and their events. A session token has every scope.'
scheme: bearer
type: http
x-scopes:
all: 'Everything a key can do: start jobs, upload, ask, cancel, the Gemini proxy and listing keys. Includes read.'
mcp: The remote MCP server at /mcp. Includes read.
read: Read jobs and their events.
cookie:
description: The browser session (same-origin /api/*).
in: cookie
name: better-auth.session_token
type: apiKey
x-refined-from:
- openapi.json
- scribiz-openapi.json