Skip to content

Migrating an integration to API v3

The legacy Watcher API (/vsaas/api/v1, /vsaas/api/v2) and the global domain key X-Vsaas-Api-Key have been removed. Integrations using these requests stop working after Watcher is updated. This article describes how to move an integration to API v3: which of the two APIs to use, how to authorize, and how v3 behavior differs from v2.

Full API v3 references:

If your integration is an operator's billing system, use the dedicated article Integration with existing billing system: it covers the same principles applied to typical billing scenarios.

Client API and Admin API

There are two request sets in v3 with different base paths:

  • Client API/watcher/client-api/v3/.... The primary API for integrations: organizations, users, folders, cameras, permissions, mosaics, analytics episodes. Available to any user; requests are limited by the user's permissions.
  • Admin API/watcher/admin-api/v3/.... Only for users with the Watcher administrator access level. Used for installation-level operations: creating presets, managing streamers and domains.

The Client API is enough for most integrations. The Admin API is needed if the integration creates presets or works with multiple domains.

Authorization

There is no global domain key in v3: every request is executed on behalf of a user and is limited by that user's permissions. Create a dedicated service account with the required permissions for the integration; do not use personal employee accounts.

Authorization methods (see API request authorization for details):

  • JWT token: POST /watcher/client-api/v3/login with Basic authorization returns an access_token (valid for one hour) and a refresh_token. A new access_token is issued by repeating the /login request with the Authorization: Bearer <refresh_token> header.
  • Personal API key: issued with POST /watcher/client-api/v3/users/{user_id}/apikey, has no expiration and requires no renewal — the recommended option for server-side integrations.

Pass the token or key in the Authorization: Bearer <value> header of every request.

Note

Do not call /login before every request: frequent requests cause the server to respond with 429 Too Many Requests. Use an API key, or reuse the access_token until it expires.

For the Admin API, the POST /watcher/admin-api/v3/login request is available only to users with the Watcher administrator access level; a domain administrator is rejected.

Behavior changes

Migration is not limited to replacing request paths. Check the integration code for the following changes:

  • The cameras resource is renamed to streams. There is no separate camera creation request: a camera is created and updated with the same PUT /watcher/client-api/v3/streams/{name} request. The camera name is assigned by Watcher: on creation, the {name} value from the URL is not used — the name is generated from title and returned in the name field of the response. Save it; all further operations are performed by it.
  • Bulk import does not return names. The POST /streams/import response contains only the counters of created and updated cameras. Use import for bulk updates; create cameras the integration will manage one at a time.
  • The user's name field is the login. The notification email is passed in the email field.
  • Blocking uses the disabled field. There is no enabled field in v3. With disabled: true and on password change, all user sessions are terminated.
  • Password change goes through the user update. PUT /users/{user_id} with the password field; there is no separate request.
  • Permissions are not inherited between levels. Administrator permissions do not automatically grant permissions in an organization: for example, POST /users with organization_id requires owning the organization or an explicit user management permission in it, otherwise 403 is returned. Perform administrative camera and user operations through the Admin API. The creator of an organization becomes its owner; the owner can be assigned explicitly with the owner.id field at creation.
  • Video access is granted on folders. Viewing permissions (can_view, can_view_dvr, can_use_ptz) are assigned with PUT /organizations/{id}/folders/{folder_id}/users/{user_id} and apply recursively to nested folders. Organization membership by itself does not grant video access.
  • The camera edit permission includes video viewing. A user with can_edit_streams automatically gets can_view_streams; in API responses this flag is returned as true regardless of the sent value.
  • Cursor pagination. Collections return the estimated_count, next, prev fields; there is no page offset. Pass the next value in the cursor parameter of the next request.
  • Camera status is in the stats.alive field (streaming; false when the delay exceeds 12 seconds) and stats.status (running / waiting / error). There are no online/offline fields.
  • A readonly user gets 403 on any modifying request (POST/PUT/DELETE/PATCH) regardless of other permissions.

Mapping of v2 and v3 requests

The main requests (see the API references for the full list):

Request in v2 Request in v3
X-Vsaas-Api-Key: <domain key> Authorization: Bearer <token or API key>
POST /vsaas/api/v2/auth/login POST /watcher/client-api/v3/login
GET /vsaas/api/v2/profile GET /watcher/client-api/v3/profile
POST /vsaas/api/v2/users/{id}/apikey POST /watcher/client-api/v3/users/{user_id}/apikey
GET /vsaas/api/v2/cameras GET /watcher/client-api/v3/streams
POST /vsaas/api/v2/cameras PUT /watcher/client-api/v3/streams/{name} — the name is assigned by Watcher, see above
PUT /vsaas/api/v2/cameras/{name} PUT /watcher/client-api/v3/streams/{name}
DELETE /vsaas/api/v2/cameras/{name} DELETE /watcher/client-api/v3/streams/{name}
POST /vsaas/api/v2/cameras/import POST /watcher/client-api/v3/streams/import
GET/POST /vsaas/api/v2/users, PUT/DELETE /users/{id} the same operations under /watcher/client-api/v3/users
GET/POST /vsaas/api/v2/organizations, PUT/DELETE /organizations/{id} the same operations under /watcher/client-api/v3/organizations
.../organizations/{id}/users/{user_id} the same path under /watcher/client-api/v3/... (PUT adds the user to the organization if they are not a member yet)
.../organizations/{id}/folders/... the same paths under /watcher/client-api/v3/...
GET/POST /vsaas/api/v2/presets GET /watcher/client-api/v3/presets; creation — POST /watcher/admin-api/v3/presets
POST /vsaas/api/v2/agent-activation-tokens POST /watcher/client-api/v3/agent_activation_token
GET /vsaas/api/v2/mosaics GET /watcher/client-api/v3/mosaics
GET /vsaas/api/v2/events GET /watcher/client-api/v3/episodes — the event model has changed, see the API reference

Migration steps

  1. Create a service account and issue an API key for it.
  2. Replace the authorization: remove X-Vsaas-Api-Key, pass Authorization: Bearer <key>.
  3. Replace the request paths using the table above and adapt the code to the behavior changes: camera name generation, cursor pagination, disabled instead of enabled.
  4. Check the service account's permissions on every operation: a 403 error in v3 most often means missing permissions in a specific organization, not an invalid token.
  5. Verify the integration on a test installation before updating the production one.