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/loginwith Basic authorization returns anaccess_token(valid for one hour) and arefresh_token. A newaccess_tokenis issued by repeating the/loginrequest with theAuthorization: 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
camerasresource is renamed tostreams. There is no separate camera creation request: a camera is created and updated with the samePUT /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 fromtitleand returned in thenamefield of the response. Save it; all further operations are performed by it. - Bulk import does not return names. The
POST /streams/importresponse 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
namefield is the login. The notification email is passed in theemailfield. - Blocking uses the
disabledfield. There is noenabledfield in v3. Withdisabled: trueand on password change, all user sessions are terminated. - Password change goes through the user update.
PUT /users/{user_id}with thepasswordfield; there is no separate request. - Permissions are not inherited between levels. Administrator permissions do not automatically grant permissions in an organization: for example,
POST /userswithorganization_idrequires owning the organization or an explicit user management permission in it, otherwise403is 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 theowner.idfield at creation. - Video access is granted on folders. Viewing permissions (
can_view,can_view_dvr,can_use_ptz) are assigned withPUT /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_streamsautomatically getscan_view_streams; in API responses this flag is returned astrueregardless of the sent value. - Cursor pagination. Collections return the
estimated_count,next,prevfields; there is no pageoffset. Pass thenextvalue in thecursorparameter of the next request. - Camera status is in the
stats.alivefield (streaming;falsewhen the delay exceeds 12 seconds) andstats.status(running/waiting/error). There are noonline/offlinefields. - A
readonlyuser gets403on 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¶
- Create a service account and issue an API key for it.
- Replace the authorization: remove
X-Vsaas-Api-Key, passAuthorization: Bearer <key>. - Replace the request paths using the table above and adapt the code to the behavior changes: camera name generation, cursor pagination,
disabledinstead ofenabled. - Check the service account's permissions on every operation: a
403error in v3 most often means missing permissions in a specific organization, not an invalid token. - Verify the integration on a test installation before updating the production one.