Orbit documentation

API

Everything the dashboard does goes through a REST API, which you can use for integrations.

  • Base path: /v1. Browsers use the dashboard's own /v1 proxy; servers can call the API directly (port 8000).
  • Interactive docs: GET /v1/docs (Swagger UI) and GET /v1/docs/openapi.json.
  • Health: GET /v1/status → {status:"ok"}; GET /v1/health; GET /ping → status, node and build.

Authentication

curl -s https://orbit.example.org/v1/auth/login \
  -H 'content-type: application/json' \
  -d '{"email":"integration@acme.test","password":"…","tenantKey":"acme"}'

The response contains accessToken and refreshToken. Send Authorization: Bearer <accessToken> on every call, and refresh with the refresh token before the access token expires (30 minutes by default). Accounts with two-step verification get a challenge instead; use a dedicated integration account.

Requests run with the account's role, sites and licenses, exactly like the dashboard.

Conventions

Topic Convention
Bodies JSON, camelCase
Single item {"data": {...}}
Lists {"items": [...], "page", "limit", "total", "totalPages"}
Errors {"error": "Short Title", "message": "Detail"} with 400, 401, 403, 404, 405, 409, 413, 422, 429 or 503
Paging page (from 1), limit (1–200, default 25)
Request IDs Send X-Request-ID or get one generated; it's echoed back and stored in the audit log

Generic resources

Most tenant data follows one pattern:

GET|POST           /v1/<resource>
GET|PATCH|DELETE   /v1/<resource>/<id>
GET|POST|PUT       /v1/<parent>/<parentId>/<child>
PATCH|DELETE       /v1/<parent>/<parentId>/<child>/<childId>
  • Filters: any query parameter named like a column filters by exact match; repeat it for IN. Many resources also accept search.
  • Sorting: orderBy=<column>&order=asc|desc.
  • Soft delete: deleted rows are hidden unless includeDeleted=true.
  • Create: unknown fields are rejected with 400; IDs and timestamps are filled in by the server.
  • Permissions: GET needs the resource's read permission, other methods its write permission, then the license check applies.

Examples: /v1/clients, /v1/cases, /v1/clients/<id>/notes, /v1/employers/<id>/contacts, /v1/job-postings/<id>/applications, /v1/definition-sets/<id>/definitions.

Useful dedicated endpoints

Endpoint Purpose
GET /v1/auth/me Who am I, tenant, sites, permissions
GET /v1/appointments/calendar?from&to Expanded occurrences
POST /v1/appointments/conflicts Dry-run conflict check
GET /v1/definition-lookup?sets=a,b Definition values by set code
POST /v1/file (multipart) Upload a document; GET /v1/file/<id> downloads
GET /v1/imports/supported-entities Import field registry
POST /v1/imports/run Run an import now (documentId + templateId, or targetEntity + mapping)
POST /v1/imports/upload (multipart) Queue an import for the worker
GET/POST /v1/import-templates Templates
POST /v1/forms/<id>/submissions Submit a form (answers keyed by field key)
POST /v1/reports/<id>/run, /export Reports
GET /v1/audit-logs Audit trail
GET/PUT /v1/settings/<category> Settings (general, terminology, notifications, scheduler, classification, documents)
/v1/<tenant>/public/… Unauthenticated portal endpoints (rate limited)

See /v1/docs for everything else.

Example: queue an import from a script

curl -s https://orbit.example.org/v1/imports/upload \
  -H "Authorization: Bearer $TOKEN" \
  -F file=@clients.csv \
  -F templateId=<template id>
# → a pending job; poll GET /v1/imports/<id> until completed, then GET /v1/imports/<id>/rows