API Reference

Everything deplo.ai does — syncing repositories, starting deployments, streaming status, monitoring live apps — is exposed as a versioned REST API. The browser dashboard and the deplo CLI are both clients of the exact same endpoints documented here.

Base URL#

base url
https://www.deplo.in/api/v1

The version is part of the path (/api/v1). Breaking changes ship as a new version segment; v1 is the current and only version. Requests to www.deplo.in are proxied same-origin to the backend, which is how the browser dashboard talks to this API without CORS — your integration hits the same URL.

Authentication#

Every authenticated endpoint accepts a bearer token in the Authorization header. Two token types work interchangeably on every route:

TokenFormatIntended for
CLI tokendpl_…API consumers, the CLI, and CI. Long-lived and revocable — create one in Settings → CLI Tokens.
JWTeyJ…The browser dashboard. Issued by GitHub OAuth sign-in, expires after 7 days.

If you are scripting against the API, use a CLI token — JWTs are session tokens for the dashboard. Your first request:

request
curl https://www.deplo.in/api/v1/auth/me \
  -H "Authorization: Bearer $DEPLO_TOKEN"
response · 200
{
  "userId": "cm5xa1b2c0001njk8w9d2f3g4",
  "email": "ada@example.com",
  "name": "Ada Lovelace",
  "githubLogin": "adalovelace",
  "avatarUrl": "https://avatars.githubusercontent.com/u/9919?v=4"
}

See Authentication for the OAuth endpoints and CLI Tokens for token management.

Errors#

Errors return a JSON envelope with a machine-readable code and a human-readable message:

error · 404
{
  "error": {
    "code": "NOT_FOUND",
    "message": "Deployment not found"
  }
}

Request-body validation failures (400) additionally include a details object with per-field issues, and a few inline guard errors return only message. Always branch on the HTTP status first, then on error.code when present.

StatusCodeMeaning
200 / 201 / 204Success. 201 on resource creation, 204 on deletion with no body.
400VALIDATION_ERRORMalformed request body or parameters.
401UNAUTHORIZEDMissing, malformed, expired, or revoked bearer token.
403FORBIDDENAuthenticated, but the resource belongs to another user.
404NOT_FOUNDResource does not exist (or is not visible to you).
409CONFLICTThe operation conflicts with current state (e.g. cancelling a completed deployment).
429Rate limit exceeded. Back off and retry after the window resets.
500INTERNAL_ERRORUnexpected server error.
502EXTERNAL_SERVICE_ERRORAn upstream provider (GitHub, Vercel, Render) failed.

Rate limits#

The API allows 200 requests per 15 minutes per IP across all endpoints. Standard RateLimit-* response headers report your limit, remaining budget, and reset time. Exceeding the limit returns 429. Polling a deployment every 2–3 seconds fits comfortably within the budget.

Health#

Service health probe. Returns 200 when the database and Redis are reachable, 503 when degraded. No authentication required.

request
curl https://www.deplo.in/api/v1/health
response · 200
{
  "status": "healthy",
  "version": "v1",
  "environment": "production",
  "checks": {
    "database": "ok",
    "redis": "ok"
  },
  "timestamp": "2026-08-07T09:15:04.512Z"
}

System endpoints#

A few routes exist for machines, not API consumers: POST /webhooks/github and POST /webhooks/vercel receive signed provider webhooks, and GET /integrations/vercel/callback completes the browser-driven Vercel OAuth flow. They validate their own signatures or state tokens and are not meant to be called directly.

Note
Public (unauthenticated) routes are /health, the GitHub OAuth pair under /auth, and the analytics beacon under /public. Everything else requires a bearer token.

Resources#