CRDF Threat Center API (1.4.3)

Download OpenAPI specification:

API for submitting and querying malicious URLs, managing false positives, and accessing WHOIS data.

Getting Started

1. Obtain an API Key

To use this API, you must obtain an API key (called a token) by registering at: https://threatcenter.crdf.fr/api.html

2. Make Your First Request

Conventional CRDF API methods use HTTP POST with Content-Type: application/json. The STIX 2.1 exports and TAXII 2.1 resources documented below use HTTP GET with Bearer authentication and their standard media types. All of these CTI resources, including TAXII discovery, are reserved for licensed private accounts.

Modern approach (recommended): Use the Authorization header:

curl -X POST https://threatcenter.crdf.fr/api/v1/info_key.json \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your_api_key_here" \
  -d '{
    "method": "info_key"
  }'

Alternative: You can also use the X-API-Key header:

curl -X POST https://threatcenter.crdf.fr/api/v1/info_key.json \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key_here" \
  -d '{
    "method": "info_key"
  }'

Legacy (deprecated): For backward compatibility, the token can still be sent in the request body:

curl -X POST https://threatcenter.crdf.fr/api/v1/info_key.json \
  -H "Content-Type: application/json" \
  -d '{
    "token": "your_api_key_here",
    "method": "info_key"
  }'

3. Understanding Responses

Conventional POST API responses follow this standard format. Native STIX exports and TAXII resources instead follow their respective standards:

Success Response:

{
  "error": false,
  "error_code": null,
  "message": null,
  "data": { ... }
}

Error Response:

{
  "error": true,
  "error_code": "ErrorCode",
  "message": "Human-readable error message",
  "data": null
}

4. Error Handling

  • Always check the error field first
  • Use error_code for programmatic error handling
  • Check HTTP status codes (200 = success, 4xx = client error, 5xx = server error)
  • For rate limiting (429) and retryable saturation (503), honor the Retry-After response header and implement exponential backoff
  • For invalid tokens (401), verify your API key is correct and active

5. Best Practices

  • Rate Limiting: Respect the rate limits configured for your API key (default: 2 requests/minute, 200/day)
  • Error Handling: Always implement proper error handling and retry logic with exponential backoff
  • Pagination: Use cursor-based pagination for large datasets
  • Permissions: Check required permissions before calling endpoints
  • URL Validation: Validate URLs client-side before submission
  • Security: Never expose your API key in client-side code. Use headers (Authorization or X-API-Key) instead of body when possible
  • Request Size: Keep request bodies under 10MB and arrays under 10,000 elements
  • JSON Depth: Avoid deeply nested JSON structures (max 32 levels)
  • IP Consistency: Use your API key from a single IP address to avoid triggering distributed attack detection

6. API Versioning

This is API version 1.4.3. The API follows semantic versioning:

  • Major version (1.x.x): Breaking changes
  • Minor version (x.0.x): New features, backward compatible
  • Patch version (x.x.1): Bug fixes, backward compatible

The current version is stable. Breaking changes will be announced in advance and documented in the Changelog.

For the latest changes, see: CHANGELOG.md

Security Features

The API implements multiple layers of security protection to ensure service availability and prevent abuse:

  • Rate limiting and quota management: Per-token, per-IP and per-endpoint rate limiting with burst detection
  • Request validation and size limits: JSON body size, depth, and array size validation
  • Automatic protection against abuse patterns: Distributed attack detection, IP and key blacklisting
  • Secure authentication mechanisms: Token caching, anti-enumeration delays, header-based authentication
  • Global IP rate limiting: Additional protection at the IP address level across all tokens
  • API anomaly monitoring: Detection of request spikes, excessive scoring requests, high 4xx rates, export scraping and token/IP fan-out
  • Public-safe error responses: Server errors and sensitive internal details are never exposed in API responses

Security Best Practices

To ensure secure and reliable API usage, follow these best practices:

API Key Security

  • Never expose your API key in client-side code, public repositories, or logs
  • Store API keys securely using environment variables or secure key management systems
  • Rotate API keys regularly if you suspect they may have been compromised
  • Use different API keys for different environments (development, staging, production)

Request Handling

  • Validate input data before sending requests to the API
  • Implement proper error handling with exponential backoff for rate limit errors
  • Respect rate limits to avoid service interruptions
  • Use pagination for large datasets instead of sending very large requests

Error Handling

  • Always check the error field in API responses before processing data
  • Use error_code for programmatic error handling (don't rely on message text)
  • Implement retry logic with exponential backoff for transient errors (429, 500)
  • Log errors appropriately for debugging while avoiding exposure of sensitive information

Rate Limiting

  • Monitor your usage to stay within rate limits
  • Implement request queuing if you need to make many requests
  • Use appropriate request intervals to avoid triggering burst protection
  • Contact support if you need higher rate limits for legitimate use cases

Rate Limits

  • Daily quota: 200 requests per API key (configurable per key)
  • Per-minute quota: 2 requests per API key (configurable per key)
  • Burst protection: Maximum 20 requests in 10 seconds (automatic IP and key blacklisting for 5 minutes if exceeded)
  • Global IP limits: 100 requests/minute and 1000 requests/hour per IP address (across all tokens)
  • Endpoint limits: sensitive endpoints have additional method-specific limits. These limits are additive to the API-key and IP quotas.

Default Endpoint Rate Limits

Effective limits may be customized per API key. The defaults below document the production safety policy:

Endpoint group Endpoint(s) Default limit
AI search ai_search_domain, ai_search_ioc 180/min, 5,000/hour, 100,000/day
AI bulk search ai_search_bulk 60/min, 1,000/hour, 10,000/day
AI queue status ai_status_ioc 240/min, 8,000/hour, 150,000/day
AI profile/list ai_profile_ioc, ai_list_entries 60-120/min depending on endpoint
AI scoring ai_score_domain, ai_score_ioc 30/min, 600/hour, 5,000/day
AI bulk scoring ai_score_bulk 10/min, 150/hour, 1,500/day
AI export ai_export_delta 10/min, 120/hour, 1,000/day
STIX / TAXII CTI read cti_export_*, taxii_objects, taxii_manifest 30/min, 500/hour, 5,000/day
URL submission submit_url, add_urls 20-30/min depending on endpoint
WHOIS / NRD / URL lists whois_*, get_nrd, list_malicious_domains endpoint-specific read quotas

If an endpoint-specific limit is exceeded, the API returns 429 EndpointRateLimitExceeded.

API Anomaly Monitoring

The API records security metadata for sensitive calls. Payloads are not logged verbatim; a SHA-256 payload hash and request size are retained for audit and abuse detection.

The following patterns may be flagged:

  • sudden request spikes for a single key
  • excessive ai_score_* usage
  • excessive 4xx responses
  • one token used from too many IP addresses
  • unusually frequent ai_export_delta usage

Anomaly events are used for operational review, throttling decisions and abuse investigation. They do not change endpoint response schemas.

Public Error Safety

Public API error responses are intentionally sanitized. They do not expose SQL, filesystem paths, stack traces, model thresholds, registry paths, internal calibration details, or raw secrets. Use error_code for client logic; do not depend on the exact human-readable message.

AI Response Safety

AI endpoints expose public-safe verdict, category, score, queue state and evidence summaries. They do not expose SQL row identifiers, raw component scores, private thresholds, calibration details, model registry paths or internal request IDs. Queue polling uses an opaque job_ref when a public reference is useful.

Permissions

API keys expose modern scopes in the permissions field returned by info_key.json. The legacy special_methods_allowed string is still returned for backward compatibility.

Access levels:

Access level Typical scopes Result
Free validated API key none or public actions only Public submission and tracking only; no private CTI data
Private licensed account unlimited, private, lookup, feeds, AI, WHOIS, NRD Contractual private CTI access
Redistribution license Private licensed scopes plus redistribution Redistribution only within written approval
CRDF internal Operational scopes, optionally urls:add Direct database curation and internal maintenance

urls:add and its legacy alias add_urls are not customer-license scopes. They are reserved for CRDF internal operations.

Scope Description
lookup Search URLs against CRDF Threat Center data
feeds:domains Retrieve malicious domain feeds
feeds:urls Reserved for malicious URL feeds
feeds:ips Reserved for malicious IP feeds
ai:score Score domains, URLs or IPs with the CRDF AI engine
ai:search Search AI results and retrieve AI status/profile data
ai:list List or export already scored AI entries
cti:ai Export the CRDF AI collection as STIX 2.1
cti:url-telemetry Export the CRDF URL Telemetry collection as STIX 2.1
taxii:read Discover and synchronize authorized collections using TAXII 2.1
whois Retrieve WHOIS enrichment data
nrd Retrieve Newly Registered Domains
urls:add Add URLs directly to the threat database
urls:add:permanent Mark directly inserted URLs as permanent
urls:add:bypass-timeout Bypass the recent-removal timeout during direct insertion
false_positive:auto_accept Auto-accept a false-positive deletion request when requested
redistribution Redistribution has been explicitly approved in writing

Legacy permissions are mapped automatically:

Legacy permission Modern scope mapping
private Licensed lookup/feed/AI scopes plus cti:ai, cti:url-telemetry and taxii:read
add_urls urls:add, urls:add:permanent, urls:add:bypass-timeout
fp_force_deleted false_positive:auto_accept
unlimited Usage flag only; disables key-level throttling but does not grant data access by itself

Endpoint Permissions Summary

Endpoint Required Permissions Optional Permissions
info_key.json None -
submit_url.json None -
submit_get_info.json None -
search_urls.json lookup -
ai_score_domain.json ai:score -
ai_search_domain.json ai:search -
ai_score_ioc.json ai:score URL, domain name or IP address
ai_search_ioc.json ai:search URL, domain name or IP address
ai_status_ioc.json ai:search URL, domain name or IP address
ai_profile_ioc.json ai:search URL, domain name or IP address
ai_score_bulk.json ai:score Up to 100 URL/domain/IP IOCs
ai_search_bulk.json ai:search Up to 500 URL/domain/IP IOCs
ai_export_delta.json ai:list Incremental v14 AI export
ai_list_entries.json ai:list -
add_urls.json urls:add urls:add:permanent, urls:add:bypass-timeout
false_positive_ng.json None false_positive:auto_accept (for auto-acceptance)
false_positive_getinfos.json None -
whois_get.json whois -
whois_list_domains.json whois -
get_nrd.json nrd -
list_malicious_domains.json feeds:domains -
GET /cti/stix/crdf-ai private plus cti:ai Native STIX 2.1 export for licensed private accounts
GET /cti/stix/url-telemetry private plus cti:url-telemetry Native STIX 2.1 export for licensed private accounts
GET /api/taxii2/... private, taxii:read, plus the collection scope when applicable TAXII 2.1 discovery and read-only synchronization for licensed private accounts

Submission and false-positive references are scoped to the API key that created them. They are opaque tracking values and should not be treated as shared identifiers between clients.

Reference Format

References returned by the API follow this format:

  • Format: YYYYMMDD + strong random suffix
  • Example: 20260418a1b2c3d4e5f6
    • 20260418 = Date
    • a1b2c3d4e5f6 = Opaque random suffix for uniqueness
  • Used in: submit_url, false_positive_ng

Pagination

Several endpoints use cursor-based pagination for efficient data retrieval:

How It Works

  1. First Request: Use cursor: 0 to start from the beginning
  2. Response: Contains next_cursor with the ID of the last returned record
  3. Next Request: Use the next_cursor value as the new cursor
  4. End: When next_cursor is null, you've reached the end

Example Flow

// Request 1
{ "cursor": 0, "per_page": 100 }
// Response: { "data": [...], "next_cursor": 100 }

// Request 2
{ "cursor": 100, "per_page": 100 }
// Response: { "data": [...], "next_cursor": 200 }

// Request 3
{ "cursor": 200, "per_page": 100 }
// Response: { "data": [...], "next_cursor": null }  // End reached

Endpoints with Pagination

  • whois_list_domains.json - Cursor: ID_DOMAIN
  • get_nrd.json - Cursor: NRD ID
  • list_malicious_domains.json - Cursor: Record ID

Status Values and Verdicts

Submission States (submit_get_info)

State Description
new Submission received, not yet processed
processing Currently being analyzed by experts
end Processing completed

URL States (in urls_arr)

State Description
accepted URL was accepted and added to database
rejected URL was rejected (e.g., whitelisted, invalid)
pending Still being processed
error An error occurred during processing

Verdicts

Verdict Description
whitelisted URL is on the whitelist
malicious Confirmed as malicious
suspicious Suspicious but not confirmed
clean Determined to be clean
deleted False positive, removed from database

False Positive Status

Status Description
new Request submitted, awaiting review
reviewing Under expert review
finished Review completed

False Positive Verdict

Verdict Description
deleted URL was removed from blacklist
rejected Request was rejected
pending Still pending

Global Error Codes

The following errors can be returned by any endpoint. Each error response follows the standard format:

{
  "error": true,
  "error_code": "ErrorCode",
  "message": "Human-readable error message",
  "data": null
}

Global Error Codes Table

Error Code HTTP Status Description
InvalidContentType 415 The request's Content-Type header is not application/json
InvalidInputJson 400 The request body is not valid JSON
InvalidRequestType 405 The HTTP method is not allowed (only POST is accepted)
InvalidMethod 400 The method field does not match any supported endpoint
InvalidToken 401 The provided API key does not exist or is not active
MissingPermission 403 The API key is valid but does not grant the required scope
RequestExceed 429 Rate limit exceeded for this API key (per-minute or daily quota)
EndpointRateLimitExceeded 429 Rate limit exceeded for this specific endpoint
IPBlacklisted 429 The client IP has been temporarily blocked due to burst detection
KeyBlacklisted 429 The API key has been temporarily blocked due to abuse
IPRateLimitExceeded 429 The IP address has exceeded global rate limits (across all tokens)
DistributedAttackDetected 429 Suspicious activity detected: token used from multiple IPs simultaneously
RequestBodyTooLarge 413 The request body exceeds the maximum allowed size (10MB)
ArraySizeExceeded 400 An array in the request exceeds the maximum allowed size (10,000 elements default)
InvalidRequest 400 A required JSON parameter is missing or malformed
InternalError 500 An internal error occurred
NotImplemented 501 The requested method is not implemented

Error Response Details

Authentication Errors (401)

  • InvalidToken: The API key provided does not exist, is inactive, or has been revoked.
    • Solution: Verify your API key is correct and active. Check your API key status using the info_key endpoint.
    • Note: Invalid token responses include a delay to prevent token enumeration attacks.

Authorization Errors (403)

  • MissingPermission: The API key is valid, but the requested endpoint requires a scope that the key does not have.
    • Solution: Call info_key.json and inspect permissions before calling private endpoints.
    • Details: The response includes data.required_permission, data.granted_permissions, and data.compat_error_code.

Rate Limiting Errors (429)

Multiple rate limiting mechanisms can trigger 429 errors:

  • RequestExceed: Token-level rate limit exceeded (per-minute or daily quota)

    • Solution: Wait for the rate limit window to reset or request higher limits from support
    • Details: Limits are configurable per API key (default: 2/minute, 200/day)
  • EndpointRateLimitExceeded: Endpoint-specific rate limit exceeded

    • Solution: Slow down calls to the specific endpoint, use pagination, or queue client-side retries
    • Details: Sensitive endpoints such as ai_score_* and ai_export_delta have stricter limits than read-only search endpoints
  • IPBlacklisted: IP address temporarily blocked due to burst detection

    • Solution: Wait for the block to expire (5 minutes) or reduce request frequency
    • Details: Triggered when exceeding burst threshold (20 requests in 10 seconds)
  • KeyBlacklisted: API key temporarily blocked due to abuse

    • Solution: Contact support or wait for ban to expire (5 minutes)
    • Details: Can be triggered by burst detection or distributed attack detection
  • IPRateLimitExceeded: IP-level rate limit exceeded (across all tokens)

    • Solution: Reduce request frequency from this IP address
    • Details: Global limits: 100 requests/minute, 1000 requests/hour per IP
  • DistributedAttackDetected: Suspicious activity detected: token used from multiple IPs simultaneously

    • Solution: Use token from a single IP address or contact support
    • Details: Triggered when same token is used from more than 5 different IPs in 5 minutes

Request Validation Errors (400)

  • InvalidInputJson: JSON parsing failed

    • Solution: Validate JSON syntax before sending requests
    • Details: Maximum JSON depth is 32 levels to prevent stack overflow attacks
  • InvalidMethod: Unknown method name

    • Solution: Check the method name spelling and ensure it's in the supported list
  • InvalidRequest: Missing required parameters

    • Solution: Ensure all required fields (token, method, etc.) are present
  • ArraySizeExceeded: Array too large

    • Solution: Split large arrays into multiple requests
    • Details: Default limit is 10,000 elements per array (configurable per endpoint)

Request Size Errors (413)

  • RequestBodyTooLarge: Request body exceeds maximum size
    • Solution: Reduce the size of your request body
    • Details: Maximum body size is 10MB

Server Errors (500, 501)

  • InternalError: Internal server error

    • Solution: Retry the request. If persistent, contact support
  • NotImplemented: Method not implemented

    • Solution: Check API version and documentation for available methods

Error Handling Best Practices

  1. Always check the error field first in the response
  2. Use error_code for programmatic error handling (don't rely on message text)
  3. Implement exponential backoff for 429 errors
  4. Log error details for debugging (error_code, message, HTTP status)
  5. Handle 401 errors by verifying API key validity
  6. Respect rate limits to avoid 429 errors
  7. Validate input client-side to prevent 400 errors
  8. Do not parse internal details from messages. Error messages are sanitized and may be generalized for security.

Changelog

For detailed information about changes, new features, and deprecations, see: CHANGELOG.md

api_key

API key management

Get information about the API key

Retrieve metadata about the API key including rate limits, usage statistics, and permissions.

This endpoint is public (no permission required).

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
token
string

Your API key

method
required
string
Value: "info_key"

Responses

Request samples

Content type
application/json
{
  • "token": "your_api_key_here",
  • "method": "info_key"
}

Response samples

Content type
application/json
{
  • "error": false,
  • "error_code": null,
  • "message": null,
  • "data": {
    }
}

submit_malicious_url

Submit malicious URLs for expert analysis

Submit malicious URLs to CRDF Labs

Submit malicious URLs for expert analysis. Maximum 250 unique URLs per request.

This endpoint is public (no permission required).

Authorizations:
ApiKeyAuth
header Parameters
Idempotency-Key
string [ 8 .. 128 ] characters ^[A-Za-z0-9._:-]{8,128}$

Stable client-generated key used to safely retry the same URL set without creating a duplicate submission. Reusing a key with a different URL set returns 409 IdempotencyConflict.

Request Body schema: application/json
required
token
string

Your API key

method
required
string
Value: "submit_url"
urls
required
Array of strings <uri> [ 1 .. 250 ] items [ items <uri > [ 3 .. 10000 ] characters ]

Array of malicious URLs to submit (maximum 250 unique URLs, each URL must be 3-10000 characters)

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{}

Get information on submitting malicious URLs

Retrieve status and details for a previously submitted set of URLs.

This endpoint is public (no permission required). A reference is only visible to the API key that created the submission.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
token
string

Your API key

method
required
string
Value: "submit_get_info"
ref
required
string^[A-Za-z0-9]+$

Opaque alphanumeric reference returned by submit_url

Responses

Request samples

Content type
application/json
{
  • "token": "your_api_key",
  • "method": "submit_get_info",
  • "ref": "20260723a1b2c3d4e5f6"
}

Response samples

Content type
application/json
{}

urls

URL management and search

Search a list of URLs in the database

Check a list of URLs against the blacklisted database.

Required Permission: lookup

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
token
string

Your API key

method
required
string
Value: "search_urls"
urls
required
Array of strings

List of URLs to check

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "error": false,
  • "error_code": null,
  • "message": null,
  • "data": []
}

Add URLs to the CRDF Threat Center

Add malicious URLs to the database. Maximum 10,000 URLs per request.

Required Permission: urls:add

Setting permanent additionally requires urls:add:permanent. Setting bypass_timeout additionally requires urls:add:bypass-timeout. Legacy CRDF-managed keys carrying add_urls retain both capabilities.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
token
string

Your API key

method
required
string
Value: "add_urls"
urls
required
Array of strings [ 1 .. 10000 ] items [ items [ 1 .. 10000 ] characters ]

Array of URLs to add (maximum 10000 URLs)

category
string

Threat category (default "Malicious:URL")

bypass_timeout
integer
Enum: 0 1

If 1, ignore recent unblacklist timeout (requires urls:add:bypass-timeout)

advert
integer
Enum: 0 1

If 1, mark as advertisement

permanent
integer
Enum: 0 1

If 1, URL cannot be removed by false positive system (requires urls:add:permanent)

Responses

Request samples

Content type
application/json
{
  • "token": "your_api_key",
  • "method": "add_urls",
  • "urls": []
}

Response samples

Content type
application/json
{
  • "error": false,
  • "error_code": null,
  • "message": null,
  • "data": [
    ]
}

List malicious domain names contained in the database

List malicious domain names contained in the database with cursor-based pagination.

Required Permission: feeds:domains

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
token
string

Your API key

method
required
string
Value: "list_malicious_domains"
cursor
integer >= 0
Default: 0

Last-seen record ID (exclusive). Use 0 to start from the first record.

Pagination: See pagination documentation in whois_list_domains.json endpoint.

per_page
integer [ 1 .. 500 ]
Default: 100

Number of records to return per page (max 500)

Responses

Request samples

Content type
application/json
{
  • "token": "your_api_key",
  • "method": "list_malicious_domains",
  • "cursor": 0,
  • "per_page": 100
}

Response samples

Content type
application/json
{
  • "error": false,
  • "error_code": null,
  • "message": null,
  • "data": {}
}

ai

AI scoring and AI database access

Score a domain name with the AI engine

Submit a domain name to the AI engine and return the latest available AI result.

If the domain is newly queued or currently being processed, the response returns a processing state.

Required Permission: ai:score

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
token
string

Your API key

method
required
string
Value: "ai_score_domain"
domain_name
required
string

Domain name to score

Responses

Request samples

Content type
application/json
{
  • "token": "your_api_key",
  • "method": "ai_score_domain",
  • "domain_name": "example.com"
}

Response samples

Content type
application/json
{
  • "error": false,
  • "error_code": null,
  • "message": null,
  • "data": {
    }
}

Search a domain in the AI database

Retrieve the latest scored AI entry for a single domain name.

Required Permission: ai:search

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
token
string

Your API key

method
required
string
Value: "ai_search_domain"
domain_name
required
string

Domain name to search

Responses

Request samples

Content type
application/json
{
  • "token": "your_api_key",
  • "method": "ai_search_domain",
  • "domain_name": "example.com"
}

Response samples

Content type
application/json
{
  • "error": false,
  • "error_code": null,
  • "message": null,
  • "data": {
    }
}

Score a URL, domain or IP with the AI engine

Submit a generic IOC to the AI engine and return the latest available v14 result plus queue status.

If the IOC has not been scored yet, this endpoint enqueues it for analysis and returns a queue status. Use ai_status_ioc to poll processing state and ai_search_ioc for strict read-only lookup.

Required Permission: ai:score

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
token
string
method
required
string
Value: "ai_score_ioc"
ioc
required
string

HTTP(S) URL, domain name or IP address

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "error": false,
  • "error_code": null,
  • "message": null,
  • "data": { }
}

Search a URL, domain or IP in the AI database

Retrieve the latest stored v14 AI result for an already scored IOC.

This endpoint is strictly read-only. It does not enqueue new analysis. If the IOC is not already materialized in the AI database, the response is 404 IocNotFound. Use ai_score_ioc to enqueue or score a new URL, domain or IP.

Required Permission: ai:search

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
token
string
method
required
string
Value: "ai_search_ioc"
ioc
required
string

HTTP(S) URL, domain name or IP address

Responses

Request samples

Content type
application/json
{
  • "token": "string",
  • "method": "ai_search_ioc",
  • "ioc": "string"
}

Response samples

Content type
application/json
{
  • "error": false,
  • "error_code": null,
  • "message": null,
  • "data": { }
}

Get AI queue status for a URL, domain or IP

Return the current queue state and latest result if one is already materialized.

Required Permission: ai:search

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
token
string
method
required
string
Value: "ai_status_ioc"
ioc
required
string

HTTP(S) URL, domain name or IP address

Responses

Request samples

Content type
application/json
{
  • "token": "string",
  • "method": "ai_status_ioc",
  • "ioc": "string"
}

Response samples

Content type
application/json
{
  • "error": false,
  • "error_code": null,
  • "message": null,
  • "data": { }
}

Get a public-safe AI profile for a URL, domain or IP

Return a summarized v14 profile, queue status and public-safe evidence fields without raw private payloads.

Required Permission: ai:search

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
token
string
method
required
string
Value: "ai_profile_ioc"
ioc
required
string

HTTP(S) URL, domain name or IP address

Responses

Request samples

Content type
application/json
{
  • "token": "string",
  • "method": "ai_profile_ioc",
  • "ioc": "string"
}

Response samples

Content type
application/json
{
  • "error": false,
  • "error_code": null,
  • "message": null,
  • "data": { }
}

Search multiple IOCs in the AI database

Search up to 500 URL/domain/IP IOCs in one private request. This endpoint does not enqueue new scans.

Required Permission: ai:search

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
token
string
method
required
string
Value: "ai_search_bulk"
iocs
required
Array of strings [ 1 .. 500 ] items

Responses

Request samples

Content type
application/json
{
  • "token": "string",
  • "method": "ai_search_bulk",
  • "iocs": [
    ]
}

Response samples

Content type
application/json
{
  • "error": false,
  • "error_code": null,
  • "message": null,
  • "data": { }
}

Queue and score multiple IOCs with the AI engine

Queue up to 100 URL/domain/IP IOCs in one private request and return the latest available result for each.

Required Permission: ai:score

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
token
string
method
required
string
Value: "ai_score_bulk"
priority
boolean
Default: true
iocs
required
Array of strings [ 1 .. 100 ] items

Responses

Request samples

Content type
application/json
{
  • "token": "string",
  • "method": "ai_score_bulk",
  • "priority": true,
  • "iocs": [
    ]
}

Response samples

Content type
application/json
{
  • "error": false,
  • "error_code": null,
  • "message": null,
  • "data": { }
}

Export changed AI v14 rows

Export materialized AI rows updated after a date. Supports cursor pagination and optional verdict, IOC type, category and score filters.

Required Permission: ai:list

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
token
string
method
required
string
Value: "ai_export_delta"
updated_after
required
string <date-time>
cursor
integer
Default: 0
per_page
integer <= 1000
Default: 250
verdict
string
Enum: "safe" "suspicious" "malicious"
ioc_type
string
Enum: "url" "domain" "ip"
category
string
min_score
number [ 0 .. 1 ]

Responses

Request samples

Content type
application/json
{
  • "token": "string",
  • "method": "ai_export_delta",
  • "updated_after": "2019-08-24T14:15:22Z",
  • "cursor": 0,
  • "per_page": 250,
  • "verdict": "safe",
  • "ioc_type": "url",
  • "category": "string",
  • "min_score": 1
}

Response samples

Content type
application/json
{
  • "error": false,
  • "error_code": null,
  • "message": null,
  • "data": { }
}

List scored AI database entries

List scored AI entries with cursor-based pagination.

Only fully scored entries are returned. SQL row identifiers are not exposed in entry objects; use next_cursor only as an opaque pagination value for the next request.

Required Permission: ai:list

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
token
string

Your API key

method
required
string
Value: "ai_list_entries"
cursor
integer >= 0
Default: 0

Opaque pagination cursor returned by the previous response. Use 0 for the first page.

per_page
integer [ 1 .. 500 ]
Default: 100

Number of entries to return

Responses

Request samples

Content type
application/json
{
  • "token": "your_api_key",
  • "method": "ai_list_entries",
  • "cursor": 0,
  • "per_page": 100
}

Response samples

Content type
application/json
{
  • "error": false,
  • "error_code": null,
  • "message": null,
  • "data": {
    }
}

false_positive

False positive management

Declare a URL as a false positive (next-gen)

Submit a false-positive request for a blacklisted URL.

This endpoint is public (no permission required).

Optional Permission: false_positive:auto_accept - If present and force_deleted is set to true, the request is automatically accepted and the URL is removed immediately (bypasses expert review).

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
token
string

Your API key

method
required
string
Value: "false_positive_ng"
url
required
string <uri>

URL of the site to mark as false positive

force_deleted
boolean

If true and permitted, request is auto-accepted and URL is removed immediately

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{}

Get information for a false positive request

Retrieve information on a false-positive request by reference.

This endpoint is public (no permission required). A reference is only visible to the API key that created the request.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
token
string

Your API key

method
required
string
Value: "false_positive_getinfos"
ref
required
string

Reference of your false positive request

Responses

Request samples

Content type
application/json
{
  • "token": "your_api_key",
  • "method": "false_positive_getinfos",
  • "ref": "20230409474197"
}

Response samples

Content type
application/json
{}

whois

WHOIS domain information

Retrieve WHOIS information for a domain

Returns all WHOIS-related data (domain, registrar, DNS-SEC, name servers, statuses) in JSON format for the specified domain name.

Required Permission: whois

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
token
string

Your API key

method
required
string
Value: "whois_get"
domain_name
required
string^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?...

Valid domain name (e.g., crdf.fr, example.com)

Responses

Request samples

Content type
application/json
{
  • "token": "your_api_key",
  • "method": "whois_get",
  • "domain_name": "crdf.fr"
}

Response samples

Content type
application/json
{
  • "error": false,
  • "error_code": null,
  • "message": null,
  • "data": {
    }
}

Retrieve WHOIS domains via cursor-based pagination

Returns a paginated list of WHOIS domains (ID_DOMAIN, domain_name, domain_tld, query_time, create_date, update_date, expiry_date). Pagination is cursor-based.

Required Permission: whois

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
token
string

Your API key

method
required
string
Value: "whois_list_domains"
cursor
integer
Default: 0

Last-seen ID_DOMAIN (exclusive). Use 0 to start at the first record.

per_page
integer [ 1 .. 500 ]
Default: 100

Number of records to return (max 500)

Responses

Request samples

Content type
application/json
{
  • "token": "your_api_key",
  • "method": "whois_list_domains",
  • "cursor": 1000,
  • "per_page": 50
}

Response samples

Content type
application/json
{
  • "error": false,
  • "error_code": null,
  • "message": null,
  • "data": {
    }
}

nrd

Newly Registered Domains (NRDs)

Retrieve newly registered domains (NRDs) with cursor-based pagination

Retrieve a list of newly registered domains (NRDs) stored in the database, using cursor-based pagination.

Required Permission: nrd

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
token
string

Your API key

method
required
string
Value: "get_nrd"
cursor
integer >= 0
Default: 0

Last-seen NRD ID (exclusive). Use 0 to start from the first record.

Pagination: See pagination documentation in whois_list_domains.json endpoint.

per_page
integer [ 1 .. 500 ]
Default: 100

Number of records to return per page (max 500)

Responses

Request samples

Content type
application/json
{
  • "token": "your_api_key",
  • "method": "get_nrd",
  • "cursor": 150,
  • "per_page": 50
}

Response samples

Content type
application/json
{
  • "error": false,
  • "error_code": null,
  • "message": null,
  • "data": {
    }
}

cti

STIX 2.1 exports for licensed CTI collections

Export CRDF AI indicators as STIX 2.1

Returns the current malicious IOC decisions published by CRDF AI as a native STIX 2.1 Bundle. Safe, indeterminate and insufficient-evidence decisions are excluded. Internal models, thresholds, source details and private evidence are never exported.

Required permissions: licensed private account and cti:ai

Pagination is returned through the X-CRDF-Next and Link response headers. Pass the opaque value back as the next query parameter.

Authorizations:
ApiKeyAuth
query Parameters
added_after
string <date-time>

Return objects added strictly after this RFC 3339 UTC timestamp.

limit
integer [ 1 .. 500 ]
Default: 100
next
string

Opaque cursor returned by the previous page. It is bound to the API key and filters.

Responses

Response samples

Content type
application/stix+json;version=2.1
{
  • "type": "bundle",
  • "id": "string",
  • "objects": [
    ]
}

Export CRDF URL Telemetry as STIX 2.1

Returns active malicious URL and domain telemetry as a native STIX 2.1 Bundle. URL user-info, fragments and query strings are removed before publication to prevent accidental disclosure of secrets or personal data.

Required permissions: licensed private account and cti:url-telemetry

Pagination is returned through the X-CRDF-Next and Link response headers. Pass the opaque value back as the next query parameter.

Authorizations:
ApiKeyAuth
query Parameters
added_after
string <date-time>

Return objects added strictly after this RFC 3339 UTC timestamp.

limit
integer [ 1 .. 500 ]
Default: 100
next
string

Opaque cursor returned by the previous page. It is bound to the API key and filters.

Responses

Response samples

Content type
application/stix+json;version=2.1
{
  • "type": "bundle",
  • "id": "string",
  • "objects": [
    ]
}

taxii

Read-only TAXII 2.1 discovery, collections, manifests and objects

Discover the CRDF TAXII 2.1 API root

Returns the TAXII 2.1 discovery document. This resource is reserved for licensed private accounts and requires private plus taxii:read.

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/taxii+json;version=2.1
{}

Read the CRDF TAXII API root

Requires a licensed private account and taxii:read.

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/taxii+json;version=2.1
{
  • "title": "string",
  • "description": "string",
  • "versions": [
    ],
  • "max_content_length": 0
}

List readable CRDF CTI collections

Requires a licensed private account and taxii:read. Returns only collections authorized for the supplied API key.

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/taxii+json;version=2.1
{
  • "collections": [
    ]
}

Read one CRDF TAXII collection

Authorizations:
ApiKeyAuth
path Parameters
collection_id
required
string <uuid>

Responses

Response samples

Content type
application/taxii+json;version=2.1
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "title": "string",
  • "description": "string",
  • "can_read": true,
  • "can_write": true,
  • "media_types": [
    ]
}

Read STIX objects from a CRDF collection

Authorizations:
ApiKeyAuth
path Parameters
collection_id
required
string <uuid>
query Parameters
added_after
string <date-time>

Return objects added strictly after this RFC 3339 UTC timestamp.

limit
integer [ 1 .. 500 ]
Default: 100
next
string

Opaque cursor returned by the previous page. It is bound to the API key and filters.

match[id]
string
match[type]
string
Value: "indicator"
match[version]
string <date-time>
match[spec_version]
string
Value: "2.1"

Responses

Response samples

Content type
application/taxii+json;version=2.1
{
  • "more": true,
  • "next": "string",
  • "objects": [
    ]
}

Read the manifest of a CRDF collection

Authorizations:
ApiKeyAuth
path Parameters
collection_id
required
string <uuid>
query Parameters
added_after
string <date-time>

Return objects added strictly after this RFC 3339 UTC timestamp.

limit
integer [ 1 .. 500 ]
Default: 100
next
string

Opaque cursor returned by the previous page. It is bound to the API key and filters.

match[id]
string
match[type]
string
Value: "indicator"
match[version]
string <date-time>
match[spec_version]
string
Value: "2.1"

Responses

Response samples

Content type
application/taxii+json;version=2.1
{
  • "more": true,
  • "next": "string",
  • "objects": [
    ]
}

Read one retained STIX object

Authorizations:
ApiKeyAuth
path Parameters
collection_id
required
string <uuid>
object_id
required
string^indicator--[a-f0-9-]{36}$

Responses

Response samples

Content type
application/taxii+json;version=2.1
{
  • "more": true,
  • "next": "string",
  • "objects": [
    ]
}

List retained versions of one STIX object

Authorizations:
ApiKeyAuth
path Parameters
collection_id
required
string <uuid>
object_id
required
string^indicator--[a-f0-9-]{36}$

Responses

Response samples

Content type
application/taxii+json;version=2.1
{
  • "versions": [
    ]
}