# API reference

Everything the portal does, from code. Same rules, same checks, same jobs. See the [MCP reference ](https://docs.lathe.live/mcp)for the same ground from an AI agent.

## API keys

One credential for both the REST API and the MCP server.

[Sign in ](https://app.lathe.live/login), then create a key on the [Access page ](https://app.lathe.live/account/access). A key acts as the customer who created it and cannot create or revoke other keys. Send it on every request:

```
Authorization: Bearer lathe_…
```

A key made while you are working in an organization belongs to that organization and acts for you there, with your role: a viewer's key reads, a developer's runs the instances, an admin's manages them. It stops working the moment you leave the organization, and a change to your role applies to its next request. GET /me says which account a key acts in and as whom ( kind , role , actor ). A call your role does not allow is answered 403 with code forbidden and a sentence naming the role it needs. Members are invited and removed in the portal, never through a key.

## Webhooks

Every event about your instances, posted to an https URL of yours. Add endpoints on the [Integrations page ](https://app.lathe.live/account/integrations#webhooks)or with POST /webhooks .

Each delivery is a POST with a JSON body {"id", "type", "instance_id", "at", "data"} and three headers: X-Lathe-Event (the type), X-Lathe-Delivery (an id, the same on every retry) and X-Lathe-Signature - sha256= followed by the hex HMAC-SHA256 of the raw body with the endpoint's secret. Verify the signature before trusting the body. Answer any 2xx within 10 seconds; anything else is retried after 1, 5 and 30 minutes, then 2 and 12 hours, then given up. An endpoint that fails 20 deliveries in a row is disabled until you enable it again.

Types you will see: created ready allowlist label resize reset restore rotate console engines engine_settings health_alert health_reset verify_ok verify_failed job_failed pg_database_created pg_database_dropped couch_database_created couch_database_deleted nats_stream_created nats_stream_purged nats_stream_deleted auth_user_created auth_user_invited auth_user_banned auth_user_unbanned auth_user_deleted auth_link_sent api_key_created api_key_revoked oauth_granted oauth_disconnected . New types appear as features do; ignore what you do not know.

## REST API

Base URL https://app.lathe.live/api/v1 · [interactive docs ](https://app.lathe.live/api/v1/docs)· [OpenAPI ](https://app.lathe.live/api/v1/openapi.json)

```
curl -H "Authorization: Bearer lathe_…" https://app.lathe.live/api/v1/instances
```

```
curl -H "Authorization: Bearer lathe_…" https://app.lathe.live/api/v1/instances/ID/connection
```

```
curl -X POST -H "Authorization: Bearer lathe_…" -H "Content-Type: application/json" \
  -d '{"tier": "starter", "name": "acme-prod", "tags": ["prod"]}' https://app.lathe.live/api/v1/instances
```

| Method and path | Purpose |
| --- | --- |
| `GET /me `· `PATCH /me ` | The account and its profile (what goes on receipts), and who is acting in it: a person's own account or an organization, with the caller's role. |
| `GET /plans `· `GET /locations ` | Plans, prices, hardware, locations. |
| `GET /instances `· `POST /instances ` | List; create. Free, where offered, starts without checkout or a card; a paid purchase returns `checkout_url `. |
| `GET /instances/{id} `· `PATCH `· `DELETE ?confirm= ` | Status, usage, monitoring, backups, activity; rename and retag; delete. |
| `GET /instances/{id}/connection ` | Connection strings, password included. |
| `GET /instances/{id}/backups ` | Daily backups and undo snapshots. |
| `PUT /instances/{id}/allowlist `· `PUT …/sql-console ` | IP allowlist; SQL console off / ro / rw. |
| `PUT /instances/{id}/engines ` | The engines on the box (any subset of Apps, Auth, Postgres, Redis, CouchDB, NATS and SeaweedFS) and their memory budgets; `GET /plans `lists each engine's floor, port, category and licence. |
| `POST /instances/{id}/actions/rotate | resize | reset | restore ` | Queue an operation; answers 202 with a job id. |
| `GET /jobs/{id} ` | A job's progress. |
| `GET /billing ` | Subscriptions and charges. |
| `GET /webhooks `· `POST /webhooks `· `PATCH /webhooks/{id} `· `DELETE /webhooks/{id} ` | List, create, update and remove signed webhook endpoints. |
| `GET /guides/apps ` | The apps-hosting contract as markdown, for a coding agent (also public at [/guides/apps ](https://docs.lathe.live/guides/apps)here). |

To start Free by API, send `{"tier": "free"} `to `POST /instances `. The response has `free: true `, `checkout_url: null `and an instance id to poll. It costs $0, needs no card and has 1000 GB outbound per month and no daily backups.

Errors are JSON: `{"detail": "…", "code": "…"} `. One job runs per instance at a time; a busy instance answers 409. Reset, restore and delete need `confirm `= the instance id. [Previous Plans, limits and policies ](https://docs.lathe.live/limits)[Next Lathe MCP server reference ](https://docs.lathe.live/mcp)

## Related

- [Deploy a Next.js guestbook ](https://docs.lathe.live/guestbook)

Deploy one Next.js guestbook with Postgres and Auth through the Lathe portal, REST API or MCP, then verify persistence.
- [App deployment tutorials ](https://docs.lathe.live/tutorials)

Deploy apps beside Postgres, connect GitHub, configure Auth, and run production workloads on Lathe step by step.
- [Host a container beside its Postgres, flat price ](https://docs.lathe.live/guides/host-your-app)

Put the image of your app on the dedicated machine that runs its database: deploy from a push, your domain, TLS, nothing metered. From $15 a month.
