Sell a file#
A PDF, a dataset, a clip, a zip. Someone pays; they get the bytes.
A file is not a fifth fulfilment mode. It is relay — pointed at the file
instead of at an API — plus a content declaration that says what kind of thing
is behind the wall. That gives it a browser face at /x/{id} and a download
disposition, and costs the object model nothing.
The file stays on your server. We never hold a copy.
Make one#
Create a checkout → A file → paste the URL, name it, set a price.
c402 checkouts create \
--title "Q3 report" --price 5.00 \
--origin-url https://yourserver.com/reports/q3.pdf \
--description "Forty pages of quarterly numbers." \
--content '{"media": "file", "filename": "q3-report.pdf"}'
Sell
https://yourserver.com/reports/q3.pdffor $5 as a file called q3-report.pdf.
curl -X POST https://api.checkout402.com/v1/checkouts \
-H "Authorization: Bearer c402_live_…" \
-H "content-type: application/json" \
-d '{"title": "Q3 report",
"price_usd": "5.00",
"origin_url": "https://yourserver.com/reports/q3.pdf",
"description": "Forty pages of quarterly numbers.",
"content": {"media": "file", "filename": "q3-report.pdf"}}'
The id comes back cnt_, and the URL to share is /x/{id}.
A file is a listing, not an invoice
Checkouts are single-shot by default, which is right for "pay me for this
job" and wrong for "here is a thing I sell" — the first sale would consume
it and the second buyer would get a 410 from a store that looked open.
So a file defaults to reusable: true and carries no deadline. Send
reusable: false if you really do mean one buyer.
What the buyer gets#
A person opens /x/{id} |
your title, description and price, then a pay button |
| They pay | the bytes, with Content-Disposition: attachment and the name you set |
| An agent asks for JSON | a 402 with the price, then the file base64-enveloped as payload_base64 |
An <img>/<video>/<audio> element |
/x/{id}/media, which honours Range so a browser can seek |
Unpaid callers to /x/{id}/media get a 402 with a Link: …; rel="payment"
header rather than the pay page — the caller is usually a tag, and an HTML
document renders as a broken image.
Nothing is cacheable: private, no-store on every paid response, and
X-Content-Type-Options: nosniff so a gated image cannot be sniffed into
something executable.
Naming the download#
content.filename is what the file is saved as. It is sanitised at declaration
— control characters, quotes and path separators are stripped — and sent
RFC 5987-encoded, so a non-ASCII name survives intact and a name can never
inject a header.
Leave it out and the browser falls back to whatever it derives from the URL.
The 5 MB limit, and what to do above it#
The relay buffers the response, so bodies over 5 MB are refused. That covers a report, a photo, a short clip, a spreadsheet. It does not cover a 200 MB video or a large dataset.
For anything bigger, point origin_url at your own endpoint that returns a
signed URL — S3, R2, GCS — instead of at the file. The buyer pays, we call
your endpoint, and they get a short-lived link. The bytes never pass through us,
so there is no size limit at all, and you keep control of expiry.
c402 checkouts create --title "Full dataset" --price 40.00 \
--origin-url https://yourserver.com/sign/dataset \
--content '{"media": "file"}'
Keep the signed URL's lifetime short: it is a bearer link for as long as it lives.
Behind your own credential#
The file can sit behind a key your server checks. Store it once and the buyer never sees it:
c402 checkouts create --title "Q3 report" --price 5.00 \
--origin-url https://yourserver.com/private/q3.pdf \
--origin-auth-type bearer --origin-auth-value "$YOUR_KEY" \
--content '{"media": "file", "filename": "q3-report.pdf"}'
The credential is encrypted at rest, injected server-to-server, and never appears in anything the buyer can see.
Say what it is#
A gated piece needs something free to judge it by: a description, a
content.teaser, or a content.preview_url (a cover image). Create is refused
without one — a price with nothing behind it does not sell, and the refusal is
cheaper than the silence.
What next#
- What can I sell? — the four modes side by side
- Pay to Read — the same face, for prose
- Sell an API — relay in its usual shape