Quickstart
Send a User-Agent and, when available, an IP address to /v1/inspect using your RequestIntel API key. Include both for the most complete result.
curl -X POST https://api.requestintel.dev/v1/inspect \
-H "Authorization: Bearer ri_live_xxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"ip": "20.171.207.12",
"user_agent": "GPTBot/1.2"
}'Authentication
Authenticate every API request with an active API key created in your RequestIntel account.
Treat API keys as secrets and never expose them in client-side code.
POST/v1/inspect
User-Agent identifies the claimed crawler. IP and request headers provide additional evidence that RequestIntel can use to verify that claim.
Send a User-Agent for every request and include the IP address when available for the most complete V1 result.
| Parameter | Type | Required | Description |
|---|---|---|---|
| ip | string | No | IPv4 or IPv6 address to inspect. Include it when available for network verification. |
| user_agent | string | Yes | User-Agent reported by the request. |
| headers | object | No | Optional additional request headers. Accepted by the API for forward compatibility, but headers do not currently affect V1 bot identification or verification. |
A User-Agent-only request can identify a claim, but cannot independently verify it.
{
"ip": "20.171.207.12",
"user_agent": "GPTBot/1.2",
"headers": {
"accept": "*/*"
}
}{
"request_id": "req_01K...",
"is_bot": true,
"bot": {
"id": "openai-gptbot",
"name": "GPTBot",
"organization": "OpenAI",
"category": "ai_crawler",
"purposes": ["training"]
},
"identity": {
"status": "verified",
"signals": [
{ "type": "user_agent", "result": "match" },
{ "type": "official_ip_range", "result": "match" }
]
},
"network": {
"asn": 8075,
"organization": "Microsoft Corporation"
}
}When no supported bot is identified, bot, identity, and network are null. is_bot: false does not prove the request came from a human.
Integration examples
Choose your server runtime. Every example calls /v1/inspect directly with native fetch.
Node.js 20+: inspect a request
Run this on your server with native fetch. Modern Node/server runtimes support the included five-second AbortSignal timeout.
// Node.js 20+ (run this only on your server)
async function main() {
const apiKey = process.env.REQUESTINTEL_API_KEY;
if (!apiKey) {
console.error("REQUESTINTEL_API_KEY is not configured");
process.exitCode = 1;
return;
}
const response = await fetch("https://api.requestintel.dev/v1/inspect", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
ip: "203.0.113.24",
user_agent: "Mozilla/5.0 ...",
}),
signal: AbortSignal.timeout(5000),
});
const result = await response.json().catch(() => null);
if (!response.ok) {
console.error(result?.error?.message ?? `Request failed: ${response.status}`);
process.exitCode = 1;
return;
}
console.log(result.identity?.status ?? "not a supported bot");
}
main().catch(() => {
console.error("RequestIntel could not be reached. Check the network and try again.");
process.exitCode = 1;
});The Node.js examples use AbortSignal.timeout(5000), which is available in modern Node/server runtimes. Omit it or use your platform's cancellation support in runtimes that do not provide it.
POST/v1/inspect/batch
Inspect between 1 and 100 requests in one call. Every item must include a User-Agent and may include an IP address. The output order matches the input order.
{
"requests": [
{
"ip": "20.171.207.12",
"user_agent": "GPTBot/1.2"
},
{
"ip": "192.0.2.7",
"user_agent": "Mozilla/5.0"
}
]
}{
"results": [
{
"request_id": "req_01K...",
"is_bot": true,
"bot": {
"id": "openai-gptbot",
"name": "GPTBot",
"organization": "OpenAI",
"category": "ai_crawler",
"purposes": ["training"]
},
"identity": {
"status": "verified",
"signals": [
{ "type": "user_agent", "result": "match" },
{ "type": "official_ip_range", "result": "match" }
]
},
"network": null
}
]
}Integration examples
Choose your server runtime to send a batch directly to /v1/inspect/batch.
Node.js 20+: batch inspection
Send up to 100 inspections in one request with native fetch.
async function main() {
const apiKey = process.env.REQUESTINTEL_API_KEY;
if (!apiKey) {
console.error("REQUESTINTEL_API_KEY is not configured");
process.exitCode = 1;
return;
}
const requests = [
{ ip: "203.0.113.24", user_agent: "Mozilla/5.0 ..." },
{ ip: "2001:db8::24", user_agent: "ExampleBot/1.0" },
];
if (requests.length > 100) {
console.error("Batch requests are limited to 100 items");
process.exitCode = 1;
return;
}
const response = await fetch("https://api.requestintel.dev/v1/inspect/batch", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ requests }),
signal: AbortSignal.timeout(5000),
});
const result = await response.json().catch(() => null);
if (!response.ok) {
console.error(result?.error?.message ?? `Request failed: ${response.status}`);
process.exitCode = 1;
return;
}
// result.results is in the same order as requests.
}
main().catch(() => {
console.error("RequestIntel could not be reached. Check the network and try again.");
process.exitCode = 1;
});A batch containing 100 items is one HTTP request for rate limiting, but consumes 100 API lookups from the account's monthly allowance.
Batch quota checks are atomic. If the account does not have enough remaining monthly allowance for the entire batch, the whole batch is rejected before inspection begins. No items are processed and no lookup allowance is consumed. For example, if an account has 7 lookups remaining and sends a batch containing 10 items, the full batch is rejected.
POST/v1/ua
Match one User-Agent against RequestIntel's supported crawler identities. This is claim matching only: it does not perform IP, DNS, or ASN verification.
{
"user_agent": "GPTBot/1.2"
}{
"matched": true,
"bots": [
{
"id": "openai-gptbot",
"name": "GPTBot",
"organization": "OpenAI",
"category": "ai_crawler"
}
]
}The response contains at most one bot, selected using RequestIntel's deterministic User-Agent match. A result with matched: false returns an empty bots array.
POST/v1/ip
Match one IPv4 or IPv6 address against supported official crawler network ranges. This is range matching only: it does not establish that a crawler claim is verified.
{
"ip": "20.171.207.12"
}{
"matched": true,
"bots": [
{
"id": "openai-gptbot",
"name": "GPTBot",
"organization": "OpenAI",
"category": "ai_crawler"
}
]
}An IP address can match more than one supported bot. In that case, every matched bot is returned. RequestIntel does not expose the ranges or source records used for matching.
GET/v1/me
/v1/me inspects the request that is calling the RequestIntel API. It requires API-key authentication and is intended for integration testing and diagnostics.
- It is a diagnostic convenience endpoint, not a replacement for sending an end-user request to
/v1/inspect. - Reverse-proxy or trusted-proxy configuration can affect which source IP RequestIntel sees.
- It returns the same core response shape as an inspection.
curl https://api.requestintel.dev/v1/me \
-H "Authorization: Bearer ri_live_xxxxxxxxx"Response meanings
These definitions apply to every response returned by /v1/inspect and each item in /v1/inspect/batch.
is_bot: false means RequestIntel did not match the request to a supported known bot identity. It does not prove that the request came from a human. In that case, bot, identity, and network are null.
verified- The claimed bot identity has been independently confirmed using supported authoritative verification data.
unverified- The request matches a known bot identity, but RequestIntel does not currently have enough independent evidence to prove the identity. It does not mean fake.
spoofed- A supported authoritative verification check contradicts the claimed crawler identity.
bot.organization is the organisation operating the identified crawler.
network.organization is the organisation associated with the source IP's network/ASN. Network enrichment may be null, is not guaranteed for every request, and does not mean the crawler operator owns that infrastructure.
Errors & limits
Request-rate limit
API requests are rate-limited per account at the rate included with your plan. All active API keys share that account-wide limit; a batch is one rate-limited HTTP request.
Monthly lookup allowance
Monthly usage is counted per inspected item at the account level. This allowance is separate from the request-rate limit.
Monthly limit exceeded
429 Too Many Requests
{
"error": {
"code": "monthly_limit_exceeded",
"message": "monthly limit exceeded"
}
}Monthly limits are hard limits. RequestIntel does not automatically charge overages. Browse supported bots and crawlers to see the public reference coverage.