Enrichment Order Guide¶
Submit your company list, get back enriched data with contacts, technologies, and more.
Overview¶
Enrichment orders let you submit a list of companies you already know and get back structured data: company profiles, decision-maker contacts, technology stacks, legal registration data, and AI-powered match scoring.
The workflow is simple:
- Create an order with your company list
- Track the order status (polling or webhook)
- Retrieve enriched results via the order endpoint
Order Lifecycle¶
stateDiagram-v2
[*] --> RECEIVED: Create order
RECEIVED --> ACCEPTED: Admin review
RECEIVED --> CANCELLED: Cancel
ACCEPTED --> IN_PROGRESS: Enrichment starts
ACCEPTED --> CANCELLED: Cancel
IN_PROGRESS --> COMPLETED: All enrichment finished
IN_PROGRESS --> CANCELLED: Cancel
COMPLETED --> [*]
CANCELLED --> [*]
| Status | What It Means |
|---|---|
RECEIVED |
Your order is queued for admin review |
ACCEPTED |
Approved and enrichment pipeline is starting |
IN_PROGRESS |
Enrichment is actively running |
COMPLETED |
All data is ready — retrieve your results |
CANCELLED |
Order was cancelled |
Prerequisites¶
Before you begin:
- API Key with
orders:readandorders:writescopes. Create one in the OpenProspect dashboard under Settings > Developer > API Keys. - Base URL:
https://api.openprospect.io/api/v1
Scopes
Enrichment orders only need two scopes: orders:read and orders:write. No other scopes are required.
Step 1: Create an Order¶
Submit your company list with the enrichment features you want.
Request¶
POST /api/v1/orders/
curl -X POST "https://api.openprospect.io/api/v1/orders/" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Q1 2026 Hotel Prospects",
"features": ["COMPANY_DATA", "CONTACTS", "TECHNOLOGIES"],
"profile_name": "Hotel Enrichment Q1",
"companies": [
{
"company_name": "Grand Hotel Berlin",
"external_id": "CRM-1001",
"website_url": "https://www.grandhotel-berlin.de",
"city": "Berlin",
"country": "Germany"
},
{
"company_name": "Alpine Resort Innsbruck",
"external_id": "CRM-1002",
"city": "Innsbruck",
"country": "Austria"
}
]
}'
import httpx
API_KEY = "lnc_live_your_api_key_here"
BASE_URL = "https://api.openprospect.io/api/v1"
order = {
"title": "Q1 2026 Hotel Prospects",
"features": ["COMPANY_DATA", "CONTACTS", "TECHNOLOGIES"],
"profile_name": "Hotel Enrichment Q1",
"companies": [
{
"company_name": "Grand Hotel Berlin",
"external_id": "CRM-1001",
"website_url": "https://www.grandhotel-berlin.de",
"city": "Berlin",
"country": "Germany",
},
{
"company_name": "Alpine Resort Innsbruck",
"external_id": "CRM-1002",
"city": "Innsbruck",
"country": "Austria",
},
],
}
response = httpx.post(
f"{BASE_URL}/orders/",
json=order,
headers={"Authorization": f"Bearer {API_KEY}"},
)
if response.status_code == 202:
data = response.json()
print(f"Order created: {data['order_id']}")
print(f"Status: {data['status']}")
else:
print(f"Error {response.status_code}: {response.json()}")
const API_KEY = "lnc_live_your_api_key_here";
const BASE_URL = "https://api.openprospect.io/api/v1";
const order = {
title: "Q1 2026 Hotel Prospects",
features: ["COMPANY_DATA", "CONTACTS", "TECHNOLOGIES"],
profile_name: "Hotel Enrichment Q1",
companies: [
{
company_name: "Grand Hotel Berlin",
external_id: "CRM-1001",
website_url: "https://www.grandhotel-berlin.de",
city: "Berlin",
country: "Germany",
},
{
company_name: "Alpine Resort Innsbruck",
external_id: "CRM-1002",
city: "Innsbruck",
country: "Austria",
},
],
};
const response = await fetch(`${BASE_URL}/orders/`, {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(order),
});
if (response.status === 202) {
const data = await response.json();
console.log(`Order created: ${data.order_id}`);
console.log(`Status: ${data.status}`);
} else {
console.error(`Error ${response.status}:`, await response.json());
}
const API_KEY = "lnc_live_your_api_key_here";
const BASE_URL = "https://api.openprospect.io/api/v1";
interface CreateOrderResponse {
order_id: string;
status: string;
company_count: number;
estimated_cost: { total: number; currency: string } | null;
message: string;
}
const order = {
title: "Q1 2026 Hotel Prospects",
features: ["COMPANY_DATA", "CONTACTS", "TECHNOLOGIES"],
profile_name: "Hotel Enrichment Q1",
companies: [
{
company_name: "Grand Hotel Berlin",
external_id: "CRM-1001",
website_url: "https://www.grandhotel-berlin.de",
city: "Berlin",
country: "Germany",
},
{
company_name: "Alpine Resort Innsbruck",
external_id: "CRM-1002",
city: "Innsbruck",
country: "Austria",
},
],
};
const response = await fetch(`${BASE_URL}/orders/`, {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(order),
});
if (response.status === 202) {
const data: CreateOrderResponse = await response.json();
console.log(`Order created: ${data.order_id}`);
console.log(`Status: ${data.status}`);
} else {
console.error(`Error ${response.status}:`, await response.json());
}
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
var apiKey = "lnc_live_your_api_key_here";
var baseUrl = "https://api.openprospect.io/api/v1";
var order = new
{
title = "Q1 2026 Hotel Prospects",
features = new[] { "COMPANY_DATA", "CONTACTS", "TECHNOLOGIES" },
profile_name = "Hotel Enrichment Q1",
companies = new[]
{
new
{
company_name = "Grand Hotel Berlin",
external_id = "CRM-1001",
website_url = "https://www.grandhotel-berlin.de",
city = "Berlin",
country = "Germany"
},
new
{
company_name = "Alpine Resort Innsbruck",
external_id = "CRM-1002",
city = (string?)null,
website_url = (string?)null,
// city and country can be provided without a URL
}
}
};
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", apiKey);
var json = JsonSerializer.Serialize(order);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync($"{baseUrl}/orders/", content);
if ((int)response.StatusCode == 202)
{
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Order created: {body}");
}
else
{
Console.WriteLine($"Error {(int)response.StatusCode}");
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
Response (202 Accepted)¶
{
"order_id": "4f767705-03a2-4e91-a3e8-1ec3f9dea865",
"status": "RECEIVED",
"company_count": 2,
"estimated_cost": null,
"message": "Order received. Awaiting admin review."
}
Checkpoint
Save the order_id from the response. You need it for all subsequent calls.
Company Fields¶
Each company in the companies array accepts these fields:
| Field | Type | Required | Description |
|---|---|---|---|
company_name |
string | Yes | Company name (max 500 chars) |
external_id |
string | No | Your CRM ID for this company. Returned as source_id in results. Auto-generated if omitted. |
website_url |
string | No | Company website. If missing, we attempt to discover it automatically. |
postal_code |
string | No | Postal/ZIP code |
city |
string | No | City name |
street |
string | No | Street address |
country |
string | No | Country name or ISO code |
email |
string | No | Contact email |
phone |
string | No | Contact phone number |
employee_count |
integer | No | Number of employees |
industry_code |
string | No | SIC or industry code |
industry_description |
string | No | Industry description |
Providing website_url
If you have the company's website URL, always include it. It significantly improves enrichment quality and speed. Without it, we use automated search to discover the URL, which can occasionally find the wrong site for companies with ambiguous names.
Request Parameters¶
| Parameter | Type | Required | Description |
|---|---|---|---|
title |
string | Yes | A descriptive name for your order |
features |
string[] | Yes | Enrichment features to apply (see Features Reference) |
profile_name |
string | No | Name for a new enrichment profile (auto-created). Mutually exclusive with profile_id. If neither is provided, a profile is auto-created from the order title. |
profile_id |
UUID | No | ID of an existing enrichment profile. Mutually exclusive with profile_name. |
priority |
string | No | NORMAL (default) or EXPRESS |
webhook_url |
string | No | URL for status change notifications (see Webhooks) |
ideal_customer_profile |
string | No | ICP description for targeting (improves match scoring) |
contact_roles |
string[] | No | Target contact roles (e.g., ["CEO", "CTO", "Head of Sales"]) |
companies |
object[] | Yes | 1 to 10,000 companies |
Step 2: Track Order Status¶
After creating an order, poll the status endpoint to know when results are ready.
Request¶
GET /api/v1/orders/{order_id}
import time
order_id = "4f767705-03a2-4e91-a3e8-1ec3f9dea865"
while True:
response = httpx.get(
f"{BASE_URL}/orders/{order_id}",
headers={"Authorization": f"Bearer {API_KEY}"},
)
data = response.json()
status = data["status"]
print(f"Order status: {status}")
if status == "COMPLETED":
print("Results are ready!")
break
elif status == "CANCELLED":
print("Order was cancelled.")
break
time.sleep(60) # Check every minute
const orderId = "4f767705-03a2-4e91-a3e8-1ec3f9dea865";
async function pollOrderStatus() {
while (true) {
const response = await fetch(`${BASE_URL}/orders/${orderId}`, {
headers: { Authorization: `Bearer ${API_KEY}` },
});
const data = await response.json();
console.log(`Order status: ${data.status}`);
if (data.status === "COMPLETED") {
console.log("Results are ready!");
return data;
}
if (data.status === "CANCELLED") {
console.log("Order was cancelled.");
return data;
}
await new Promise((resolve) => setTimeout(resolve, 60000));
}
}
await pollOrderStatus();
interface OrderStatusResponse {
order_id: string;
title: string;
status: "RECEIVED" | "ACCEPTED" | "IN_PROGRESS" | "COMPLETED" | "CANCELLED";
priority: string;
company_count: number;
features: string[];
estimated_cost: { total: number; currency: string } | null;
prospect_search_id: string | null;
admin_notes: string | null;
webhook_url: string | null;
created_at: string;
accepted_at: string | null;
completed_at: string | null;
cancelled_at: string | null;
}
const orderId = "4f767705-03a2-4e91-a3e8-1ec3f9dea865";
async function pollOrderStatus(): Promise<OrderStatusResponse> {
while (true) {
const response = await fetch(`${BASE_URL}/orders/${orderId}`, {
headers: { Authorization: `Bearer ${API_KEY}` },
});
const data: OrderStatusResponse = await response.json();
console.log(`Order status: ${data.status}`);
if (data.status === "COMPLETED" || data.status === "CANCELLED") {
return data;
}
await new Promise((resolve) => setTimeout(resolve, 60000));
}
}
const result = await pollOrderStatus();
var orderId = "4f767705-03a2-4e91-a3e8-1ec3f9dea865";
while (true)
{
var response = await client.GetAsync($"{baseUrl}/orders/{orderId}");
var body = await response.Content.ReadAsStringAsync();
var data = JsonSerializer.Deserialize<JsonElement>(body);
var status = data.GetProperty("status").GetString();
Console.WriteLine($"Order status: {status}");
if (status == "COMPLETED")
{
Console.WriteLine("Results are ready!");
break;
}
if (status == "CANCELLED")
{
Console.WriteLine("Order was cancelled.");
break;
}
await Task.Delay(60000); // Check every minute
}
Response (200 OK)¶
{
"order_id": "4f767705-03a2-4e91-a3e8-1ec3f9dea865",
"title": "Q1 2026 Hotel Prospects",
"status": "COMPLETED",
"priority": "NORMAL",
"company_count": 2,
"features": ["COMPANY_DATA", "CONTACTS", "TECHNOLOGIES"],
"estimated_cost": null,
"prospect_search_id": "42665897-b189-4e0f-8841-499351a30aff",
"admin_notes": null,
"webhook_url": null,
"created_at": "2026-02-25T10:30:00.000000Z",
"accepted_at": "2026-02-25T10:45:00.000000Z",
"completed_at": "2026-02-25T12:00:00.000000Z",
"cancelled_at": null
}
Checkpoint
When status is COMPLETED, proceed to Step 3 to retrieve your enriched data.
List All Orders¶
You can also list all your orders with optional status filtering:
curl -X GET "https://api.openprospect.io/api/v1/orders/?status=COMPLETED&limit=10" \
-H "Authorization: Bearer YOUR_API_KEY"
Step 3: Retrieve Results¶
Once the order is COMPLETED, retrieve your enriched companies with all their data.
Request¶
GET /api/v1/orders/{order_id}/results
order_id = "4f767705-03a2-4e91-a3e8-1ec3f9dea865"
all_companies = []
offset = 0
limit = 50
while True:
response = httpx.get(
f"{BASE_URL}/orders/{order_id}/results",
params={"limit": limit, "offset": offset},
headers={"Authorization": f"Bearer {API_KEY}"},
)
data = response.json()
for company in data["items"]:
print(f"Company: {company['name']}")
print(f" Source ID: {company['source_id']}")
print(f" Match Score: {company['match_score']}")
print(f" Prospects: {len(company['prospects'])}")
all_companies.append(company)
if not data["has_more"]:
break
offset += limit
print(f"\nTotal companies retrieved: {len(all_companies)}")
const orderId = "4f767705-03a2-4e91-a3e8-1ec3f9dea865";
const allCompanies = [];
let offset = 0;
const limit = 50;
while (true) {
const response = await fetch(
`${BASE_URL}/orders/${orderId}/results?limit=${limit}&offset=${offset}`,
{ headers: { Authorization: `Bearer ${API_KEY}` } }
);
const data = await response.json();
for (const company of data.items) {
console.log(`Company: ${company.name}`);
console.log(` Source ID: ${company.source_id}`);
console.log(` Match Score: ${company.match_score}`);
console.log(` Prospects: ${company.prospects.length}`);
allCompanies.push(company);
}
if (!data.has_more) break;
offset += limit;
}
console.log(`\nTotal companies retrieved: ${allCompanies.length}`);
interface Prospect {
id: string;
company_id: string;
first_name: string;
last_name: string | null;
job_title: string | null;
email: string | null;
phone_number: string | null;
linkedin_url: string | null;
qualification_score: number | null;
qualification_reason: string | null;
email_type: string | null;
validation_confidence: number | null;
bounce_risk_score: number | null;
}
interface Company {
id: string;
name: string;
website_url: string | null;
business_type: string | null;
city: string | null;
country: string | null;
description: string | null;
employee_count: number | null;
phone_numbers: string[] | null;
social_media_links: { platform: string; url: string }[] | null;
match_score: number | null;
match_reasons: string[] | null;
web_technologies: string[] | null;
source_id: string | null;
delivered_at: string | null;
legal_registration_info: Record<string, unknown> | null;
prospects: Prospect[];
}
interface ResultsResponse {
items: Company[];
total: number;
limit: number;
offset: number;
has_more: boolean;
}
const orderId = "4f767705-03a2-4e91-a3e8-1ec3f9dea865";
const allCompanies: Company[] = [];
let offset = 0;
const limit = 50;
while (true) {
const response = await fetch(
`${BASE_URL}/orders/${orderId}/results?limit=${limit}&offset=${offset}`,
{ headers: { Authorization: `Bearer ${API_KEY}` } }
);
const data: ResultsResponse = await response.json();
allCompanies.push(...data.items);
if (!data.has_more) break;
offset += limit;
}
console.log(`Total companies: ${allCompanies.length}`);
var orderId = "4f767705-03a2-4e91-a3e8-1ec3f9dea865";
var offset = 0;
var limit = 50;
var allCompanies = new List<JsonElement>();
while (true)
{
var response = await client.GetAsync(
$"{baseUrl}/orders/{orderId}/results?limit={limit}&offset={offset}");
var body = await response.Content.ReadAsStringAsync();
var data = JsonSerializer.Deserialize<JsonElement>(body);
foreach (var company in data.GetProperty("items").EnumerateArray())
{
Console.WriteLine($"Company: {company.GetProperty("name")}");
Console.WriteLine($" Source ID: {company.GetProperty("source_id")}");
allCompanies.Add(company);
}
if (!data.GetProperty("has_more").GetBoolean()) break;
offset += limit;
}
Console.WriteLine($"\nTotal companies: {allCompanies.Count}");
Response (200 OK)¶
{
"items": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Grand Hotel Berlin",
"website_url": "https://www.grandhotel-berlin.de",
"normalized_url": "grandhotel-berlin.de",
"business_type": "Hotel",
"city": "Berlin",
"country": "Germany",
"description": "A luxury 5-star hotel in the heart of Berlin...",
"employee_count": 120,
"phone_numbers": ["+49 30 12345678"],
"social_media_links": [
{"platform": "facebook", "url": "https://facebook.com/grandhotelberlin"},
{"platform": "instagram", "url": "https://instagram.com/grandhotelberlin"}
],
"match_score": 8,
"match_reasons": ["Industry match", "Size match", "Location match"],
"match_reasoning": "The company operates a luxury hotel in Berlin...",
"web_technologies": ["WordPress", "Google Analytics", "Cloudflare"],
"web_technologies_analyzed_at": "2026-02-25T11:30:00.000000Z",
"source_id": "CRM-1001",
"delivered_at": "2026-02-25T11:45:00.000000Z",
"legal_registration_info": null,
"prospects": [
{
"id": "e5f6a7b8-c9d0-1234-e5f6-a7b8c9d01234",
"company_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"first_name": "Maria",
"last_name": "Schmidt",
"job_title": "General Manager",
"email": "m.schmidt@grandhotel-berlin.de",
"phone_number": null,
"linkedin_url": "https://linkedin.com/in/mariaschmidt",
"qualification_score": 9,
"qualification_reason": "Senior decision maker in hotel management",
"email_type": "PERSONAL",
"validation_confidence": 95,
"bounce_risk_score": 5
}
]
}
],
"total": 2,
"limit": 50,
"offset": 0,
"has_more": false
}
Checkpoint
You should see your companies with enriched data. Each company's source_id matches the external_id you submitted — use this to sync results back to your CRM.
Correlating Results to Your CRM¶
The external_id you submit with each company is returned as source_id in the results. This is your correlation key:
| You Submit | You Get Back | Use For |
|---|---|---|
"external_id": "CRM-1001" |
"source_id": "CRM-1001" |
Match enriched data to your CRM record |
Incremental Sync¶
For large orders or ongoing syncs, use the delivered_since parameter to fetch only new results:
curl -X GET "https://api.openprospect.io/api/v1/orders/{order_id}/results?delivered_since=2026-02-25T12:00:00Z" \
-H "Authorization: Bearer YOUR_API_KEY"
Pagination¶
Results are paginated. Use limit and offset to page through large result sets:
| Parameter | Default | Range | Description |
|---|---|---|---|
limit |
50 | 1-100 | Companies per page |
offset |
0 | 0+ | Number of companies to skip |
delivered_since |
- | ISO 8601 | Only companies delivered after this timestamp |
The response includes has_more: true when there are additional pages.
Webhook Notifications¶
Instead of polling, you can receive status change notifications via webhook.
Setup¶
Include a webhook_url when creating your order:
{
"title": "Q1 2026 Hotel Prospects",
"features": ["COMPANY_DATA", "CONTACTS"],
"profile_name": "Hotel Enrichment Q1",
"webhook_url": "https://your-api.com/webhooks/openprospect",
"companies": [...]
}
Webhook Payload¶
When the order status changes, we send a POST request to your URL:
{
"event": "order.status_changed",
"order_id": "4f767705-03a2-4e91-a3e8-1ec3f9dea865",
"status": "COMPLETED",
"previous_status": "IN_PROGRESS",
"timestamp": "2026-02-25T12:00:00.000000+00:00"
}
You receive a notification for every status transition:
| Transition | When |
|---|---|
RECEIVED → ACCEPTED |
Admin approves your order |
ACCEPTED → IN_PROGRESS |
Enrichment starts |
IN_PROGRESS → COMPLETED |
All enrichment finished — retrieve your results |
Retry Policy¶
If your endpoint returns a 5xx error or is unreachable, we retry up to 3 times. Design your webhook handler to be idempotent.
Testing Webhooks
Use webhook.site to generate a temporary URL for testing. You can inspect every payload we send.
Webhook Security¶
For production use, verify webhook authenticity using one of these approaches:
Option 1: URL token — Include a secret token as a query parameter:
Verify this token on your server before processing the payload.
Option 2: Organization-level Authorization header — Configure a default webhook URL and Authorization header for your organization via the notification settings endpoints. This header is sent with every webhook delivery.
Organization Notification Settings
You can configure organization-wide webhook settings (URL, auth header, email notifications) through the OpenProspect dashboard. When set, these apply to all orders unless overridden by an order-level webhook_url.
Enrichment Features¶
Choose which data you want by including features in the features array.
Available Features¶
| Feature | What You Get |
|---|---|
COMPANY_DATA |
Company profile: description, employee count, phone numbers, social media, reviews, favicon |
CONTACTS |
Decision-maker contacts: names, job titles, LinkedIn profiles, qualification scores |
TECHNOLOGIES |
Web technology stack: CMS, analytics tools, frameworks, marketing platforms |
JOBS |
Active job postings from the company (used for hiring signal analysis) |
HANDELSREGISTER |
German commercial register data: legal form, registration, capital, founding date |
ANALYSIS |
AI match scoring: how well the company fits your ICP, with detailed reasoning |
EMAIL_DISCOVERY |
Validated email addresses for discovered contacts |
EMAIL_GENERATION |
AI-generated personalized outreach emails for contacts |
Feature Dependencies¶
Some features build on others for best results:
COMPANY_DATA ──> CONTACTS ──> EMAIL_DISCOVERY
| | |
| └──> EMAIL_GENERATION
|
├──> TECHNOLOGIES
├──> JOBS
├──> HANDELSREGISTER (German companies only)
└──> ANALYSIS (benefits from all other data)
COMPANY_DATA is the foundation — it crawls the company website and extracts structured data. Most other features depend on this data being available.
Recommended Combinations
For a standard enrichment order, use ["COMPANY_DATA", "CONTACTS", "ANALYSIS"]. Add "TECHNOLOGIES" if you need technology stack data, or "EMAIL_DISCOVERY" if you need verified email addresses.
What Each Feature Returns¶
COMPANY_DATA¶
Populates the company profile fields in the response:
description,business_type,employee_countphone_numbers,social_media_linksreview_rating,review_countstreet,city,postal_code,countryfavicon_url
CONTACTS¶
Populates the prospects array on each company:
first_name,last_name,job_titlelinkedin_url,phone_numberqualification_score(0-10),qualification_reason
TECHNOLOGIES¶
Populates the technology fields:
web_technologies(e.g.,["WordPress", "Google Analytics", "React"])web_technologies_analyzed_at
HANDELSREGISTER¶
Populates legal_registration_info (German companies only):
company_name,legal_form,registration_number,registration_courtfounding_date,share_capital_amount,business_purposestatus,is_dissolved
ANALYSIS¶
Populates the match scoring fields:
match_score(0-10)match_reasons(e.g.,["Industry match", "Size match"])match_reasoning(detailed AI explanation)
EMAIL_DISCOVERY¶
Populates email fields on each prospect:
email,email_type(PERSONAL,GENERAL,ROLE)validation_confidence(0-100),bounce_risk_score(0-100)
Error Handling¶
Error Response Formats¶
The API uses consistent error formats per status code:
Authentication Error (401)¶
Cause: Invalid API key, expired key, or missing Authorization header.
Resolution: Verify your API key in the OpenProspect dashboard. Ensure the header format is Authorization: Bearer lnc_live_....
Insufficient Permissions (403)¶
{
"code": "AUTHORIZATION_ERROR",
"message": "Insufficient permissions. Required scopes: orders:write",
"required_scopes": ["orders:write"],
"user_scopes": ["orders:read"]
}
Cause: Your API key is missing required scopes.
Resolution: Create a new API key with both orders:read and orders:write scopes in the dashboard.
Not Found (404)¶
{
"code": "ORDER_NOT_FOUND",
"message": "Order with identifier 00000000-0000-0000-0000-000000000000 not found",
"resource_type": "Order",
"identifier": "00000000-0000-0000-0000-000000000000"
}
Cause: The order ID does not exist or belongs to a different organization.
Resolution: Verify the order_id from the create order response.
Validation Error (422)¶
{
"detail": [
{
"type": "too_short",
"loc": ["body", "companies"],
"msg": "List should have at least 1 item after validation, not 0",
"input": [],
"ctx": {"field_name": "List", "min_length": 1, "actual_length": 0}
}
]
}
Cause: Request body fails validation.
Common validation errors:
| Error | Cause | Fix |
|---|---|---|
companies too short |
Empty companies list | Provide at least 1 company |
| Invalid feature | Unrecognized feature name | Use one of the 8 valid feature names |
Missing company_name |
Company without a name | Every company must have company_name |
| Duplicate features | Same feature listed twice | Remove duplicates from the features array |
| Profile conflict | Both profile_id and profile_name provided |
Use one or the other, not both |
Limitations and FAQ¶
How long does enrichment take?¶
Enrichment time depends on the number of companies and features requested. Typical processing times:
| Order Size | Features | Approximate Time |
|---|---|---|
| 1-10 companies | COMPANY_DATA, CONTACTS | Minutes |
| 50-100 companies | COMPANY_DATA, CONTACTS, TECHNOLOGIES | 1-2 hours |
| 500+ companies | Full feature set | Several hours |
Orders are processed by our admin team. You receive a webhook notification (or can poll) when processing completes.
Can I cancel an order?¶
Not directly via the API. Contact support if you need to cancel an order.
Can I resubmit a failed company?¶
Create a new order with the companies you want to retry. Each order is independent.
What happens if a company website is not found?¶
If you do not provide a website_url, we attempt to discover it via automated web search. If no website is found, the company is still imported but will have limited enrichment data (only the fields you provided in the order).
What is the maximum order size?¶
10,000 companies per order. For larger batches, create multiple orders.
Do I need profile_id or profile_name?¶
Use profile_name to auto-create a new enrichment profile for your order. Use profile_id if you want to reuse an existing profile. You can provide at most one of the two. If you omit both, a profile is auto-created from the order title.
API Reference Summary¶
| Method | Path | Scope | Description |
|---|---|---|---|
POST |
/api/v1/orders/ |
orders:write |
Create enrichment order (202) |
GET |
/api/v1/orders/ |
orders:read |
List your orders |
GET |
/api/v1/orders/{order_id} |
orders:read |
Get order status |
GET |
/api/v1/orders/{order_id}/results |
orders:read |
Get enriched results |