senapati
Documentation index

Bulk endpoints

Every product has a bulk twin that takes an array instead of a single value, runs the lookups concurrently on our side and returns one result per item. One HTTP request, one credit charge, one line in your usage log.

POST/api/bulk/check-ipCosts 1 credit per itemAPI key

Bulk Check Ip

The five bulk routes

RouteBodyPer itemSingle-item docs
POST /api/bulk/check-ip{ "ips": [...] }1 creditIP reputation
POST /api/bulk/domain-reputation{ "domains": [...] }1 creditDomain reputation
POST /api/bulk/url-reputation{ "urls": [...] }2 creditsURL reputation
POST /api/bulk/email-reputation{ "emails": [...] }1 creditEmail verification
POST /api/bulk/dns-lookup{ "domains": [...], "record_type": "ALL" }1 creditDNS lookup
  • 1 to 100 items per request. Larger arrays are rejected with 422 before anything is charged.
  • The charge is items × price for the whole batch. If the balance cannot cover the whole batch the request fails with 402 and nothing runs.
  • Items are independent: a malformed or failing item is reported in its own results[] entry with success: false and an error, while the rest complete. Failed items are still charged.
  • A bulk call counts as a single request toward the per-second allowance.

Request

JSON body
FieldTypeDescription
ips*string[]

Authenticate with API key. Send it as the X-API-Key header.

curl -X POST "https://api.senapati.io/api/bulk/check-ip" \
  -H "X-API-Key: $SENAPATI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ips":["8.8.8.8","1.1.1.1"]}'

Response

Every success is wrapped in { "data": … } with a request_id; the fields below describe data. See Errors for the failure shape.

response: 200 OKBulkData
{
"request_id": "req_8f2c1a7e",
"timestamp": "2026-08-27T12:01:12.627349+00:00",
"data": {
"product": "check-ip",
"total_items": 2,
"successful": 2,
"failed": 0,
"credits_charged": 2,
"results": [
{
"input": "8.8.8.8",
"status": "success",
"result": {
"ip": "8.8.8.8",
"version": "IPv4",
"blacklists": {
"engines": {
"0": {
"name": "0spam",
"detected": false,
"reference": "https://0spam.org/",
"elapsed_ms": 11
},
"5": {
"name": "Backscatterer",
"detected": false,
"reference": "https://www.backscatterer.org/",
"elapsed_ms": 10
},
"6": {
"name": "Barracuda_Reputation_BL",
"detected": false,
"reference": "https://barracudacentral.org/lookups",
"elapsed_ms": 12
},
"…": "60 more engines omitted from this example"
},
"detections": 0,
"engines_count": 63,
"detection_rate": "0%",
"scan_time_ms": 2004
},
"information": {
"reverse_dns": "dns.google",
"is_eu": false,
"continent_code": "NA",
"continent_name": "North America",
"country_code": "US",
"country_name": "United States",
"currency": "USD",
"currency_name": "US Dollar",
"currency_name_plural": "US dollars",
"currency_symbol": "$",
"currency_symbol_native": "$",
"calling_code": "",
"emoji_flag": "🇺🇸",
"emoji_flag_unicode": "U+1F1FA U+1F1F8",
"region_name": "",
"city_name": "",
"latitude": 37.751,
"longitude": -97.822,
"isp": "Google LLC",
"asn": "AS15169",
"is_bogon": false,
"is_spamhaus_drop": false,
"is_fake_bot": false,
"is_google_bot": false,
"is_search_engine_bot": false,
"related_service_name": "",
"related_service_domain": "",
"related_service_type": "",
"is_major_provider_spf_ip": false,
"is_public_dns": true,
"cloud_provider": "",
"cloud_provider_domain": "",
"aws_service": "",
"is_google_service": true,
"edge_service": "",
"edge_service_domain": "",
"is_satellite": false,
"is_hosting": false
},
"asn": {
"asn": "AS15169",
"asname": "Google LLC",
"route": "",
"status": "active",
"org": "Google LLC",
"country_code": "",
"created": "",
"days_since_created": 0,
"updated": "",
"days_since_updated": 0,
"address": "",
"abuse_email": "",
"domain": "",
"total_ipv4_prefixes": 0,
"total_ipv4_ips": 0,
"total_ipv6_prefixes": 0,
"type": "business",
"rir": ""
},
"anonymity": {
"is_proxy": false,
"is_webproxy": false,
"is_residential_proxy": false,
"is_vpn": false,
"is_hosting": false,
"is_relay": false,
"is_tor": false
},
"risk_score": {
"result": 0
},
"elapsed_ms": 2004,
"sia_enrichment": null
},
"error": null
},
"1 more results omitted"
],
"elapsed_ms": 2860
}
}

Only the first item's result is shown; each entry mirrors the single-lookup response for that product.

data · BulkData
FieldTypeDescription
product*string
total_items*integer
successful*integer
failed*integer
credits_charged*integer
results*BulkResultItem[]
↳ input*string
↳ status*string'success' or 'error'
↳ resultobject | null
↳ errorstring | null
elapsed_ms*integer

Errors

  • 401missing or invalid API key / token
  • 402not enough credits on the account
  • 422the request body or a parameter failed validation

Per-item shape

data.results[] · BulkResultItem
FieldTypeDescription
input*string
status*string'success' or 'error'
resultobject | null
errorstring | null

result is the same object the single endpoint returns under data, so parsing code can be shared.