Getting started by App
Each Vision App is its own service. It verifies Vision-issued tokens for its own audience, owns its own data, and has its own conventions while the platform is in preview. This page gives you, for each App, the first call and the differences that will otherwise cost you an afternoon.
On live Vision, CRM's origin answers from the internet (a token is required),
and the only App permission a key you make can hold is CRM's lead intake
(crm:intake:create; see Collect leads from your website). The
other App origins return 403 from the internet while their contracts are in
preview. Use this page to design and test against the preview environment; see
API availability.
At a glance
| CRM | To-Do | Calendar | Accounting | Directory | |
|---|---|---|---|---|---|
| Origin | crm.runonvision.com | todo.runonvision.com | calendar.runonvision.com | accounting.runonvision.com | directory.runonvision.com |
| Base path | /api/crm/v1 | /api/todo/v1 | /calendar/v1 | /apps/accounting/v1 | /api/v1 |
| Workspace ref format | lowercase slug | lowercase slug | CWS- + 12 | AWS- + 12 | DWS- + 12 |
| Page size (default / max) | 25 / 50 | 50 / 100 | 50 / 100 | 25 / 50 | 50 / 100 |
| Idempotency | body idempotencyKey | body idempotencyKey | Idempotency-Key header (required) | Idempotency-Key header (required) | Idempotency-Key header (optional) |
| Correlation header | X-Correlation-ID (UUID) | X-Correlation-ID (UUID) | X-Correlation-ID (UUID) | X-Request-ID (UUID) | X-Request-ID (UUID) |
| Machine writes | Lead intake only | No (reads only) | Call requests, actor bindings | No (reads only) | Yes, with a workspace grant |
| OpenAPI | CRM | To-Do | Calendar | Accounting | Directory |
The workspace reference is taken from your token (app_workspace_ref). You never send a workspace header.
CRM
People, organizations, opportunities, tasks and the intake review queue. Scopes are crm:<area>:read|write, for example crm:people:read. A service or agent client can read only the scopes the workspace has also granted to its machine actor.
List people
curl "https://crm.runonvision.com/api/crm/v1/people?limit=25" \
--header "authorization: Bearer $CRM_TOKEN" \
--header "x-correlation-id: $(uuidgen)"
- Pages: pass
cursorfrom the previous response'snextCursor;nullmeans done. - Unknown query parameters are rejected with
400. - Errors: flat envelope
{ schemaVersion: "vision-crm-error.v1", code, message, retryable, correlationId, fieldIssues }. - Replaying a command with the same
idempotencyKeyreturns200withreplayed: true.
To-Do
Tasks and lists. Scopes todo:tasks:read, todo:tasks:write (lists are read with todo:tasks:read). Machine clients can read; commands are made by people through Vision.
List open tasks
curl "https://todo.runonvision.com/api/todo/v1/tasks?limit=50" \
--header "authorization: Bearer $TODO_TOKEN"
- Mint the token with
resource=<To-Do audience>(the only App-audience token available today). - The cursor is tied to the
scopeand sort that produced it; keep them unchanged while paging. - Send
x-vision-time-zone: Europe/London(an IANA zone) to get due dates bucketed in that zone.
Calendar
Agenda, events, availability, holds and call requests. Scopes are calendar:<area>:read|write, for example calendar:agenda:read.
Read the agenda
curl "https://calendar.runonvision.com/calendar/v1/agenda?from=2026-11-02T00:00:00Z&to=2026-11-09T00:00:00Z&limit=50" \
--header "authorization: Bearer $CALENDAR_TOKEN"
fromandtoneed explicit offsets; the window is at most 93 days.- Every
*-commandsendpoint requires anIdempotency-Keyheader. - Two reads use
POSTbecause they take a body:/conflictsand/availability/slots. - Errors carry
conflict.intervalswhen a time clash is the cause.
Accounting
Invoices, counterparties, settings and imports. Scopes are accounting:<area>:read|write, for example accounting:invoices:read. Machine clients are read-only.
List overdue invoices
curl "https://accounting.runonvision.com/apps/accounting/v1/invoices?state=overdue&limit=25" \
--header "authorization: Bearer $ACCOUNTING_TOKEN" \
--header "x-request-id: $(uuidgen)"
- Errors are wrapped:
{ "error": { schemaVersion: "vision-accounting-error.v1", code, message, requestId, retryable, fieldIssues } }. - Commands require an
Idempotency-Keyheader (16 to 160 characters ofA-Z a-z 0-9 . _ : -).
Directory
The shared people and companies record that other Apps build on. Scopes directory:people:read|write, directory:companies:read|write. A service client may write the scopes its workspace grant allows.
Create a person
curl https://directory.runonvision.com/api/v1/people \
--request POST \
--header "authorization: Bearer $DIRECTORY_TOKEN" \
--header 'content-type: application/json' \
--header "idempotency-key: $(uuidgen)" \
--data '{"displayName":"Ada Lovelace"}'
- Follow changes without polling every record:
GET /api/v1/changes?since=<n>returnsitems,nextSinceandhasMore. - A replay with the same
Idempotency-Keyreturns the original status and body exactly; the same key with a different body is409 idempotency_conflict. - Errors are wrapped like Accounting's, with lowercase codes.