// GETTING STARTED
Platform API for AI Coding Tools
A per-project API key and REST endpoints under /api/v1 — let an AI coding tool check deploy status, read logs, trigger deploys, and read/write env vars on its own.
The Dev Prompt is a one-time snapshot — useful to paste at the start of a session, but it goes stale the moment something changes. The Platform API is the always-live counterpart: a REST API scoped to a single project that an AI coding tool (or any script) can call directly, without a human regenerating and re-pasting anything.
Getting a key
Open a project's Dev Prompt page and generate a key in the API Key card — optionally give it a name (e.g. "Cursor", "CI") so you can tell keys apart later. The raw key is shown exactly once — copy it immediately, since AnySites only ever stores its hash, not the value itself. A project can have any number of keys at once, each independently revocable, so giving one tool its own key doesn't affect any other tool's access. Revoking a key removes its access immediately; the others keep working.
Authentication
Authorization: Bearer ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxEvery request needs this header. There's no separate login step and no session — the key is the credential. A missing or revoked key returns 401.
Base URL
https://api.anysites.app/api/v1Endpoints
| Method & path | What it does |
|---|---|
GET /status | Project status, site type, tech stack, build/start commands, port, the currently active deploy, and custom domains. |
GET /deploys | The last 20 deploys — status, commit, branch, who/what triggered it. |
GET /deploys/:deployId | One deploy in full, including the complete build log. |
POST /deploys | Trigger a build of the production branch's latest commit — same pipeline as clicking Manual Deploy. Returns 409 if a deploy is already in flight. |
GET /logs/runtime?lines=200 | Recent stdout/stderr from the running container. Same data as the dashboard's Runtime Logs page, not a live stream. |
GET /env | Every environment variable with its real value — no masking, since the key itself already grants this level of access. |
PUT /env/:key | Create or update one variable. Rejects keys that don't match [A-Z_][A-Z0-9_]*. System variables (like DATABASE_URL) can't be modified this way — 403. |
DELETE /env/:key | Delete one variable. System variables can't be deleted this way — 403. |
GET /database | The project's live DATABASE_URL, if a database is provisioned. |
GET /resources | The running container's current disk (writable layer) and memory usage, plus the thresholds AnySites itself alerts and auto-remediates on. |
POST /deploys afterward if you need the change live immediately.Checking your own container's footprint
A container's writable layer (local caches, log files, anything the app writes to its own filesystem instead of the database or object storage) is disposable but not unlimited — AnySites monitors it platform-wide and, past a hard ceiling, automatically recreates the container to reclaim the space. That's a safety net for the shared node, not a substitute for the app managing its own cache. GET /resources returns the same numbers that monitoring uses, so an AI coding tool can check them directly instead of finding out the hard way.
| Field | Meaning |
|---|---|
diskUsageBytes | Current size of the container's writable layer. |
diskWarningBytes / diskCriticalBytes | 5GB / 15GB. Past warning, AnySites logs an alert. Past critical, it recreates the container (same image, same config, fresh writable layer) automatically. |
memoryUsageBytes / memoryLimitBytes | Current usage against the container's memory limit. |
fetch() Data Cache writing to .next/cache/fetch-cache with no revalidate policy, which can grow into the tens of gigabytes over a few days of traffic. If diskUsageBytes is climbing toward diskWarningBytes, that's usually where to look.Database management (`/db` prefix)
These run against the same connection pool and introspection logic as the project's Table Editor and SQL Editor in the dashboard — same trust level as a direct psql connection, not sandboxed to SELECT.
| Method & path | What it does |
|---|---|
GET /db/schema | Every table: columns (type, nullable, default, primary key, foreign key), indexes, size, and row estimate. |
GET /db/tables/:table/rows | Paginated rows. Query params: schema (default public), limit (max 500), offset, orderBy, orderDir, filters (JSON object of column→value equality filters). |
POST /db/tables/:table/rows | Insert one row. Body: { values: {...} }. |
PATCH /db/tables/:table/rows | Update one row. Body: { pk: {...}, values: {...} }. 404 if the table has no primary key — there's nothing safe to match on. |
DELETE /db/tables/:table/rows | Delete one row. Body: { pk: {...} }. |
POST /db/query / POST /db/migrate | Identical endpoints — run arbitrary SQL, including multi-statement scripts and DDL (CREATE TABLE, etc.). Body: { sql: "..." }. Results capped at 500 rows, 15-second statement timeout, same as the SQL Editor. /db/migrate is just a clearer name for the same thing: running a full schema.sql or migration file against a freshly-provisioned, empty database. |
POST /db/tables | Create a table. Body: { schema?, name, columns: [{ name, dataType, nullable, default?, primaryKey? }] }. |
DELETE /db/tables/:table | Drop a table. |
POST /db/tables/:table/columns | Add a column. Body: { column: { name, dataType, nullable, default? } }. |
DELETE /db/tables/:table/columns/:column | Drop a column. |
POST /db/tables/:table/indexes | Create an index. Body: { name, columns: [...], unique? }. |
DELETE /db/tables/:table/indexes/:indexName | Drop an index. |
Example
curl -H "Authorization: Bearer ak_..." https://api.anysites.app/api/v1/status
curl -H "Authorization: Bearer ak_..." https://api.anysites.app/api/v1/db/schemaDesign notes
None of these routes take a project ID in the URL — the key itself identifies exactly one project, so there's no ID to get wrong or spoof. This is deliberate: it's structurally impossible to use one project's key to read or modify another project's data, regardless of what path you construct.