Skip to content

API reference

Everything the dashboard does, you can do over the REST API — with scoped API keys (Settings) or the typed @canvasrelay/api-client package. Machine-readable spec: GET /api/v1/openapi.json on the API origin.

Authenticating

Create a scoped key under Settings → API keys and send it as a Bearer token. Keys are shown once (only the hash is stored) and can carry read/write scopes per resource — mint the narrowest key that does the job.

curl https://api.canvasrelay.app/api/v1/boards \
  -H "Authorization: Bearer crk_…"

Errors come back as a JSON envelope with a stable CR-xxxx code, a message, and an HTTP status. Rate limits are per-IP for anonymous routes and per-workspace for authed ones (CR-1006, 429).

The public board feed — what players poll — needs no auth: GET /api/v1/feed/{board-slug} with ETag revalidation.

auth

POST/api/v1/auth/signup
POST/api/v1/auth/verify-email
POST/api/v1/auth/login
POST/api/v1/auth/logout
POST/api/v1/auth/password/forgot
POST/api/v1/auth/password/reset
POST/api/v1/auth/password/change
GET/api/v1/auth/me
GET/api/v1/auth/sessions
DELETE/api/v1/auth/sessions/{id}
GET/api/v1/auth/oauth/google
GET/api/v1/auth/oauth/google/callback
DELETE/api/v1/auth/oauth/google
DELETE/api/v1/auth/account

orgs

GET/api/v1/orgs
POST/api/v1/orgs
GET/api/v1/orgs/current
PATCH/api/v1/orgs/current
GET/api/v1/orgs/{orgId}/export
GET/api/v1/orgs/{orgId}/export/{jobId}
GET/api/v1/export/jobs/{jobId}/download
GET/api/v1/export/media/{mediaId}
POST/api/v1/orgs/{orgId}/deletion
DELETE/api/v1/orgs/{orgId}/deletion
GET/api/v1/orgs/{orgId}/members
PATCH/api/v1/orgs/{orgId}/members/{userId}
DELETE/api/v1/orgs/{orgId}/members/{userId}
GET/api/v1/orgs/{orgId}/invitations
POST/api/v1/orgs/{orgId}/invitations
POST/api/v1/orgs/{orgId}/invitations/{invitationId}/resend
DELETE/api/v1/orgs/{orgId}/invitations/{invitationId}
POST/api/v1/invitations/accept
GET/api/v1/invitations/{token}

billing

GET/api/v1/billing/entitlements
POST/api/v1/billing/checkout
POST/api/v1/billing/subscription
POST/api/v1/billing/credits/checkout
POST/api/v1/billing/credits/claim
POST/api/v1/billing/portal
POST/api/v1/billing/webhook

boards

GET/api/v1/boards
POST/api/v1/boards
GET/api/v1/boards/{id}
PATCH/api/v1/boards/{id}
DELETE/api/v1/boards/{id}
POST/api/v1/boards/{id}/publish
GET/api/v1/boards/{id}/releases
GET/api/v1/boards/{id}/playback
POST/api/v1/boards/{id}/rollback
POST/api/v1/boards/{id}/duplicate
POST/api/v1/boards/{id}/test-session
GET/api/v1/boards/{boardId}/menus
GET/api/v1/boards/{boardId}/scenes
POST/api/v1/boards/{boardId}/scenes/reorder
GET/api/v1/boards/{boardId}/schedules
GET/api/v1/boards/{boardId}/takeovers

scenes

POST/api/v1/scenes
GET/api/v1/scenes/{id}
PATCH/api/v1/scenes/{id}
DELETE/api/v1/scenes/{id}
GET/api/v1/scenes/{id}/elements
PUT/api/v1/scenes/{id}/elements
GET/api/v1/scenes/{id}/draft
PUT/api/v1/scenes/{id}/draft

schedules

POST/api/v1/schedules
PUT/api/v1/schedules/{id}
POST/api/v1/schedules/{id}/activate
DELETE/api/v1/schedules/{id}

media

GET/api/v1/media
POST/api/v1/media
PATCH/api/v1/media/{id}
DELETE/api/v1/media/{id}
PUT/api/v1/media/{id}/blob
GET/api/v1/media/{id}/blob
GET/api/v1/media/{id}/access
GET/api/v1/media/{id}/usage
POST/api/v1/media/tags

fonts

GET/api/v1/fonts
POST/api/v1/fonts
DELETE/api/v1/fonts/{id}

templates

GET/api/v1/templates
GET/api/v1/templates/{id}
POST/api/v1/templates
DELETE/api/v1/templates/{id}

takeovers

GET/api/v1/takeovers
POST/api/v1/takeovers
DELETE/api/v1/takeovers/{id}

devices

DELETE/api/v1/devices/self
GET/api/v1/devices/self/boards
POST/api/v1/devices/self/board
GET/api/v1/devices
GET/api/v1/devices/{id}
PATCH/api/v1/devices/{id}
DELETE/api/v1/devices/{id}
DELETE/api/v1/devices/{id}/purge
POST/api/v1/devices/{id}/screenshots
GET/api/v1/devices/{id}/screenshots/{screenshotId}/blob
PUT/api/v1/devices/screenshots/{id}/blob
POST/api/v1/devices/{id}/commands
GET/api/v1/devices/{id}/commands
POST/api/v1/devices/{id}/release
GET/api/v1/devices/{id}/render
POST/api/v1/devices/pair/start
POST/api/v1/devices/pair/claim
GET/api/v1/devices/pair/poll
POST/api/v1/devices/heartbeat
POST/api/v1/devices/playback
POST/api/v1/devices/token
POST/api/v1/devices/commands/{id}/ack

feed

GET/api/v1/feed/{slug}

widget data

GET/api/v1/widget-data/{kind}

assist

POST/api/v1/assist/layout
POST/api/v1/assist/general-screen
POST/api/v1/assist/copy
POST/api/v1/assist/bulk
POST/api/v1/assist/import-menu
POST/api/v1/assist/menu-plan
POST/api/v1/assist/image
POST/api/v1/assist/image-edit
POST/api/v1/assist/slideshow
POST/api/v1/assist/slideshow/{id}/accept
POST/api/v1/assist/scene-edit
GET/api/v1/assist/credits
POST/api/v1/assist/import-menu/{id}/accept

ai

GET/api/v1/ai/jobs
GET/api/v1/ai/jobs/{id}
GET/api/v1/ai/consent
POST/api/v1/ai/consent
DELETE/api/v1/ai/consent
GET/api/v1/ai/reports
POST/api/v1/ai/reports

proposals

GET/api/v1/proposals
POST/api/v1/proposals
POST/api/v1/proposals/{id}/apply
POST/api/v1/proposals/{id}/approve
POST/api/v1/proposals/{id}/reject

keys

GET/api/v1/keys
POST/api/v1/keys
DELETE/api/v1/keys/{id}

events

GET/api/v1/events

email

GET/api/v1/email/unsubscribe

test session

GET/api/v1/test-session/{token}

tools

POST/api/v1/tools/menu-photo-preview

health

GET/api/v1/health

networks

GET/api/v1/networks
POST/api/v1/networks
GET/api/v1/networks/{networkId}
PATCH/api/v1/networks/{networkId}
GET/api/v1/networks/{networkId}/overview
GET/api/v1/networks/{networkId}/organizations
POST/api/v1/networks/{networkId}/organizations
PATCH/api/v1/networks/{networkId}/organizations/{organizationId}
DELETE/api/v1/networks/{networkId}/organizations/{organizationId}
GET/api/v1/networks/{networkId}/screens
GET/api/v1/networks/{networkId}/operators
POST/api/v1/networks/{networkId}/operators
PATCH/api/v1/networks/{networkId}/operators/{userId}
GET/api/v1/networks/{networkId}/branding
PUT/api/v1/networks/{networkId}/branding
GET/api/v1/networks/{networkId}/hostnames
POST/api/v1/networks/{networkId}/hostnames
GET/api/v1/networks/{networkId}/delegated-sessions
POST/api/v1/networks/{networkId}/delegated-sessions
DELETE/api/v1/networks/{networkId}/delegated-sessions/{sessionId}
GET/api/v1/networks/{networkId}/events
GET/api/v1/networks/{networkId}/templates
POST/api/v1/networks/{networkId}/templates
GET/api/v1/networks/{networkId}/templates/{templateId}/versions
POST/api/v1/networks/{networkId}/templates/{templateId}/versions
PATCH/api/v1/networks/{networkId}/templates/{templateId}/versions/{versionId}
GET/api/v1/networks/{networkId}/campaigns
POST/api/v1/networks/{networkId}/campaigns
PATCH/api/v1/networks/{networkId}/campaigns/{campaignId}
POST/api/v1/networks/{networkId}/campaigns/{campaignId}/materialize
GET/api/v1/networks/{networkId}/campaigns/{campaignId}/deployments
POST/api/v1/networks/{networkId}/campaigns/{campaignId}/withdraw
POST/api/v1/networks/{networkId}/campaigns/{campaignId}/deployments/{deploymentId}/rollback
GET/api/v1/networks/{networkId}/campaigns/{campaignId}/proof

network campaigns

GET/api/v1/network-campaigns
PATCH/api/v1/network-campaigns/{deploymentId}/overrides
POST/api/v1/network-campaigns/{deploymentId}/install
POST/api/v1/network-campaigns/{deploymentId}/decline

portal

GET/api/v1/portal/config

notifications

GET/api/v1/notifications/preferences
PUT/api/v1/notifications/preferences
GET/api/v1/notifications/inbox
PATCH/api/v1/notifications/inbox/{id}
POST/api/v1/notifications/test

mobile

GET/api/v1/mobile/push/subscriptions
POST/api/v1/mobile/push/subscriptions
DELETE/api/v1/mobile/push/subscriptions
POST/api/v1/mobile/push/publish-failure

pi

POST/api/v1/pi/auth/login
POST/api/v1/pi/auth/logout
POST/api/v1/pi/auth/select-org
GET/api/v1/pi/session
POST/api/v1/pi/device/register

relay

GET/api/v1/relay/{slug}

integrations

GET/api/v1/integrations/google
POST/api/v1/integrations/google/{product}/connect
GET/api/v1/integrations/google/callback
GET/api/v1/integrations/google/calendar/calendars
GET/api/v1/integrations/google/business-profile/locations
DELETE/api/v1/integrations/google/{product}
GET/api/v1/integrations/http-connectors
POST/api/v1/integrations/http-connectors
PATCH/api/v1/integrations/http-connectors/{id}
DELETE/api/v1/integrations/http-connectors/{id}
POST/api/v1/integrations/http-connectors/{id}/test
GET/api/v1/integrations/openligadb/leagues

device board-schedules

GET/api/v1/device-board-schedules
POST/api/v1/device-board-schedules
PUT/api/v1/device-board-schedules/{id}
DELETE/api/v1/device-board-schedules/{id}

device board-schedule-pauses

PUT/api/v1/device-board-schedule-pauses

releases

POST/api/v1/releases/{id}/assign

webhooks

GET/api/v1/webhooks
POST/api/v1/webhooks
DELETE/api/v1/webhooks/{id}
POST/api/v1/webhooks/{id}/test

brand kit

GET/api/v1/brand-kit
PUT/api/v1/brand-kit

openapi.json

GET/api/v1/openapi.json

support

POST/api/v1/support/ask

roku

POST/api/v1/roku/auth/login
POST/api/v1/roku/auth/signup
POST/api/v1/roku/auth/select-org
GET/api/v1/roku/session
POST/api/v1/roku/auth/logout
POST/api/v1/roku/device/register
GET/api/v1/roku/catalog
POST/api/v1/roku/purchases/validate
POST/api/v1/roku/pay/push