Authentication
The external API has exactly one credential: a workspace API key, sent as a bearer token on every request.
GET /external/v1/devices HTTP/1.1Host: api.canaro.caAuthorization: Bearer cnr_...The key is read from the Authorization header and nowhere else. It is never accepted in a query string or a cookie, so it cannot land in an access log or a browser history by accident.
What a key is
Section titled “What a key is”- A key belongs to the workspace, not to the person who created it. It keeps working if that person leaves the workspace.
- Keys begin with
cnr_. The dashboard shows the first twelve characters as a display handle so you can tell keys apart; the rest is stored only as a hash. - A key holds the scopes it was granted at creation and nothing else. A key can never create, list or revoke other keys — that is a dashboard action for a signed-in owner or admin.
- A key may carry an optional expiry. Once past it, the key is refused with
key_expired. - Revoking a key takes effect immediately. The record is kept for audit; the key is not.
Creating and managing keys
Section titled “Creating and managing keys”Keys are created in the Canaro dashboard under Settings → API, by a workspace owner or admin. The plaintext is returned once, in the creation response, and cannot be retrieved afterwards.
How many live keys a workspace may hold is set by its plan (max_api_keys on the account endpoint). Plans without API access have a limit of zero, and such a workspace cannot reach this API at all.
Server to server only
Section titled “Server to server only”This API deliberately sends no CORS headers. A browser cannot call it directly, and a key should never ship in client-side code. Call it from your own backend and expose whatever your front end needs from there.
Refusals before an endpoint is reached
Section titled “Refusals before an endpoint is reached”These are decided in order. Each is an error envelope with the code shown; see Errors for the shape.
| HTTP | code |
When |
|---|---|---|
| 401 | missing_credentials |
No Authorization: Bearer header. The response also carries WWW-Authenticate: Bearer. |
| 401 | invalid_key |
The token matches no key, or matches a revoked one. |
| 401 | key_expired |
The key’s expiry has passed. |
| 403 | tier_not_entitled |
The workspace’s plan includes no API access. |
| 403 | insufficient_scope |
The key is valid but does not hold the scope the endpoint requires. required_scope names it. |

