Skip to content

History Author Details#

Every entry in an incident's history has an author display string such as PhishFort System or Client (jane@acme.com). authorDetails is the same information as a structured object, so you can tell client messages from PhishFort updates, and automated lines from human ones, without parsing the string.

Enabled per account

authorDetails is switched on per account. Until it is enabled for yours, history entries don't include the field at all. Contact PhishFort support to enable it, and treat the field as optional in your integration.

Where it appears#

authorDetails is returned on each history entry from the single-incident endpoints:

Method Endpoint
GET /v1/incident/{id}
GET /v1/incident/subject/{subject}

It needs no extra request parameters. When it's enabled for your account, it's present on every history entry those endpoints return.

Structure#

{
    "id": string,
    "message": string,
    "type": "info" | "info/auto" | "info/comment", // unchanged
    "author": string, // unchanged display string
    "authorDetails": {
        "type": "client" | "phishfort",
        "clientId": string | null,
        "email": string | null,
        "automated": boolean
    },
    "timestamp": Date
}
Field Type Meaning
authorDetails.type "client" | "phishfort" client for messages and takedown approvals or declines from your organisation. phishfort for everything else, including analyst updates and automated status lines.
authorDetails.clientId string | null The id of the client that wrote the entry, when it can be matched to exactly one of the clients your API key covers. Always null for phishfort entries.
authorDetails.email string | null The responder's email address, when the entry was recorded with one (for example a comment posted with an author email, or a takedown approval). Always null for phishfort entries.
authorDetails.automated boolean true for automated, system-generated entries such as Awaiting client approval or Takedown initiated. Always false for client entries.

How authorDetails lines up with the existing type and author fields:

type author authorDetails.type authorDetails.automated
info/auto PhishFort System phishfort true
info PhishFort phishfort false
info/comment Client (<sender>) or Client client false
info Client (<sender>) or Client (takedown approvals and declines) client false

Response Example#

{
    "data": {
        "id": "054zKkjCnR1I3B3U812z",
        "history": [
            {
                "id": "5521874",
                "message": "Awaiting client approval",
                "type": "info/auto",
                "author": "PhishFort System",
                "authorDetails": {
                    "type": "phishfort",
                    "clientId": null,
                    "email": null,
                    "automated": true
                },
                "timestamp": "2026-09-10T08:12:04.000Z"
            },
            {
                "id": "5521908",
                "message": "Takedown approved by jane@acme.com",
                "type": "info",
                "author": "Client (jane@acme.com)",
                "authorDetails": {
                    "type": "client",
                    "clientId": null,
                    "email": "jane@acme.com",
                    "automated": false
                },
                "timestamp": "2026-09-10T09:30:47.000Z"
            },
            {
                "id": "5521911",
                "message": "Please prioritise this one, it is being shared with our customers.",
                "type": "info/comment",
                "author": "Client (Acme Corp)",
                "authorDetails": {
                    "type": "client",
                    "clientId": "a1B2c3D4e5F6g7H8i9J0",
                    "email": null,
                    "automated": false
                },
                "timestamp": "2026-09-10T09:31:02.000Z"
            },
            {
                "id": "5522046",
                "message": "We've contacted the hosting provider and are waiting on a response.",
                "type": "info",
                "author": "PhishFort",
                "authorDetails": {
                    "type": "phishfort",
                    "clientId": null,
                    "email": null,
                    "automated": false
                },
                "timestamp": "2026-09-10T11:05:19.000Z"
            }
        ]
    }
}

Other incident fields are left out above for brevity. See DetailedIncidentStructure for the full response.

Usage Examples#

import requests

incident_id = "054zKkjCnR1I3B3U812z"
response = requests.get(
    f"https://capi.phishfort.com/v1/incident/{incident_id}",
    headers={"accept": "application/json", "x-api-key": "YOUR_API_KEY"},
)
history = response.json()["data"].get("history", [])

# authorDetails is optional: skip entries without it
detailed = [e for e in history if "authorDetails" in e]

client_entries = [e for e in detailed if e["authorDetails"]["type"] == "client"]
analyst_updates = [
    e for e in detailed
    if e["authorDetails"]["type"] == "phishfort" and not e["authorDetails"]["automated"]
]
const incidentId = "054zKkjCnR1I3B3U812z";
const response = await fetch(
  `https://capi.phishfort.com/v1/incident/${incidentId}`,
  { headers: { accept: "application/json", "x-api-key": "YOUR_API_KEY" } }
);
const { data } = await response.json();

// authorDetails is optional: skip entries without it
const detailed = (data.history ?? []).filter((e) => e.authorDetails);

const clientEntries = detailed.filter((e) => e.authorDetails.type === "client");
const analystUpdates = detailed.filter(
  (e) => e.authorDetails.type === "phishfort" && !e.authorDetails.automated
);

Notes#

  • type and author are unchanged. authorDetails is added alongside them, so existing integrations keep working.
  • Don't rely on clientId or email being set on client entries. Each one is filled in only when the entry carries that information.
  • For the rest of the history entry fields, see IncidentHistory.