---
title: "Bulk entity check"
method: POST
path: "/bulk/check"
tags: ["check"]
---

# Bulk entity check

`POST /bulk/check`

Check up to N entities per request (N depends on subscription plan). Each
entity may be a domain, IP, URL, or file hash string. With
`format: "csv"` the 200 response is `text/csv` instead of JSON.
Validation failures (empty list, over the plan limit) answer 400 with the
same `BulkCheckResponse` shape (`success: false` + `errors`).

## Request body

- BulkCheckRequest
  - `enrichment` string, nullable
  - `entities` string[], required
  - `format` string, nullable

## Response `200`

Batch results (JSON, or CSV when `format: "csv"`)

- BulkCheckResponse
  - `errors` string[], nullable
  - `processed` integer, required
  - `processingTimeMs` integer, required
  - `results` EntityResult[], required
    - `analystStatus` string, required
    - `categories` string[], required
    - `confidence` number, double, nullable — 0-100. Absent on an unknown hash (`lookupStatus: "unknown"`), like `riskScore` and `riskLevel`: there is no evidence to be confident in.
    - `entity` string, required
    - `error` string, nullable
    - `evidence` unknown
    - `infrastructure` InfrastructureAttribution — What the entity IS, according to the listings that describe rather than accuse it. Present on a response only when at least one such listing exists on the document.
      - `attributes` string[], required — Distinct, sorted attributes drawn from the vocabulary: `tor-exit`, `vpn`, `proxy`, `doh-resolver`, `dns-resolver`, `sinkhole`, `cloud`, `cdn`, `crawler`, `scanner`, `monitoring`, `disposable-email`, `dynamic-dns`, `url-shortener`, `bogon`, `saas`, `allowlist`
      - `sources` InfrastructureSource[], required — The non-threat listings the attributes were derived from
        - `category` string, nullable — The listing's primary category, as ingested
        - `id` string, nullable — Registry id of the feed (absent on legacy listings written before ids)
        - `name` string, required — Feed name as stored on the listing
        - `threatClass` string, required — `infrastructure` | `policy` | `allowlist` — never `threat` here
    - `isMalicious` boolean, required
    - `lookupStatus` string, nullable — Whether hash reputation evidence exists. Unknown is not a clean verdict.
    - `observedAt` string, required
    - `recommendedAction` string, required
    - `riskLevel` string, nullable
    - `riskScore` integer, nullable
    - `sources` integer, required — Threat-class listings only — the same count as `/check` `blocklistHits` and `/gate` `sources`. Infrastructure, policy and allowlist listings are summarised under `infrastructure`, not counted here.
    - `type` string, required
  - `success` boolean, required
  - `total` integer, required

## Other responses

- `400` — Empty entity list or plan limit exceeded — same shape with `success: false` and `errors`
- `401` — Unauthorized - Missing or invalid API key
- `429` — Too many requests - Rate limit exceeded

## Changes

- **2026-09-25** `0fa256b179f3` — 4 breaking
  - the response property `results/items/confidence` became nullable for the status `200`
  - the response property `results/items/confidence` became nullable for the status `400`
  - the response property `results/items/confidence` became optional for the status `200`
  - the response property `results/items/confidence` became optional for the status `400`
- **2026-09-20** `eb1bf7b5e785` — 2 info
  - added the optional property `results/items/lookupStatus` to the response with the `200` status
  - added the optional property `results/items/lookupStatus` to the response with the `400` status
- **2026-09-19** `1bc3c7aeff82` — 2 info
  - added the optional property `results/items/infrastructure` to the response with the `200` status
  - added the optional property `results/items/infrastructure` to the response with the `400` status
- **2026-08-31** `9d9ef31d83e5` — 12 breaking, 12 info
  - the response property `message` became nullable for the status `401`
  - the response property `message` became nullable for the status `429`
  - the response property `message` became optional for the status `401`
  - the response property `message` became optional for the status `429`
  - …20 more

[Change history](https://skmtc.dev/ismalicious/apis/ismalicious-threat-intelligence-api/changes/bulk/check/post.md)

---

[API](https://skmtc.dev/ismalicious/apis/ismalicious-threat-intelligence-api.md) · [All operations](https://skmtc.dev/ismalicious/apis/ismalicious-threat-intelligence-api/llms.txt) · [OpenAPI document](https://skmtc.dev/ismalicious/apis/ismalicious-threat-intelligence-api/revisions/fe46a64acc79?raw)
