POST /v1/radars/bulk.
Bulk creation is asynchronous:
- The submission request returns
202 Acceptedwith abulk_id. - Item-level outcomes are produced later as
radar_createdorradar_failure. - A final
bulk_completedevent indicates that all items are done.
Bulk flow and responsibilities
| Component | Responsibility |
|---|---|
| Your application | Build the bulk payload, submit it, store bulk_id, reconcile outcomes |
POST /v1/radars/bulk | Validates envelope-level shape and queues items |
| Bulk processor | Validates and processes each queued item asynchronously |
| Your webhook endpoint | Receives per-item radar_created / radar_failure, then bulk_completed |
GET /v1/radars/bulk/{bulk_id} | Polls live status and per-item results |
Step 1: Prepare your webhook consumer
webhook_url is required for async bulk. Point it to an HTTPS endpoint that:
- accepts
POST - returns
2xxquickly - processes payloads asynchronously in your own worker queue
radar_createdradar_failurebulk_completed
Step 2: Build a valid bulk request
The top-level body requires:webhook_url: single callback URL for all items in this bulk submissionradars: array of radar payloads
Each item in
radars[] uses the same field structure as the corresponding single-radar endpoint. Before building a bulk payload, make sure you’re familiar with the per-type schemas:- Create Company Radar —
domain,radar_type, optional filters - Create Contact Radar —
profile_url,radar_type,domain - Create Industry Radar —
radar_type, optionalkeyword
custom_fields to every item. If you skip it, you can still reconcile with item_index, but item-level tracing in downstream systems is harder.
Step 3: Submit and persist bulk_id
On success, the API returns 202 with a bulk_id and summary. Persist bulk_id immediately. It is your primary key for reconciliation and polling.
400: invalid JSON or invalid envelope (webhook_url,radars[])401: missing or invalid API key429: bulk rate limit exceeded500: queueing failed
400 example:
429 example:
reason is always minute because this endpoint enforces a dedicated per-minute bulk bucket.
Step 4: Process per-item events
Items do not complete at the same time. You can receive outcomes in any order.radar_created means the item created successfully.
radar_failure means that item failed (validation, conflict, billing, or processing error). The code, message, and errors[] fields are identical to what the sync single-create endpoint would return for the same failure — so any error handling you already have for the sync API works here without changes.
Use item_index, bulk_id, and custom_fields to map each event back to the original request item.
For successful items, data matches the same data shape returned by single-create endpoints:
Create Company Radar, Create Contact Radar, and Create Industry Radar.
radar_created example:
radar_failure example:
discovered_at is included for backwards compatibility and equals completed_at. Prefer completed_at — discovered_at will be removed in a future version.Possible failure codes
Thecode, message, and errors[] below are spread directly into the radar_failure envelope above — identical to what the sync single-create endpoint returns for the same failure. Your existing sync error handling works for bulk without changes.
400 — Validation error
400 — Validation error
Returned when a field is missing, invalid, or the radar type is not supported.
errors[] may contain multiple entries, one per failing field.402 — Insufficient balance
402 — Insufficient balance
Returned when your account does not have enough credits to create the radar. The item is not created and no credits are deducted.
409 — Conflict (radar already exists)
409 — Conflict (radar already exists)
Returned when a radar with the same configuration already exists on your account. Always includes
conflicting_radar_id so you can look it up directly.The field name varies by radar type:- Company radars →
domain - Contact radars →
identifiers - Industry radars →
keyword(forindustry_mentions/industry_job_openings) orradar_type(for other industry types)
500 — Internal server error
500 — Internal server error
Rare. Indicates a transient infrastructure failure. The item will be retried automatically — no action needed on your side. If a
radar_failure with code: 500 is delivered, it means all retries were exhausted.Step 5: Finalize on bulk_completed
When all items reach terminal state, you receive one bulk_completed event. Use it to:
- mark the bulk job complete in your system
- compare final counts (
created,failed) with your local ledger - trigger any retry workflow for failed items
bulk_completed.radars[] contains per-item results for the submission.
Each radars[] entry is identical to the per-item webhook payload already delivered for that item (radar_created or radar_failure).
Step 6: Add polling as a reliability path
If webhook delivery is delayed or your consumer is unavailable, poll:GET /v1/radars/bulk/{bulk_id}
The response status is:
processing: at least one item is still in flightcompleted: all items are terminal
completed, then stop.
Both polling responses include radars[]:
- In
processing, in-flight items appear as{ item_index, status: "processing", custom_fields }. - In
completed, each item is the full terminal payload (same shape as per-item webhook delivery).
processing example:
completed example:
Recommended production pattern
- Submit bulk and store
bulk_id. - Process webhook events and persist item outcomes by
bulk_id + item_index. - Poll status endpoint on a fallback interval until completed.
- Reconcile webhook-driven and poll-driven outcomes.
- Retry only failed items with a new bulk request.