Migrating to V2
Migrating to V2
The Doppel V2 API preserves the V1 path and request/response contract for
equivalent, non-deprecated endpoints, with a new authentication model. It also
adds V2-only asset endpoints and deprecates the older V2 protected-asset list
and create routes.
For routes that exist in both versions and are not deprecated, migration is
primarily an authentication and path-prefix change. Integrations that use
report routes or protected-asset list/create routes should also make the
resource changes below.
What changed
| V1 | V2 | |
|---|---|---|
| Auth headers | x-api-key (organization-wide), or x-api-key + x-user-api-key (user-specific). See Authentication. | Authorization: Bearer <access_token> |
| Token issuance | Static keys: organization-wide keys are issued by your Doppel sales representative; user-specific keys are self-service from Doppel Vision API settings. See Authentication. | OAuth 2.0 client credentials at POST /oauth/token; access_token expires after expires_in seconds (24 hours at the time of writing) |
| Org scope header | x-organization-code: <ORG> (optional; per the V1 OpenAPI spec, required only when your user belongs to multiple organizations) | Not part of the V2 contract — organization is derived from the org_id claim in the JWT |
| Path prefix | /v1/<resource> | /v2/<resource> |
| Request/response bodies | — | Unchanged for equivalent non-deprecated endpoints; V2-only asset routes have their own contracts |
If your code uses only routes present in both versions and no deprecated
endpoints (see below), the required code changes are: (1) exchange your client
credentials for a token, (2) replace the V1 auth headers with
Authorization: Bearer ..., (3) drop x-organization-code if you were sending
one, and (4) change /v1/ to /v2/ in those request URLs.
Deprecated endpoints
The following V1 endpoints are documented as deprecated: true in the V2 OpenAPI spec. They still work in V2, but new integrations should not depend on them.
POST /v2/report— usePOST /v2/alertinsteadGET /v2/report— useGET /v2/alertinsteadPUT /v2/report— usePUT /v2/alertinsteadGET /v2/reports— useGET /v2/alertsinsteadGET /v2/protected-assets— useGET /v2/assetswith the required
asset_typePOST /v2/protected-asset— usePOST /v2/assetswith the required
asset_type
The report resource and the alert resource refer to the same underlying
object. The migration is a rename: replace report with alert (and reports
with alerts) in the path. Request bodies and response shapes are otherwise
identical.
The deprecated protected-asset routes also continue to work. The old list
returns owned and associated assets together, and the old create route creates
owned assets only. DELETE /v2/protected-asset/{id} is not deprecated.
V2-only asset workflows
V2 adds:
GET /v2/assetsto list one requiredasset_typePOST /v2/assetsto create an owned or associated assetPOST /v2/alert/assetsto create an asset using the value and brand from an
alert
See Manage assets for examples and migration guidance.
Step 1: Get an OAuth access token
An organization admin or super admin can create a Client ID and Client Secret from the Version 2 tab on the API Settings page in Doppel Vision. Credentials are self-service, and each organization can have up to 10 clients.
Save the Client Secret when you create the client. It is shown only once and cannot be retrieved later. Exchange the credentials for an access token via POST /oauth/token. See the V2 Authentication guide on the V2 docs site for the full token-exchange flow (including refresh handling).
Step 2: Replace your auth headers
V1 (before)
The example below shows the user-specific V1 mode (x-api-key + x-user-api-key) with an explicit x-organization-code. If you were authenticating with x-api-key alone (organization-wide), simply drop the other two headers from the V1 request.
cURL
curl --request GET \
--url "https://api.doppel.com/v1/alerts?queue_state=needs_confirmation" \
--header "x-api-key: <YOUR_ORG_API_KEY>" \
--header "x-user-api-key: <YOUR_USER_API_KEY>" \
--header "x-organization-code: ACM"Python
import requests
response = requests.get(
"https://api.doppel.com/v1/alerts",
headers={
"x-api-key": "<YOUR_ORG_API_KEY>",
"x-user-api-key": "<YOUR_USER_API_KEY>",
"x-organization-code": "ACM",
},
params={"queue_state": "needs_confirmation"},
)Node.js
const url = new URL("https://api.doppel.com/v1/alerts");
url.searchParams.set("queue_state", "needs_confirmation");
const response = await fetch(url, {
headers: {
"x-api-key": "<YOUR_ORG_API_KEY>",
"x-user-api-key": "<YOUR_USER_API_KEY>",
"x-organization-code": "ACM",
},
});V2 (after)
cURL
curl --request GET \
--url "https://api.doppel.com/v2/alerts?queue_state=needs_confirmation" \
--header "Authorization: Bearer <YOUR_ACCESS_TOKEN>"Python
import requests
response = requests.get(
"https://api.doppel.com/v2/alerts",
headers={"Authorization": f"Bearer {access_token}"},
params={"queue_state": "needs_confirmation"},
)Node.js
const url = new URL("https://api.doppel.com/v2/alerts");
url.searchParams.set("queue_state", "needs_confirmation");
const response = await fetch(url, {
headers: { Authorization: `Bearer ${access_token}` },
});For this alert-list request, the query string, response shape, and pagination
behavior are identical to V1; only the auth headers and path prefix change.
Step 3: Handle token expiration
V2 access tokens expire after the expires_in window returned by POST /oauth/token (24 hours at the time of writing). Your client must refresh on 401 Unauthorized, or proactively before expiration. A typical pattern:
import time
import requests
_token = None
_token_expires_at = 0
def get_token() -> str:
global _token, _token_expires_at
if _token and time.time() < _token_expires_at - 60:
return _token
response = requests.post(
"https://api.doppel.com/oauth/token",
json={
"client_id": CLIENT_ID,
"client_secret": CLIENT_SECRET,
"audience": "doppel-external",
"grant_type": "client_credentials",
},
)
response.raise_for_status()
data = response.json()
_token = data["access_token"]
_token_expires_at = time.time() + data["expires_in"]
return _tokenMigration checklist
- Have an organization admin or super admin create a Client ID and Client Secret in Doppel Vision API Settings.
- Implement the OAuth token-exchange flow (see the V2 Authentication guide).
- Replace
x-api-key(and, if you were sending it,x-user-api-key) withAuthorization: Bearer <token>. - Drop the
x-organization-codeheader if you were sending one — V2 derives the organization from the token. - Confirm each route exists in V2, then change its
/v1/prefix to/v2/. - Add token-refresh handling on
401 Unauthorized. - If you call
/v1/report*or/v1/reports, switch to/v2/alert*or/v2/alerts. - If you list or create protected assets, switch to
/v2/assetsand send
asset_type. - Run your existing integration tests against
/v2/to confirm response shapes are unchanged.
Need help?
If you hit a difference between V1 and V2 that is not covered here, contact your Doppel representative — please include the request URL, the V1 vs V2 response, and any HTTP status codes you observed.
Updated 7 days ago
