Docs / api-advanced

Custom endpoints, API docs & security

Once your project's REST API is on, four more tabs let you add custom endpoints, read its OpenAPI docs, test requests, and lock it down.

Enabling the API and creating keys are covered in REST API for your data — this page picks up from there.

Custom endpoints

The generated data API covers CRUD on your tables. Anything else — a monthly sales summary, a webhook receiver — is a custom endpoint. Ask the AI for one on the Endpoints tab.

  1. Fill in the slug (sales-summary): lowercase letters, digits and hyphens, 2 to 50 characters, unique per project — a name already taken is refused.
  2. Describe what the endpoint should do, up to 2,000 characters.
  3. Pick how it authenticates — End-user login (ownership-scoped), API key (service-role) or Public (no auth).
  4. Click Create API.

That queues an ordinary AI run: follow it in the project chat, and it is charged like any other run. The AI writes one route file at app/api/custom/<slug>/route.ts, reusing the auth and query helpers the data API already uses, then registers it under Custom endpoints in the catalog and the docs.

A custom endpoint is AI-written code sitting in your repository. Read it as you would any other route before you rely on it — especially one you set to Public (no auth).

API docs

The Docs tab renders Swagger UI over an OpenAPI document generated from your real schema and settings: exposed models, the operations you left on, your custom endpoints, and the auth each expects. Anything you hid from the API is not described in it.

Switch between Preview and Production at the top. Each reads that environment's live /api/openapi, so the target has to be running — start a preview or publish first. Try-it-out is off here on purpose: the docs are read-only, and Console is the interactive path.

The test console

The Console tab sends a real request to your Preview or Production app and shows the status, duration and body.

  • Pick a method, then a path — the field autocompletes from your catalog.
  • Paste a key into the masked X-API-Key field when the endpoint needs one.
  • POST, PUT and PATCH reveal a JSON body box.

The request goes out server-side, not from your browser: your key is forwarded straight to your app and never recorded, and browser CORS rules never block a test. Paths must start with /api/, bodies are capped at 100 KB, and a request is abandoned after 15 seconds.

CORS

By default the API answers same-origin requests only — a browser on another domain gets nothing. The allow-list lives on the Security tab.

  1. Type an origin (https://app.example.com) and click Add. Repeat per origin.
  2. Tick Allow credentials (cookies) if your front end sends cookies.
  3. Click Save CORS.

* is allowed and reflects every origin — but the credentials checkbox disables itself while * is in the list. That is the browser's rule, not ours, and it is enforced twice: saving both is refused, and the generated code drops the credentials header at runtime anyway.

Rate limits

On the same tab, tick Enable rate limit to throttle callers before they reach your data.

FieldDefaultRange
Max requests601 – 100,000
Window (seconds)601 – 86,400
PerAPI keyAPI key or IP address
StorageIn-memoryIn-memory or Database

Per → API key counts each key separately, falling back to the caller's address when there is no key; IP address counts every caller by address. Over the limit, the API answers 429.

In-memory (fast, resets on redeploy) keeps counters inside the running app — no database writes, but a deploy clears them. Database (survives restart) stores them in your own database, at one extra write per request.

Key scopes in practice

A key created with Full access (all models & operations) can do anything the API exposes. Untick that and you get a grid of your models against the five operations — list, read, create, update, delete — where each box you tick becomes a scope.

Give a public dashboard a key holding only Order:list and Order:read, and a leaked copy still cannot write a row or read another table. A narrowed key is deny-by-default: anything unticked is refused, even on a model the API otherwise exposes. Use Scope on the key row to tighten a key later without rotating it.

Limits & notes

  • Custom slugs: lowercase, digits, hyphens; 2–50 characters; unique per project. Descriptions up to 2,000 characters.
  • Creating a custom endpoint costs a run, like any prompt.
  • Console: paths must start with /api/; 100 KB body cap; 15-second timeout.
  • In-memory rate-limit counters reset on every deploy; a * origin never carries credentials.
  • If your API was enabled before scopes, CORS and rate limits existed, click Upgrade API code on the Endpoints tab first — the banner appears when an update is waiting.
  • All of this is code and config in your repository, so it survives an export.
  • Limits may change during alpha.