API

Build on Canner.

Everything the dashboard and CLI do, your own code can do too. The Canner REST API is documented with an OpenAPI 3.1 spec and an interactive reference — manage projects, deployments, domains, databases, and billing from any language that can send an HTTP request.

GEThttps://api.canner.ca/v1

Authentication

Every request is authenticated with a Bearer token. Create one under Account → API tokens in the dashboard; it’s shown once and starts with cnr_. Send it in the Authorization header. The same session cookie the dashboard uses also works, so browser-side calls need no token.

curl https://api.canner.ca/v1/projects \
  -H "Authorization: Bearer cnr_your_token_here"

Versioning

The documented, stable surface is mounted under /v1. The older unversioned paths (no /v1 prefix) keep working as back-compat aliases for the dashboard and existing CLI, but new integrations should target /v1 — that’s what the OpenAPI spec describes.

Resources

Eight resource groups, 45 operations. Each is fully described — request bodies, responses, and error codes — in the interactive reference.

Projects10 endpoints

Create, list, configure, stop, and delete projects; manage the edge cache.

Deployments11 endpoints

Trigger, retry, cancel, and roll back builds; read metrics, logs, and screenshots.

Domains9 endpoints

Attach custom domains, verify DNS, search, and buy a domain through Canner.

Environment variables4 endpoints

Read, create, update, and delete per-environment secrets.

Billing4 endpoints

Read plan + trial state, capture a card, and manage the subscription.

Databases3 endpoints

Provision, inspect, and drop an isolated Postgres database per project.

API tokens3 endpoints

Mint, list, and revoke the cnr_ tokens that authenticate this API.

Uploads1 endpoint

Upload a .zip or .tar.gz of your source and enqueue a build.

Errors

Errors share one envelope: a stable machine-readable code, an optional human message, and a request_id you can quote to support. Validation failures (400) add an issues array of field-level problems.

{
  "error": "project_not_found",
  "message": "No project with that slug.",
  "request_id": "req_a1b2c3d4e5f6"
}

Rate limits

Authenticated requests are limited to 300/minute (30/minute unauthenticated). Every response carries the current budget so you can back off before you’re throttled:

X-RateLimit-LimitRequests allowed in the current window.X-RateLimit-RemainingRequests left before a 429.X-RateLimit-ResetUnix seconds until the window resets.Retry-AfterOn a 429, seconds to wait before retrying.

Pagination

List endpoints are keyset-paginated. Pass limit (1–100, default 50); the response includes a next_cursor. Pass it back as cursor for the next page. next_cursor is null on the last page. Omitting both returns the newest page, unchanged.

curl "https://api.canner.ca/v1/projects?limit=20" \
  -H "Authorization: Bearer cnr_your_token_here"
# → { "projects": [ ... ], "next_cursor": "MjAyNi0w..." }

Quick start

List your projects, then trigger a deployment — two requests, any HTTP client.

# List projects
curl https://api.canner.ca/v1/projects \
  -H "Authorization: Bearer $CANNER_TOKEN"

# Trigger a deployment
curl -X POST https://api.canner.ca/v1/projects/my-site/deploy \
  -H "Authorization: Bearer $CANNER_TOKEN"

Prefer a terminal?

The Canner CLI wraps this API for day-to-day work: canner login stores a token, canner deploy --follow ships a directory and streams the build log. It’s the same endpoints under the hood.

Read the CLI guide →

Building an AI agent? The llms.txt file describes Canner for language models, and the OpenAPI spec above is ready for codegen and tool definitions.