Use an API key
Create a long-lived key, send it in x-access-key, and know exactly which endpoints each scope opens.
An API key authenticates a script or service as you, without a password and
without a token that expires every few days. Unlike the JWT from
POST /v2/auth/login, a key carries only the access you grant it: a set of
scopes, and a set of projects.
Reach for a key when something runs unattended — a cron job, a CI step, an integration. For a person signing in, keep using the JWT.
Create a key
Keys are managed on the API keys page. Creating one takes four steps: a name, an expiry, the projects it may reach, and the scopes it is granted.
Evercam shows the key once, at creation, and stores only a hash of it. There is no way to read it back — if you lose it, regenerate, which invalidates the old value.
Send it
A key goes in the x-access-key header. Not Authorization: Bearer, which is
for the JWT, and not x-api-key, which is a different header on the AI API.
curl "https://api-keys.staging.media.evercam.io/v2/projects" \
-H "x-access-key: $EVERCAM_API_KEY"Two gates, not one
Every request with a key passes two independent checks:
- Scopes — what it may do. The endpoint declares the scopes that reach it;
the key must hold at least one of them. Missing it returns
403withINSUFFICIENT_SCOPE. - Projects — where it may do it. The key lists the projects it can touch.
A camera or project outside that list returns
403, and list endpoints come back filtered to the key's own projects rather than erroring.
Both fail closed: an endpoint that declares no scopes at all is refused, and a key with an empty project list reaches nothing.
A key can never exceed you. Access is the key's scopes and your own
permissions on the project — granting project:settings to a key does not give
it settings access on a project where you are only a viewer.
What each scope unlocks
Scopes are grouped the same way the key editor groups them.
User
| Scope | Opens |
|---|---|
user:info | Your profile, roles, permissions, sessions and notifications |
profile:write | Updating your profile, marking notifications read, revoking your own sessions |
user:info
GET /v2/users/{id}
GET /v2/users/{email}/features
GET /v2/users/permissions
GET /v2/users/roles
GET /v2/users/active-sessions
GET /v2/users/session/activities
GET /v2/notifications
GET /v2/auth/options
GET /v2/auth/signup_options
GET /v2/auth/provider/{provider}
GET /v2/oauth2-tokens/providers
profile:write
PATCH /v2/users/{id}
DELETE /v2/users/active-sessions/{id}
PATCH /v2/notifications/{id}
POST /v2/notifications/mark-as-readProjects and cameras
| Scope | Opens |
|---|---|
projects:read | Projects, their contacts and battery readings, progress photos |
cameras:read | Cameras, their health, battery and last public note |
GET /v2/cameras and GET /v2/projects/{exid}/cameras accept either scope —
they are the one place the two overlap.
projects:read
GET /v2/projects
POST /v2/projects
GET /v2/projects/{exid}
GET /v2/projects/{exid}/cameras
GET /v2/projects/{exid}/contacts
GET /v2/projects/{exid}/camera_refs
GET /v2/projects/{exid}/battery-readings
GET /v2/projects/{exid}/progress-photos
GET /v2/cameras
GET /v2/progress-photos/{id}
POST /v2/progress-photos
PATCH /v2/progress-photos/{id}
DELETE /v2/progress-photos/{id}
cameras:read
GET /v2/cameras
GET /v2/cameras/{camera_exid}
GET /v2/cameras/{camera_exid}/health
GET /v2/cameras/{camera_exid}/last-public-note
GET /v2/cameras/{camera_exid}/battery-readings
GET /v2/cameras/{camera_exid}/battery-readings/voltage-summary
GET /v2/projects/{exid}/camerasCamera features
| Scope | Opens |
|---|---|
camera:live_view | Live snapshots, HLS and RTMP stream details, ONVIF calls |
camera:recordings | Stored snapshots, the days/hours index, thumbnails, ANPR events |
camera:ptz | Every pan/tilt/zoom control and preset |
camera:live_view
GET /v2/cameras/{camera_exid}/live/snapshot
GET /v2/cameras/{camera_exid}/live/snapshot.jpg
GET /v2/cameras/{camera_exid}/hls
GET /v2/cameras/{camera_exid}/streaming
GET /v2/onvif/v20/{service}/{operation}
camera:recordings
GET /v2/cameras/{camera_exid}/thumbnail
GET /v2/cameras/{camera_exid}/recordings/snapshots
GET /v2/cameras/{camera_exid}/recordings/snapshots/latest
GET /v2/cameras/{camera_exid}/recordings/snapshots/oldest
GET /v2/cameras/{camera_exid}/recordings/snapshots/{timestamp}
GET /v2/cameras/{camera_exid}/recordings/snapshots/{timestamp}/nearest
GET /v2/cameras/{camera_exid}/recordings/snapshots/{year}/{month}/days
GET /v2/cameras/{camera_exid}/recordings/snapshots/{year}/{month}/{day}/hours
POST /v2/cameras/{camera_exid}/snapshots
GET /v2/cameras/{camera_exid}/anpr (+ /matched, /plates, /{eventid})
camera:ptz
GET /v2/cameras/{camera_exid}/ptz/status
GET /v2/cameras/{camera_exid}/ptz/presets
GET /v2/cameras/{camera_exid}/ptz/nodes
GET /v2/cameras/{camera_exid}/ptz/configurations
POST /v2/cameras/{camera_exid}/ptz/home (+ /home/set)
POST /v2/cameras/{camera_exid}/ptz/relative
POST /v2/cameras/{camera_exid}/ptz/continuous/start/{direction}
POST /v2/cameras/{camera_exid}/ptz/continuous/stop
POST /v2/cameras/{camera_exid}/ptz/continuous/zoom/{mode}
POST /v2/cameras/{camera_exid}/ptz/presets/create
POST /v2/cameras/{camera_exid}/ptz/presets/go/{preset_token}
POST /v2/cameras/{camera_exid}/ptz/presets/{preset_token}/set
DELETE /v2/cameras/{camera_exid}/ptz/presets/{preset_token}/removeProject features
| Scope | Opens | Endpoints |
|---|---|---|
project:media_hub | Media hub items, compares and timelapses | 18, under /v2/projects/{exid}/media-hub and /v2/media-hub |
project:bim | BIM captures, camera parameters and layers | 13, under /v2/cameras/{camera_exid}/bim and /layers |
project:weather | Current and historical weather for a site | /v2/projects/{exid}/weather, /weather/current, /weather/filters |
project:video_wall | Video walls, including creating and deleting them | 5, under /v2/video-walls |
project:comments | Reading and writing project comments | 5, under /v2/projects/{exid}/comments |
project:connectors | Procore, Autodesk, Aconex, HammerTech, Voyage Control, Ring and XWeather | 46, under each connector's own prefix |
project:settings | Members, roles, logos, thumbnails, camera settings and project transfer | 32, under /v2/projects/{exid} and /v2/cameras/{camera_exid} |
project:settings is the broad one — it covers adding and removing people,
changing roles and transferring a project. Grant it only to a key that really
administers a site.
Scopes with no Dash endpoints yet
The key editor also offers project:gate_report, project:timeline,
project:smart_search, project:ppe_monitoring, project:360,
project:drone, project:planner, project:automations and
project:widgets. None of them map to a Dash endpoint today — they exist for
features served elsewhere, or not yet enforced. Granting one changes nothing
about what the key can reach on this API.
What a key can never do
Some endpoints refuse API keys outright, whatever scopes the key holds:
- Authentication —
POST /v2/auth/login,DELETE /v2/auth/logout,GET /v2/auth/users/me,GET /v2/auth/credentials, provider and impersonation logins. A key is a credential; it cannot mint others. - Key and app management — everything under
/v2/api-keysand/v2/developer/apps. Keys cannot create, edit or regenerate keys. - Admin — every endpoint under
/v2/admin. - Internal — the Zoho CRM proxy, the Storyblok CMS proxy, and the OAuth callback and consent routes.
Anything not listed in the platform's scope map is refused the same way, so a brand-new endpoint is closed to keys until it is explicitly opened.
When a request is refused
| Response | Meaning |
|---|---|
401 | The key is missing, unknown, expired or revoked |
403 INSUFFICIENT_SCOPE | The key is valid but lacks the scope this endpoint needs — the www-authenticate header names it |
403 | The project or camera is outside the key's project list, or your own permissions do not allow it |
An expired key cannot be edited back to life: create a new one. The API keys page shows each key's status, scopes, projects and when it was last used.