Skip to content

Report Incident

The incident report endpoint provides a way to submit incidents to PhishFort analysts for multiple scenarios including:

  • Submitting an incident for takedown.
  • Submitting an incident for monitoring (eg. the incident is suspicious but its current state does not warrant a takedown).

If submitting an incident on behalf of a sub-client, please make sure to use the clientId parameter as described in the Requesting a takedown for a specific sub-client example.

Endpoints

POST /v1/incident/tkd — Takedown request

POST /v1/incident/monitor — Monitoring request

Parameters

Parameter Type Required Description
url string Conditional The URL or domain of the incident. Required for domain/url incidents unless subject is provided.
incidentType string Conditional Required if not a domain/url incident. Values: email, phone, ipv4.
subject string Conditional Required when incidentType is email, phone, or ipv4. The subject value of the incident.
reportedBy string No Email address of the submitter. Required for the reporter to receive status emails. Highly recommended.
clientId string No Sub-client ID to report on behalf of. Only for clients with managed sub-clients.
comment string No Comment displayed to the analyst handling the case.
attachments file[] No Multipart file field. Repeat the attachments field to upload multiple files.

Conditional requirements

  • For domain/url incidents: provide url.
  • For email, phone, or ipv4 incidents: provide both incidentType and subject.
  • The comment field, if provided, cannot be null — it must be a valid non-null string.
  • The phone incident type is validated against E.164 format.

Attachment limits

Multipart incident reports can include up to 12 files by repeating the attachments field, and the total request size must stay under 10 MB. See Limits for details.

Request Example (Requesting a takedown)

curl -X POST 'https://capi.phishfort.com/v1/incident/tkd' \
  -H 'accept: application/json' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"url": "https://somethingbad.com", "reportedBy": "john.doe@company.com"}'
import requests

response = requests.post(
    "https://capi.phishfort.com/v1/incident/tkd",
    headers={
        "accept": "application/json",
        "x-api-key": "YOUR_API_KEY",
    },
    json={
        "url": "https://somethingbad.com",
        "reportedBy": "john.doe@company.com",
    },
)
print(response.json())
const response = await fetch("https://capi.phishfort.com/v1/incident/tkd", {
  method: "POST",
  headers: {
    accept: "application/json",
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    url: "https://somethingbad.com",
    reportedBy: "john.doe@company.com",
  }),
});
const data = await response.json();
console.log(data);

Request Example (Requesting a takedown for a specific sub-client)

curl -X POST 'https://capi.phishfort.com/v1/incident/tkd' \
  -H 'accept: application/json' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"url": "https://somethingbad.com", "clientId": "client_id_here", "reportedBy": "john.doe@company.com"}'
import requests

response = requests.post(
    "https://capi.phishfort.com/v1/incident/tkd",
    headers={
        "accept": "application/json",
        "x-api-key": "YOUR_API_KEY",
    },
    json={
        "url": "https://somethingbad.com",
        "clientId": "client_id_here",
        "reportedBy": "john.doe@company.com",
    },
)
print(response.json())
const response = await fetch("https://capi.phishfort.com/v1/incident/tkd", {
  method: "POST",
  headers: {
    accept: "application/json",
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    url: "https://somethingbad.com",
    clientId: "client_id_here",
    reportedBy: "john.doe@company.com",
  }),
});
const data = await response.json();
console.log(data);

Request Example (Requesting with subject)

curl -X POST 'https://capi.phishfort.com/v1/incident/tkd' \
  -H 'accept: application/json' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"subject": "192.168.1.1", "incidentType": "ipv4", "reportedBy": "john.doe@company.com"}'
import requests

response = requests.post(
    "https://capi.phishfort.com/v1/incident/tkd",
    headers={
        "accept": "application/json",
        "x-api-key": "YOUR_API_KEY",
    },
    json={
        "subject": "192.168.1.1",
        "incidentType": "ipv4",
        "reportedBy": "john.doe@company.com",
    },
)
print(response.json())
const response = await fetch("https://capi.phishfort.com/v1/incident/tkd", {
  method: "POST",
  headers: {
    accept: "application/json",
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    subject: "192.168.1.1",
    incidentType: "ipv4",
    reportedBy: "john.doe@company.com",
  }),
});
const data = await response.json();
console.log(data);

Where incidentType can be any of the following: phone, email, ipv4. The subject field should have the value of the appropriate incidentType. Please note that all the values will be validated according to their format where phone incidentType will be validated against E.164 format.

Request Example (Report with comment)

curl -X POST 'https://capi.phishfort.com/v1/incident/monitor' \
  -H 'accept: application/json' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"url": "https://somethingsuspicious.com", "comment": "This is extremely important", "reportedBy": "john.doe@company.com"}'
import requests

response = requests.post(
    "https://capi.phishfort.com/v1/incident/monitor",
    headers={
        "accept": "application/json",
        "x-api-key": "YOUR_API_KEY",
    },
    json={
        "url": "https://somethingsuspicious.com",
        "comment": "This is extremely important",
        "reportedBy": "john.doe@company.com",
    },
)
print(response.json())
const response = await fetch(
  "https://capi.phishfort.com/v1/incident/monitor",
  {
    method: "POST",
    headers: {
      accept: "application/json",
      "x-api-key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      url: "https://somethingsuspicious.com",
      comment: "This is extremely important",
      reportedBy: "john.doe@company.com",
    }),
  }
);
const data = await response.json();
console.log(data);

Request Example (Report with attachments)

curl -X POST 'https://capi.phishfort.com/v1/incident/tkd' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: multipart/form-data' \
  --form 'url="https://somethingbad.com"' \
  --form 'reportedBy="john.doe@company.com"' \
  --form 'attachments=@"/path/to/file-1.pdf"' \
  --form 'attachments=@"/path/to/file-2.png"'
import requests

with open("/path/to/file-1.pdf", "rb") as file_1, open("/path/to/file-2.png", "rb") as file_2:
    response = requests.post(
        "https://capi.phishfort.com/v1/incident/tkd",
        headers={"x-api-key": "YOUR_API_KEY"},
        data={
            "url": "https://somethingbad.com",
            "reportedBy": "john.doe@company.com",
        },
        files=[
            ("attachments", file_1),
            ("attachments", file_2),
        ],
    )
print(response.json())
const fs = require("fs");
const FormData = require("form-data");

const form = new FormData();
form.append("url", "https://somethingbad.com");
form.append("reportedBy", "john.doe@company.com");
form.append("attachments", fs.createReadStream("/path/to/file-1.pdf"));
form.append("attachments", fs.createReadStream("/path/to/file-2.png"));

const response = await fetch("https://capi.phishfort.com/v1/incident/tkd", {
  method: "POST",
  headers: {
    "x-api-key": "YOUR_API_KEY",
    ...form.getHeaders(),
  },
  body: form,
});
const data = await response.json();
console.log(data);

Request Example (Requesting the incident be monitored)

curl -X POST 'https://capi.phishfort.com/v1/incident/monitor' \
  -H 'accept: application/json' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"url": "https://somethingsuspicious.com", "reportedBy": "john.doe@company.com"}'
import requests

response = requests.post(
    "https://capi.phishfort.com/v1/incident/monitor",
    headers={
        "accept": "application/json",
        "x-api-key": "YOUR_API_KEY",
    },
    json={
        "url": "https://somethingsuspicious.com",
        "reportedBy": "john.doe@company.com",
    },
)
print(response.json())
const response = await fetch(
  "https://capi.phishfort.com/v1/incident/monitor",
  {
    method: "POST",
    headers: {
      accept: "application/json",
      "x-api-key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      url: "https://somethingsuspicious.com",
      reportedBy: "john.doe@company.com",
    }),
  }
);
const data = await response.json();
console.log(data);

Response Example

If successful, the response normally contains a success message, an id used by later incident endpoints, and a dashboard url. Treat id as an opaque string: its format can vary and integrations must not infer an internal storage system from it. Use it with the Single Incident Query API.

{
    "message": "Successfully reported the incident",
    "id": "inc_A1b2C3d4E5f6G7h8I9j0",
    "url": "https://dashboard.phishfort.com/incident/inc_A1b2C3d4E5f6G7h8I9j0"
}

Duplicate Reports

Prevent duplicate submissions in your integration; the report endpoints do not accept an idempotency key. A duplicate can be returned in either of these forms:

  • 409 Conflict with a message that the incident already exists.
  • 200 OK with no id or url when the report is accepted by an older processing path:
{
    "message": "Successfully reported but this incident may be a duplicate"
}

Always check both the HTTP status and the presence of id. Do not retry automatically and do not parse the human-readable error message as a stable identifier. Route an unlinked duplicate for manual handling.

GET /v1/incident/subject/{subject} can resolve email, phone, and ipv4 incidents, but it is not a general lookup-by-URL or idempotency endpoint. Integrations must persist the successful report response's id alongside their own ticket, case, or alert record.