Start here

building

From a new account to your first successful API call, in about two minutes.

Quickstart

Two minutes from nothing to a working call. You need an account and a project — if you have one open in the console, you already have everything below.

1. Your base URL and key

Every request goes to the same base and carries the same kind of key:

bash
export BASE="https://<your-deployment>"
export KEY="sk_live_…"          # the secret key from your project page

Your project page shows both. The key is displayed once, when it is issued — if you have lost it, issue another; keys are free and revoking the old one takes a click.

Two kinds exist and the difference matters:

Where it goesWhat it can do
sk_… secretOn your server, onlyEverything
pk_… publishableIn your app's frontendSign users in, and nothing else

A publishable key is safe in a browser because it can't reach the management APIs. A secret key in a browser is a breach, so we make it impossible rather than discouraged — the endpoints that matter answer no preflight at all.

2. Your first call

bash
curl "$BASE/v1/files" -H "authorization: Bearer $KEY"
json
{ "files": [], "total": 0, "page": 1, "totalPages": 0, "nextCursor": null }

That's a working integration. An empty list is the correct answer for a new project, and the response shape is the one you'll get with a thousand files in it.

If you got 401, the key is wrong or revoked. If you got nothing at all, $BASE is unset — the most common first mistake, and the reason it is spelled out above.

3. Upload something

Uploading is three calls, and the middle one doesn't touch us at all:

bash
# a) Ask where to put it
curl -X POST "$BASE/v1/files/upload-intent" \
  -H "authorization: Bearer $KEY" -H "content-type: application/json" \
  -d '{"filename":"hello.txt","contentType":"text/plain","size":11}'
bash
# b) Send the bytes straight to storage, using the url that came back
curl -X PUT "<uploadUrl>" -H "content-type: text/plain" --data-binary "hello world"
bash
# c) Tell us it landed
curl -X POST "$BASE/v1/files/confirm" \
  -H "authorization: Bearer $KEY" -H "content-type: application/json" \
  -d '{"id":"<id from step a>"}'

The bytes never pass through us, which is why a 500 MB upload costs you one request rather than a timeout. Upload files has the full shape.

4. Sign someone in

Auth is enabled per project, because it gives you a Postgres database of your own — open Auth on your project page and turn it on. Then:

bash
curl -X POST "$BASE/v1/auth/sign-up/email" \
  -H "authorization: Bearer $KEY" -H "content-type: application/json" \
  -d '{"email":"ada@example.com","password":"correct-horse-battery","name":"Ada"}'

A session cookie comes back, and that user now exists in a database no other project can reach. Auth covers social login, passkeys, two-factor, organizations and SSO — all of it on the same key.

Nothing here assumes a client library. There is no SDK yet, so this HTTP API is the whole interface, and every example above is a request you can paste into a terminal.