Embed CROW into your platform
Run background intelligence checks directly from your fintech, real estate, HR, or trust-and-safety product. Same rigorous methodology, structured for programmatic access.
Authentication
All API requests require an API key sent via the X-API-Key header. Keys are provisioned after your access request is approved.
// Every request must include your API key
curl -X POST https://yourcrowdomain.com/api/v1/search \
-H "Content-Type: application/json" \
-H "X-API-Key: crw_live_YOUR_API_KEY" \
-d '{"name": "Jane Smith", "city": "Austin", "state": "TX"}'
API keys follow the format crw_live_XXXXXXXX. Keep your key secret. If compromised, contact us immediately to revoke and reissue.
Authentication Flow
Here is how API key authentication works end-to-end:
+----------------+ +------------------+ +----------------+
| Your Platform | | CROW API | | ODIN Backend |
+-------+--------+ +--------+---------+ +-------+--------+
| | |
| 1. POST /api/v1/search | |
| X-API-Key: crw_live_... | |
|------------------------->| |
| | |
| | 2. Validate key |
| | Check rate limit |
| | Check scopes |
| | |
| 3. 200 OK (preview) | |
|<-------------------------| |
| | |
| 4. POST /api/v1/report | |
| X-API-Key: crw_live_... | |
|------------------------->| |
| | 5. Fire intelligence |
| | request |
| |------------------------>|
| 6. 202 Accepted | |
| { reference: "..." } | |
|<-------------------------| |
| | |
| | 7. Report completed |
| |<------------------------|
| | |
| 8. Webhook POST | |
| (if callback_url set) | |
|<-------------------------| |
| | |
All requests are authenticated via the X-API-Key header. No session tokens, cookies, or OAuth flows required.
Rate Limits
Rate limits are enforced per API key. The following tiers apply:
| Tier | Daily Limit | Burst (per min) | Cost |
|---|---|---|---|
| Starter | 100 requests | 20 | Free with API key |
| Growth | 1,000 requests | 60 | $199/mo |
| Enterprise | 10,000 requests | 200 | Custom |
X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
When the limit is exceeded, you receive a 429 response:
{
"error": "Rate limit exceeded",
"daily_limit": 100,
"remaining": 0,
"reset": "2026-03-27T23:59:59Z",
"message": "You have exceeded 100 requests/day. Resets at midnight UTC.",
"upgrade_url": "https://crowsearch.com/enterprise.html"
}
POST /api/v1/search
Run a preliminary search to see what public records are available for a subject. Returns preview-level data structured for display in your platform.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Full name of the subject |
| city | string | No | City to narrow results |
| state | string | No | Two-letter state code |
Example Request
curl -X POST https://yourcrowdomain.com/api/v1/search \
-H "Content-Type: application/json" \
-H "X-API-Key: crw_live_YOUR_API_KEY" \
-d '{
"name": "Jane Smith",
"city": "Austin",
"state": "TX"
}'
Example Response
{
"subject": {
"name": "Jane Smith",
"city": "Austin",
"state": "TX"
},
"preview": {
"records_found": true,
"categories": [
"Public records",
"Court filings",
"Professional licenses",
"Property records",
"Corporate affiliations"
],
"note": "Preview data. Order a full report for detailed findings."
},
"pricing": {
"brief": { "price": 500, "currency": "USD", "description": "Clarity Brief" },
"plus": { "price": 500, "currency": "USD", "description": "Clarity Plus" },
"relationship": { "price": 500, "currency": "USD", "description": "Relationship Report" }
},
"api_search_cost": { "price": 25, "currency": "USD" }
}
Try It Live
Test the search endpoint directly from this page. Enter your API key and a subject name to see a live response.
Interactive API Tester
Code Examples
Quick integration snippets for popular languages:
cURL
curl -X POST https://crowsearch.com/api/v1/search \
-H "Content-Type: application/json" \
-H "X-API-Key: crw_live_YOUR_API_KEY" \
-d '{"name": "Jane Smith", "city": "Austin", "state": "TX"}'
Python
import requests
response = requests.post(
"https://crowsearch.com/api/v1/search",
headers={
"Content-Type": "application/json",
"X-API-Key": "crw_live_YOUR_API_KEY",
},
json={
"name": "Jane Smith",
"city": "Austin",
"state": "TX",
},
)
data = response.json()
print(f"Records found: {data['preview']['records_found']}")
print(f"Categories: {', '.join(data['preview']['categories'])}")
Node.js
const response = await fetch("https://crowsearch.com/api/v1/search", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": "crw_live_YOUR_API_KEY",
},
body: JSON.stringify({
name: "Jane Smith",
city: "Austin",
state: "TX",
}),
});
const data = await response.json();
console.log(`Records found: ${data.preview.records_found}`);
console.log(`Categories: ${data.preview.categories.join(", ")}`);
Ruby
require "net/http"
require "json"
require "uri"
uri = URI("https://crowsearch.com/api/v1/search")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request["Content-Type"] = "application/json"
request["X-API-Key"] = "crw_live_YOUR_API_KEY"
request.body = {
name: "Jane Smith",
city: "Austin",
state: "TX"
}.to_json
response = http.request(request)
data = JSON.parse(response.body)
puts "Records found: #{data['preview']['records_found']}"
puts "Categories: #{data['preview']['categories'].join(', ')}"
POST /api/v1/report
Order a full CROW background intelligence report. Reports are generated asynchronously via our ODIN intelligence backend. You'll receive a reference ID to poll for status, or provide a callback_url to receive a webhook when complete.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Full name of the subject |
| city | string | No | City to narrow results |
| state | string | No | Two-letter state code |
| tier | string | No | brief, plus, or relationship. Default: brief |
| callback_url | string | No | Webhook URL for delivery notification |
Example Request
curl -X POST https://yourcrowdomain.com/api/v1/report \
-H "Content-Type: application/json" \
-H "X-API-Key: crw_live_YOUR_API_KEY" \
-d '{
"name": "Jane Smith",
"city": "Austin",
"state": "TX",
"tier": "plus",
"callback_url": "https://yourplatform.com/webhooks/crow"
}'
Example Response
{
"reference": "CRW-A1B2C3D4",
"status": "processing",
"tier": "plus",
"estimated_delivery": "2026-03-31T12:00:00.000Z",
"status_url": "/api/v1/report/CRW-A1B2C3D4",
"callback_url": "https://yourplatform.com/webhooks/crow"
}
GET /api/v1/report/:reference
Check the status of a previously ordered report. When the report is delivered, the response will include a secure download URL and password.
Example Request
curl https://yourcrowdomain.com/api/v1/report/CRW-A1B2C3D4 \ -H "X-API-Key: crw_live_YOUR_API_KEY"
Example Response (Processing)
{
"reference": "CRW-A1B2C3D4",
"tier": "plus",
"status": "analyzing",
"steps": {
"received": "2026-03-26T10:00:00.000Z",
"collecting": "2026-03-26T10:05:00.000Z",
"analyzing": "2026-03-26T14:00:00.000Z",
"reviewing": null,
"delivered": null
},
"expected_delivery": "2026-03-31T12:00:00.000Z"
}
Example Response (Delivered)
{
"reference": "CRW-A1B2C3D4",
"tier": "plus",
"status": "delivered",
"steps": { ... },
"expected_delivery": "2026-03-31T12:00:00.000Z",
"report_url": "/api/report/abc123...",
"report_password": "Kx7mNp"
}
GET /api/v1/usage
Check your API usage statistics for the current billing period.
Example Response
{
"key": "crw_live_a1b2...x9z0",
"company": "Acme Lending",
"total_requests": 847,
"total_searches": 812,
"total_reports": 35,
"today_requests": 14,
"daily_limit": 100,
"remaining_today": 86
}
Webhooks
CROW supports two webhook delivery methods:
1. Per-Order Callbacks
Provide a callback_url when ordering a report. CROW will POST to that URL when the report is ready:
{
"event": "report.completed",
"reference": "CRW-A1B2C3D4",
"status": "delivered",
"report_url": "/api/report/abc123...",
"delivered_at": "2026-03-28T09:15:00.000Z"
}
2. Registered Partner Endpoints
Partners can register a persistent webhook endpoint via the API. All reports associated with your partner code will trigger webhooks automatically.
POST /api/webhooks/register { "callback_url": "https://yourplatform.com/webhooks/crow", "partner_code": "ACME-LAW" } // Response { "id": 42, "callback_url": "https://yourplatform.com/webhooks/crow", "secret": "a1b2c3...signing_secret", "message": "Use the secret to verify webhook signatures." }
Webhook Verification
Every webhook includes an X-Crow-Signature header containing an HMAC-SHA256 signature of the request body, signed with your endpoint secret:
// Verify in Node.js
const crypto = require("crypto");
const signature = req.headers["x-crow-signature"];
const expected = "sha256=" + crypto
.createHmac("sha256", YOUR_WEBHOOK_SECRET)
.update(JSON.stringify(req.body))
.digest("hex");
if (signature !== expected) {
return res.status(401).send("Invalid signature");
}
Retry Policy
Delivery Log
Check delivery status for any reference via the API:
GET /api/webhooks/deliveries?reference=CRW-A1B2C3D4 Authorization: Bearer YOUR_JWT_TOKEN
API Pricing
Simple per-use pricing. No monthly minimums. You're billed based on actual usage.
Search
Per search query. Returns preview data and record categories found.
Full Report
Per report, any tier. Complete background intelligence delivered within 2-7 business days.
Error Code Reference
All errors follow a consistent JSON structure:
{
"error": "Human-readable error message",
"code": "MACHINE_READABLE_CODE",
"status": 400,
"requestId": "req_abc123..."
}
| Status | Code | Description | Resolution |
|---|---|---|---|
| 400 | INVALID_PARAMS | Missing or invalid request parameters | Check required fields: name is always required |
| 400 | INVALID_TIER | Invalid report tier specified | Use: brief, plus, or relationship |
| 400 | INVALID_STATE | Invalid US state code | Provide a two-letter state abbreviation (e.g., TX, CA, NY) |
| 401 | MISSING_API_KEY | No API key provided | Add X-API-Key header to your request |
| 401 | INVALID_API_KEY | API key not recognized or revoked | Verify your key or request a new one |
| 403 | SCOPE_DENIED | API key lacks permission for this endpoint | Contact us to upgrade key scopes |
| 404 | NOT_FOUND | Report reference not found | Verify the reference ID is correct |
| 409 | DUPLICATE_ORDER | A report for this subject was recently ordered | Use the existing reference or wait before reordering |
| 429 | RATE_LIMIT | Daily rate limit exceeded | Wait for reset at midnight UTC or upgrade tier |
| 500 | INTERNAL_ERROR | Internal server error | Retry after a brief delay. If persistent, contact support. |
| 503 | SERVICE_UNAVAILABLE | Backend intelligence service temporarily unavailable | Retry with exponential backoff |
Request API Access
API access is available to vetted platforms and partners. Tell us about your use case and we'll get back to you within 1 business day.
