https://api.crevio.co/v1. Read this page before writing more than a quickstart call — most 400/404/422 errors come from breaking one of the rules below.
Parameters are unwrapped (top-level)
Send request fields at the top level of the JSON body. There is no resource wrapper key. A nested wrapper like{"product": {...}} is rejected with a 400 parameter_unknown error naming the wrapper — see Errors.
Associations are a bare name + a prefixed id
To link a resource, use the bare resource name as the key and pass the prefixed id string as the value. Do not append_id.
Creation order matters
Some resources have prerequisites. The big one: a product can’t be published without at least one price variant. Creating a product withstatus: "active" in a single call fails with 422.
1
Create the product as a draft
POST /products with status: "draft".2
Create one or more price variants
POST /price_variants with product: "prod_...".3
Publish
PATCH /products/{id} with status: "active".Money is in cents; currency is lowercase
All monetary amounts are integers in the smallest currency unit (cents for USD). Currency codes are lowercase ISO 4217.List responses vs single objects
List endpoints return a consistent envelope. The items are indata.
Pagination
Cursor-based. Passlimit (1–100, default 15) and starting_after (the id of the last item you received). When has_more is false, you’re on the last page.
Metadata
Products, customers, orders, checkouts, checkout links, and sites carry ametadata object — key-value storage that’s yours, not ours. Use it to store your own system’s IDs, campaign labels, or anything else you need to correlate Crevio objects with the rest of your stack. Crevio never interprets it.
- Up to 50 keys per object; keys max 40 characters, values stored as strings up to 500 characters.
- Updates merge key by key. Set a key to
null(or"") to remove it. - Metadata set on a checkout is copied to the order it produces, and it’s echoed in webhook payloads — so an
order.paidwebhook already carries your correlation IDs. - List endpoints filter by it:
?metadata[campaign]=spring(all pairs must match).
Slug lookup
Products, blog posts, experiences, and legal pages accept either an id or a slug in the{id_or_slug} path position.
Expanding related resources
By default, related resources appear as bare id strings. Passexpand to inline them. Multiple fields are comma-separated.
Delete responses
Delete endpoints return a confirmation object, not an empty body:The object discriminator
Every resource carries anobject field identifying its type. Use it to branch on heterogeneous responses.
ID prefixes
Every id is a prefixed string encoding its type. Use these — never raw database ids.Courses and other content live under
/experiences, not /products. A product bundles experiences through its price variants. The Experiences API is read-only (list + retrieve).Next steps
Errors
Every status code, what it means, and how to debug it.
Quickstart
Apply these rules in a real product creation.
API reference
Per-endpoint parameters and schemas.
TypeScript SDK
The SDK enforces most of these conventions for you.

