API Reference

List Threat Actors by Industry

Threat actors reported to target a given industry, each with the quote that says so and the URL it came from.

/v1/actors returns the ranked actor list by default and switches to this by-industry list when the industry query parameter is supplied.

GET
/v1/actors?industry={industry}

Cost: 1 credit per successful call

Query parameters

industrystringrequired

Industry name, slug, or alias. 1–80 characters. Matching ignores case, spaces and punctuation, so Financial Services, financial-services and financialservices all resolve to the same industry.

limitintegeroptional

1–100. Defaults to 50.

Request

curl "https://api.precursorintelligence.com/functions/v1/actors?industry=Financial%20Services&limit=5" \
  -H "Authorization: Bearer $PRECURSOR_API_KEY"

Response

200 OK
{
  "data": {
    "count": 5,
    "industry": "Financial Services",
    "matched_industries": [
      { "name": "Financial Services", "slug": "financial-services" }
    ],
    "limit": 5,
    "items": [
      {
        "id": "a7bf1819-8616-4042-9461-00e8eda85d40",
        "name": "APT29",
        "slug": "apt29",
        "actor_type": "apt",
        "suspected_origin_country": "Russia (SVR)",
        "motivation": "espionage",
        "mitre_attack_id": "G0016",
        "relation": "targeted",
        "evidence_quote": "The group has repeatedly targeted financial services organisations across Western Europe...",
        "source_url": "https://www.cisa.gov/news-events/cybersecurity-advisories/aa21-116a",
        "counts": { "techniques": 66, "cves": 7 }
      }
    ],
    "generated_at": "2026-08-04T10:20:34.843Z"
  },
  "meta": {
    "request_id": "8b16efb8-9a6c-4ace-b817-11cbee626d08",
    "generated_at": "2026-08-04T10:20:34.843Z",
    "credits": { "charged": 1, "remaining": 9998 }
  }
}

Response fields

data.industrystringoptional

Echo of the string you sent.

data.matched_industriesarrayoptional

The industries your string actually resolved to. Check this — it is how you tell a real match from a near-miss. An empty array means nothing matched, and items will be empty too.

data.items[].relationstringoptional

How the actor relates to the industry. Currently always targeted.

data.items[].evidence_quotestring | nulloptional

The sentence from the source that asserts the targeting.

data.items[].source_urlstring | nulloptional

Where that quote was published.

data.items[].countsobjectoptional

techniques and cves totals for the actor, so you can gauge how well documented it is without a second call.

One row per actor

An actor claimed against the same industry by several sources appears once, carrying its strongest citation. Use Get Actor for that actor's full industry list.

Matching improved in v1.2.0

Earlier releases matched your string literally against a single free-text column, so only the exact spelling stored there would hit. Matching now runs through a normalised industry taxonomy with slugs and aliases, and matched_industries reports what resolved.

Errors

StatuserrorWhen
400missing_industry, invalid_industryMissing, over 80 characters, or contains control characters.
400invalid_limitlimit is non-numeric or outside 1–100.
401invalid_authorizationMissing or malformed Authorization header.
401unauthorizedInvalid/revoked key, or IP not allowlisted.
402insufficient_creditsOrganisation credit balance is below 1.
405method_not_allowedOnly GET and OPTIONS are accepted.
500internalUnexpected server error (credit auto-refunded).

An unrecognised industry is not an error — it returns 200 OK with empty matched_industries and items, and the credit is charged.

See Errors for the full error reference.