# Developers: API & API keys

> SUBLAKE Docs · Developers · https://sublake.com/docs/developers

SUBLAKE has a REST API for your own software, signed webhooks for everything that happens, and an MCP server for AI assistants. Everything is in **Settings → Developers** (business owner only).

## Base URL

```
https://backend.sublake.com/api/public/v1
```

The full description is at `https://backend.sublake.com/api/public/v1/openapi.json` (OpenAPI 3.1 — import it into Postman or any client generator).

## API keys

Create a key in **Settings → Developers → API keys**: name it and choose what it may do (its scopes). The key (`sk_live_…`) is shown once — store it in a secret manager. You can **roll** a key (the old one keeps working for the time you choose, so nothing breaks while you swap it) or **revoke** it at once.

```
curl https://backend.sublake.com/api/public/v1/me \
  -H "Authorization: Bearer sk_live_…"
```

`GET /me` answers your business's name and the key's scopes.

## Scopes

- `customers:read` — see your customers · `customers:write` — add and update them
- `requests:read` — see your requests · `requests:write` — add requests
- `quotes:read`, `jobs:read`, `visits:read`, `invoices:read`, `payments:read` — see those records
- `webhooks` — be told when something happens

## What you can read and write

- `GET /customers`, `/requests`, `/quotes`, `/jobs`, `/visits`, `/invoices`, `/payments` — a page of records, newest first — and `GET /<records>/{id}` for one
- `GET /customers/find?email=…` or `?phone=…` — the customer with that email or phone
- `POST /customers` — add a customer (refused, naming the existing one, when the email or phone is already on file) · `PATCH /customers/{id}` — change one
- `POST /requests` — file a request for work, numbered and marked as made by your app
- `GET /events` — what happened, read after the fact ([Webhooks](https://sublake.com/docs/webhooks))

Money is in integer cents and times are ISO 8601 UTC.

## Paging and filters

Lists take `limit` (1–100, default 25) and `starting_after` (the id of the last record you have), and answer `has_more` and `next_starting_after`. Most lists filter by `created_after`, `created_before`, `updated_after`, and by their customer, job or status — the OpenAPI description lists each one.

## Retrying writes safely

Send an `Idempotency-Key` header with any write. Sent again within 24 hours with the same key, the first answer is given again and nothing is done twice.

## Errors and limits

Errors are JSON: `{"error": {"type", "code", "message", "param"}}`, with an HTTP status that matches the type (400, 401, 403, 404, 409, 429). Every answer carries `RateLimit-Policy` and `RateLimit` headers; past the limit you get `429` with `Retry-After`.

## Apps that act for other businesses (OAuth)

An app used by many SUBLAKE businesses signs each one in with OAuth 2.1: authorization code with PKCE (S256), at `https://backend.sublake.com/oauth/authorize` and `/oauth/token`, with discovery at `/.well-known/oauth-authorization-server` and client registration at `/oauth/register`. The owner sees your app's name and exactly what it asks for, and can disconnect it any time.
