Takedown Attempts#
Returns recorded takedown attempts for incidents with at least one completed attempt.
Endpoint#
GET /v1/incidents/resolutions
Send your API key in the x-api-key header. See Authentication.
Request Example#
Parameters#
All query parameters are optional.
| Parameter | Type | Description |
|---|---|---|
limit |
integer |
Incidents per page. Default: 100. Maximum: 2000, or 100 with search. Minimum: 1. |
cursor |
string |
The previous response's paging.next value. |
clientId |
string |
Filter by a client covered by your API key. Defaults to all covered clients. |
fromDate |
string |
Filter by incident creation date, from this ISO 8601 date. |
toDate |
string |
Filter by incident creation date, up to this ISO 8601 date. |
status |
string |
Current incident status. |
incidentType |
string |
Incident type. |
sortBy |
string |
createdAt (default), lastHistoryUpdateTimestamp, or resolvedAt. Results are newest first. resolvedAt uses the latest completed attempt. |
reinitiatedAfter |
string |
success: a new attempt started after a successful attempt finished. resolved: a new attempt started after an attempt finished with any outcome. |
minTakedownAttempts |
integer |
Minimum number of attempts with a known startedAt. From 1 to 100000. |
includeTotal |
boolean |
Set to true to include the total number of matching incidents in paging.total. |
search |
string |
Find by incident ID, URL, domain, email, phone number or IP. Combine only with clientId and limit. Search results do not use pagination. |
fromDate and toDate apply to incident creation, not attempt completion.
Response Example#
{
"data": [
{
"id": "inc_7Kq2mZp9Lx",
"subject": "https://example.test/login",
"createdAt": "2026-09-15T08:00:00.000Z",
"takedownAttempts": [
{
"startedAt": "2026-09-15T08:10:00.000Z",
"resolvedAt": "2026-09-15T09:00:00.000Z",
"outcome": "success"
}
]
}
],
"message": "success",
"paging": {
"next": "inc_7Kq2mZp9Lx",
"limit": 100,
"count": 1
}
}
Response Fields#
Each item in data represents one incident.
| Field | Type | Description |
|---|---|---|
id |
string |
Incident ID. |
subject |
string (optional) |
URL, domain, email, phone number or IP. |
createdAt |
string | null |
Incident creation date. |
takedownAttempts |
array |
All recorded attempts for the incident, oldest first. |
Each attempt contains:
| Field | Type | Description |
|---|---|---|
startedAt |
string | null |
Start date, or null if unknown. |
resolvedAt |
string | null |
Completion date, or null if unfinished or unknown. |
outcome |
string | null |
Result, or null if unfinished. |
Dates are ISO 8601 in UTC.
Outcome Values#
| Value | Meaning |
|---|---|
success |
Content taken down. |
failed |
Takedown unsuccessful. |
not_actionable |
Incident could not be acted on. |
closed |
Incident closed without a takedown result. |
Reading Takedown Attempts#
A completed attempt has startedAt, resolvedAt, and outcome set. Only incidents with at least one completed attempt are returned; their unfinished attempts are included too. No matching incidents returns data: [].
History is available from when recording was enabled. Earlier attempts may be missing.
Examples#
Get attempts for one incident#
curl 'https://capi.phishfort.com/v1/incidents/resolutions?search=inc_7Kq2mZp9Lx' \
-H 'x-api-key: YOUR_API_KEY'
Find incidents taken down more than once#
Return incidents with at least two takedown attempts:
curl 'https://capi.phishfort.com/v1/incidents/resolutions?minTakedownAttempts=2' \
-H 'x-api-key: YOUR_API_KEY'
Sort by completion date#
curl 'https://capi.phishfort.com/v1/incidents/resolutions?sortBy=resolvedAt' \
-H 'x-api-key: YOUR_API_KEY'
Fetch every page#
Pass paging.next as cursor, keeping the same filters and sortBy. Stop when data is empty or paging.next is absent. The last request may return an empty page.
import requests
url = "https://capi.phishfort.com/v1/incidents/resolutions"
headers = {"x-api-key": "YOUR_API_KEY"}
params = {"limit": 100}
incidents = []
while True:
response = requests.get(url, params=params, headers=headers, timeout=60)
response.raise_for_status()
page = response.json()
incidents.extend(page["data"])
if not page["data"] or not page["paging"].get("next"):
break
params["cursor"] = page["paging"]["next"]
paging.count is the number of incidents on the page. With includeTotal=true, paging.total is the number of matching incidents across all pages.
Errors#
| Status | Action |
|---|---|
400 |
Check the query parameters and allowed combinations above. |
401 |
Check your API key and clientId. |
403 |
Contact PhishFort support to check access to takedown history. |
404 |
Incident not found. Check the incident ID. |
429 / 5xx |
Retry using the guidance in Limits. |