Check the status of an alert
Check the status of an alert
After you submit an alert, Doppel processes the entity through its triage workflow. This guide shows how to read an alert's current state from the API — by id, by entity, or in bulk by filtering the alert list.
What you'll do
- Authenticate (see Authentication).
- Look the alert up by
idor byentity, or list alerts filtered byqueue_state. - Read the
queue_statefield on the response.
The examples below show the organization-wide auth mode (
x-api-keyonly). For the user-specific mode, also sendx-user-api-key(andx-organization-codeif your user belongs to multiple organizations) — see Authentication.
Get a single alert by id
The id returned from POST /v1/alert is the most reliable handle. GET /v1/alert requires exactly one of id or entity as a query parameter — passing both, or neither, returns 400 Bad Request.
cURL
curl --request GET \
--url "https://api.doppel.com/v1/alert?id=ACM-1234" \
--header "x-api-key: <YOUR_ORG_API_KEY>"Python
import requests
response = requests.get(
"https://api.doppel.com/v1/alert",
headers={"x-api-key": "<YOUR_ORG_API_KEY>"},
params={"id": "ACM-1234"},
)
response.raise_for_status()
alert = response.json()
print(alert["queue_state"], alert["entity_state"])Node.js
const url = new URL("https://api.doppel.com/v1/alert");
url.searchParams.set("id", "ACM-1234");
const response = await fetch(url, {
headers: { "x-api-key": "<YOUR_ORG_API_KEY>" },
});
const alert = await response.json();
console.log(alert.queue_state, alert.entity_state);Look an alert up by entity
If you don't have an id, look the alert up by entity (URL or phone number). URL-encode the value.
curl --request GET \
--url "https://api.doppel.com/v1/alert?entity=https%3A%2F%2Fsuspicious-site.example.com" \
--header "x-api-key: <YOUR_ORG_API_KEY>"response = requests.get(
"https://api.doppel.com/v1/alert",
headers={"x-api-key": "<YOUR_ORG_API_KEY>"},
params={"entity": "https://suspicious-site.example.com"},
)const url = new URL("https://api.doppel.com/v1/alert");
url.searchParams.set("entity", "https://suspicious-site.example.com");
const response = await fetch(url, {
headers: { "x-api-key": "<YOUR_ORG_API_KEY>" },
});List alerts by queue state
To check status across many alerts at once — for example, to see everything waiting on takedown — use GET /v1/alerts with a queue_state filter:
curl --request GET \
--url "https://api.doppel.com/v1/alerts?queue_state=actioned&page_size=100" \
--header "x-api-key: <YOUR_ORG_API_KEY>"response = requests.get(
"https://api.doppel.com/v1/alerts",
headers={"x-api-key": "<YOUR_ORG_API_KEY>"},
params={"queue_state": "actioned", "page_size": 100},
)
for alert in response.json()["alerts"]:
print(alert["id"], alert["entity"], alert["last_activity_timestamp"])const url = new URL("https://api.doppel.com/v1/alerts");
url.searchParams.set("queue_state", "actioned");
url.searchParams.set("page_size", "100");
const response = await fetch(url, {
headers: { "x-api-key": "<YOUR_ORG_API_KEY>" },
});
const { alerts } = await response.json();GET /v1/alerts is paginated (page is zero-indexed; default page_size is 30, maximum 200). Per the V1 OpenAPI spec, the listing response uses last_activity_timestamp, while a single-alert response uses last_activity.
The full set of documented query parameters on GET /v1/alerts (per the V1 OpenAPI spec) includes search_key, queue_state, product, created_before, created_after, last_activity_timestamp, sort_type, sort_order, page, page_size, and tags. See the Get Alerts entry in the V1 API reference for full details.
Reading the response
The status of an alert is captured by two fields:
queue_state— where the alert sits in Doppel's workflow. Per the V1 OpenAPI spec, the value is one of:doppel_review,needs_confirmation,actioned,taken_down,monitoring,archived.entity_state— the live state of the entity (URL, phone, etc.) the alert is tracking. Per the V1 OpenAPI spec, the value is one of:active,down,parked,suspicious,unclassified,unrelated,related,unknown.
Two queue_state values map directly to UI actions in Doppel Vision:
taken_downis shown as Resolved in the Doppel Vision app (per the V1 OpenAPI spec note).actionedis the value set when Request Takedown is invoked in the UI (see Request a takedown).
For the semantics of the other values, see the Get Alert entry in the V1 API reference.
Polling pattern
If you poll for status, do it on a backoff and stop once queue_state is taken_down or archived:
import time
TERMINAL_STATES = {"taken_down", "archived"}
def wait_for_resolution(alert_id: str, timeout_seconds: int = 86400) -> dict:
deadline = time.time() + timeout_seconds
delay = 60
while time.time() < deadline:
response = requests.get(
"https://api.doppel.com/v1/alert",
headers={"x-api-key": "<YOUR_ORG_API_KEY>"},
params={"id": alert_id},
)
response.raise_for_status()
alert = response.json()
if alert["queue_state"] in TERMINAL_STATES:
return alert
time.sleep(delay)
delay = min(delay * 2, 900)
raise TimeoutError(f"{alert_id} did not reach a terminal state in time")Status codes
| Status | Meaning |
|---|---|
200 OK | Alert (or alert list) returned successfully. |
400 Bad Request | Both or neither of id / entity was provided to GET /v1/alert, or another query parameter was malformed. |
401 Unauthorized | Missing or invalid auth headers. |
404 Not Found | No alert in your organization matches the supplied id or entity. (Single-alert endpoint only.) |
429 Too Many Requests | Rate limit exceeded. |
Next steps
- Request a takedown — set an alert's
queue_statetoactionedviaPUT /v1/alert. - Submit a new alert — start tracking a new entity.
