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/signupPOST
/api/v1/auth/verify-emailPOST
/api/v1/auth/loginPOST
/api/v1/auth/logoutPOST
/api/v1/auth/password/forgotPOST
/api/v1/auth/password/resetPOST
/api/v1/auth/password/changeGET
/api/v1/auth/meGET
/api/v1/auth/sessionsDELETE
/api/v1/auth/sessions/{id}GET
/api/v1/auth/oauth/googleGET
/api/v1/auth/oauth/google/callbackDELETE
/api/v1/auth/oauth/googleDELETE
/api/v1/auth/accountorgs
GET
/api/v1/orgsPOST
/api/v1/orgsGET
/api/v1/orgs/currentPATCH
/api/v1/orgs/currentGET
/api/v1/orgs/{orgId}/exportGET
/api/v1/orgs/{orgId}/export/{jobId}GET
/api/v1/export/jobs/{jobId}/downloadGET
/api/v1/export/media/{mediaId}POST
/api/v1/orgs/{orgId}/deletionDELETE
/api/v1/orgs/{orgId}/deletionGET
/api/v1/orgs/{orgId}/membersPATCH
/api/v1/orgs/{orgId}/members/{userId}DELETE
/api/v1/orgs/{orgId}/members/{userId}GET
/api/v1/orgs/{orgId}/invitationsPOST
/api/v1/orgs/{orgId}/invitationsPOST
/api/v1/orgs/{orgId}/invitations/{invitationId}/resendDELETE
/api/v1/orgs/{orgId}/invitations/{invitationId}POST
/api/v1/invitations/acceptGET
/api/v1/invitations/{token}billing
GET
/api/v1/billing/entitlementsPOST
/api/v1/billing/checkoutPOST
/api/v1/billing/subscriptionPOST
/api/v1/billing/credits/checkoutPOST
/api/v1/billing/credits/claimPOST
/api/v1/billing/portalPOST
/api/v1/billing/webhookboards
GET
/api/v1/boardsPOST
/api/v1/boardsGET
/api/v1/boards/{id}PATCH
/api/v1/boards/{id}DELETE
/api/v1/boards/{id}POST
/api/v1/boards/{id}/publishGET
/api/v1/boards/{id}/releasesGET
/api/v1/boards/{id}/playbackPOST
/api/v1/boards/{id}/rollbackPOST
/api/v1/boards/{id}/duplicatePOST
/api/v1/boards/{id}/test-sessionGET
/api/v1/boards/{boardId}/menusGET
/api/v1/boards/{boardId}/scenesPOST
/api/v1/boards/{boardId}/scenes/reorderGET
/api/v1/boards/{boardId}/schedulesGET
/api/v1/boards/{boardId}/takeoversscenes
POST
/api/v1/scenesGET
/api/v1/scenes/{id}PATCH
/api/v1/scenes/{id}DELETE
/api/v1/scenes/{id}GET
/api/v1/scenes/{id}/elementsPUT
/api/v1/scenes/{id}/elementsGET
/api/v1/scenes/{id}/draftPUT
/api/v1/scenes/{id}/draftschedules
POST
/api/v1/schedulesPUT
/api/v1/schedules/{id}POST
/api/v1/schedules/{id}/activateDELETE
/api/v1/schedules/{id}media
GET
/api/v1/mediaPOST
/api/v1/mediaPATCH
/api/v1/media/{id}DELETE
/api/v1/media/{id}PUT
/api/v1/media/{id}/blobGET
/api/v1/media/{id}/blobGET
/api/v1/media/{id}/accessGET
/api/v1/media/{id}/usagePOST
/api/v1/media/tagsfonts
GET
/api/v1/fontsPOST
/api/v1/fontsDELETE
/api/v1/fonts/{id}templates
GET
/api/v1/templatesGET
/api/v1/templates/{id}POST
/api/v1/templatesDELETE
/api/v1/templates/{id}takeovers
GET
/api/v1/takeoversPOST
/api/v1/takeoversDELETE
/api/v1/takeovers/{id}devices
DELETE
/api/v1/devices/selfGET
/api/v1/devices/self/boardsPOST
/api/v1/devices/self/boardGET
/api/v1/devicesGET
/api/v1/devices/{id}PATCH
/api/v1/devices/{id}DELETE
/api/v1/devices/{id}DELETE
/api/v1/devices/{id}/purgePOST
/api/v1/devices/{id}/screenshotsGET
/api/v1/devices/{id}/screenshots/{screenshotId}/blobPUT
/api/v1/devices/screenshots/{id}/blobPOST
/api/v1/devices/{id}/commandsGET
/api/v1/devices/{id}/commandsPOST
/api/v1/devices/{id}/releaseGET
/api/v1/devices/{id}/renderPOST
/api/v1/devices/pair/startPOST
/api/v1/devices/pair/claimGET
/api/v1/devices/pair/pollPOST
/api/v1/devices/heartbeatPOST
/api/v1/devices/playbackPOST
/api/v1/devices/tokenPOST
/api/v1/devices/commands/{id}/ackfeed
GET
/api/v1/feed/{slug}widget data
GET
/api/v1/widget-data/{kind}assist
POST
/api/v1/assist/layoutPOST
/api/v1/assist/general-screenPOST
/api/v1/assist/copyPOST
/api/v1/assist/bulkPOST
/api/v1/assist/import-menuPOST
/api/v1/assist/menu-planPOST
/api/v1/assist/imagePOST
/api/v1/assist/image-editPOST
/api/v1/assist/slideshowPOST
/api/v1/assist/slideshow/{id}/acceptPOST
/api/v1/assist/scene-editGET
/api/v1/assist/creditsPOST
/api/v1/assist/import-menu/{id}/acceptai
GET
/api/v1/ai/jobsGET
/api/v1/ai/jobs/{id}GET
/api/v1/ai/consentPOST
/api/v1/ai/consentDELETE
/api/v1/ai/consentGET
/api/v1/ai/reportsPOST
/api/v1/ai/reportsproposals
GET
/api/v1/proposalsPOST
/api/v1/proposalsPOST
/api/v1/proposals/{id}/applyPOST
/api/v1/proposals/{id}/approvePOST
/api/v1/proposals/{id}/rejectkeys
GET
/api/v1/keysPOST
/api/v1/keysDELETE
/api/v1/keys/{id}events
GET
/api/v1/eventsGET
/api/v1/email/unsubscribetest session
GET
/api/v1/test-session/{token}tools
POST
/api/v1/tools/menu-photo-previewhealth
GET
/api/v1/healthnetworks
GET
/api/v1/networksPOST
/api/v1/networksGET
/api/v1/networks/{networkId}PATCH
/api/v1/networks/{networkId}GET
/api/v1/networks/{networkId}/overviewGET
/api/v1/networks/{networkId}/organizationsPOST
/api/v1/networks/{networkId}/organizationsPATCH
/api/v1/networks/{networkId}/organizations/{organizationId}DELETE
/api/v1/networks/{networkId}/organizations/{organizationId}GET
/api/v1/networks/{networkId}/screensGET
/api/v1/networks/{networkId}/operatorsPOST
/api/v1/networks/{networkId}/operatorsPATCH
/api/v1/networks/{networkId}/operators/{userId}GET
/api/v1/networks/{networkId}/brandingPUT
/api/v1/networks/{networkId}/brandingGET
/api/v1/networks/{networkId}/hostnamesPOST
/api/v1/networks/{networkId}/hostnamesGET
/api/v1/networks/{networkId}/delegated-sessionsPOST
/api/v1/networks/{networkId}/delegated-sessionsDELETE
/api/v1/networks/{networkId}/delegated-sessions/{sessionId}GET
/api/v1/networks/{networkId}/eventsGET
/api/v1/networks/{networkId}/templatesPOST
/api/v1/networks/{networkId}/templatesGET
/api/v1/networks/{networkId}/templates/{templateId}/versionsPOST
/api/v1/networks/{networkId}/templates/{templateId}/versionsPATCH
/api/v1/networks/{networkId}/templates/{templateId}/versions/{versionId}GET
/api/v1/networks/{networkId}/campaignsPOST
/api/v1/networks/{networkId}/campaignsPATCH
/api/v1/networks/{networkId}/campaigns/{campaignId}POST
/api/v1/networks/{networkId}/campaigns/{campaignId}/materializeGET
/api/v1/networks/{networkId}/campaigns/{campaignId}/deploymentsPOST
/api/v1/networks/{networkId}/campaigns/{campaignId}/withdrawPOST
/api/v1/networks/{networkId}/campaigns/{campaignId}/deployments/{deploymentId}/rollbackGET
/api/v1/networks/{networkId}/campaigns/{campaignId}/proofnetwork campaigns
GET
/api/v1/network-campaignsPATCH
/api/v1/network-campaigns/{deploymentId}/overridesPOST
/api/v1/network-campaigns/{deploymentId}/installPOST
/api/v1/network-campaigns/{deploymentId}/declineportal
GET
/api/v1/portal/confignotifications
GET
/api/v1/notifications/preferencesPUT
/api/v1/notifications/preferencesGET
/api/v1/notifications/inboxPATCH
/api/v1/notifications/inbox/{id}POST
/api/v1/notifications/testmobile
GET
/api/v1/mobile/push/subscriptionsPOST
/api/v1/mobile/push/subscriptionsDELETE
/api/v1/mobile/push/subscriptionsPOST
/api/v1/mobile/push/publish-failurepi
POST
/api/v1/pi/auth/loginPOST
/api/v1/pi/auth/logoutPOST
/api/v1/pi/auth/select-orgGET
/api/v1/pi/sessionPOST
/api/v1/pi/device/registerrelay
GET
/api/v1/relay/{slug}integrations
GET
/api/v1/integrations/googlePOST
/api/v1/integrations/google/{product}/connectGET
/api/v1/integrations/google/callbackGET
/api/v1/integrations/google/calendar/calendarsGET
/api/v1/integrations/google/business-profile/locationsDELETE
/api/v1/integrations/google/{product}GET
/api/v1/integrations/http-connectorsPOST
/api/v1/integrations/http-connectorsPATCH
/api/v1/integrations/http-connectors/{id}DELETE
/api/v1/integrations/http-connectors/{id}POST
/api/v1/integrations/http-connectors/{id}/testGET
/api/v1/integrations/openligadb/leaguesdevice board-schedules
GET
/api/v1/device-board-schedulesPOST
/api/v1/device-board-schedulesPUT
/api/v1/device-board-schedules/{id}DELETE
/api/v1/device-board-schedules/{id}device board-schedule-pauses
PUT
/api/v1/device-board-schedule-pausesreleases
POST
/api/v1/releases/{id}/assignwebhooks
GET
/api/v1/webhooksPOST
/api/v1/webhooksDELETE
/api/v1/webhooks/{id}POST
/api/v1/webhooks/{id}/testbrand kit
GET
/api/v1/brand-kitPUT
/api/v1/brand-kitopenapi.json
GET
/api/v1/openapi.jsonsupport
POST
/api/v1/support/askroku
POST
/api/v1/roku/auth/loginPOST
/api/v1/roku/auth/signupPOST
/api/v1/roku/auth/select-orgGET
/api/v1/roku/sessionPOST
/api/v1/roku/auth/logoutPOST
/api/v1/roku/device/registerGET
/api/v1/roku/catalogPOST
/api/v1/roku/purchases/validatePOST
/api/v1/roku/pay/push