Skip to content

Orders Overview

Use orders when you want OpenProspect to deliver company briefings. Every order starts from a search profile.

Mental Model

Concept Meaning
Search profile What to look for and how to qualify companies
Order What you want OpenProspect to deliver now
Discovery order Find new qualified companies for a profile
Enrichment order Enrich companies you already provide
briefing_quantity Number of companies requested or submitted
available_briefing_quantity Number of companies in the published result set
results_published Whether the immutable order result set exists, including a valid zero-result set

Create the profile first, then place one or more orders from that profile.

Choose a Flow

You have Use Send companies? Send briefing_quantity?
An ICP and need new companies Discovery No Yes
A list of companies to enrich Enrichment Yes No

For discovery, briefing_quantity is the number of qualified companies you want delivered. For enrichment, the API derives briefing_quantity from companies.length because submitted companies are treated as prequalified.

Basic Flow

  1. Create a profile with POST /api/v1/search-profile-creations.
  2. Poll profile creation until it returns SUCCEEDED.
  3. Save the returned profile_id.
  4. Create an order with POST /api/v1/orders.
  5. Poll GET /api/v1/orders/{order_id} while its status is active.
  6. Wait for status: "COMPLETED" and results_published: true.
  7. Fetch every page from GET /api/v1/orders/{order_id}/results.

External clients submit orders, poll status, and retrieve completed results. OpenProspect performs review and managed fulfillment internally. Clients do not call admin endpoints or run individual enrichment features themselves.

Statuses

Profile creation has a small async lifecycle:

Status Meaning Next step
PENDING The request is queued Poll again
RUNNING The profile is being created Poll again
SUCCEEDED The profile is ready Create an order
FAILED Profile creation did not finish Retry with a new idempotency key

Orders use this lifecycle:

Status Class Meaning Next step
RECEIVED Active The API accepted the order for review; companies are not enriched yet Poll again
ACCEPTED Active OpenProspect approved the order for managed fulfillment; requested features are not necessarily ready Poll again
IN_PROGRESS Active OpenProspect is producing the requested results Poll again
COMPLETED Successful terminal Managed fulfillment ended Fetch results when results_published is true
REJECTED Unsuccessful terminal The order was not approved Stop polling and contact support with the order ID
FAILED Unsuccessful terminal Fulfillment failed Stop polling and contact support with the order ID
CANCELLED Unsuccessful terminal The order was cancelled Stop polling

Poll only while the status is RECEIVED, ACCEPTED, or IN_PROGRESS. Stop on COMPLETED, REJECTED, FAILED, or CANCELLED.

Result Publication And Counts

OpenProspect publishes one immutable result set for a successful order. The profile's delivery policy is evaluated at publication time and determines which candidates are included. For example, an enrichment order can contain 498 submitted companies while available_briefing_quantity is 413 because 85 did not satisfy the profile's contactability or quality requirements.

briefing_quantity is the requested or submitted population; available_briefing_quantity is the published population. A valid publication can contain zero results, so use results_published, not a positive count, to decide whether the result resource exists.

For orders created before immutable publication was introduced, a historical record can be COMPLETED while results_published is false. In that case, GET /api/v1/orders/{order_id}/results returns ORDER_RESULTS_NOT_READY; contact support with the order ID rather than reading profile-wide company inventory.

Order Results Versus Profile Inventory

Use GET /api/v1/orders/{order_id}/results as the source of truth for one order. Its pages are a stable snapshot and contain only that order's published companies.

GET /api/v1/companies and GET /api/v1/deliveries/{prospect_search_id}/companies are profile-wide views. They can include companies from older or unrelated orders for the same profile and must not be used to reconcile an order. For enrichment orders, a submitted external_id is returned as the company-level source_id, providing the exact round-trip key for your CRM or batch input.

Result pages default to 50 companies and accept at most 100. Start at offset=0, increase offset by the number of returned items, and continue until has_more is false.

Optional Outputs

The order-results API is the primary delivery contract. Optional CSV, XLSX, and Google Sheets outputs are projections of the same immutable result set; they do not select a different company population and cannot change order completion.

  • POST /api/v1/orders/{order_id}/export creates a CSV or XLSX export.
  • POST /api/v1/orders/{order_id}/outputs creates a durable file or Google Sheets output.
  • GET /api/v1/orders/{order_id}/outputs?limit=50&offset=0 lists a bounded output-attempt page with total and has_more.
  • GET /api/v1/orders/{order_id}/outputs/{output_id} reads one output receipt.

Output creation is asynchronous. Poll the output receipt until COMPLETED or FAILED. A failed optional output does not remove or rewrite the published API results. A published zero-result order is valid through the results API but has nothing to project; output creation returns 409 / ORDER_RESULTS_EMPTY.

Create an output only after results_published is true:

curl --fail-with-body -sS -X POST \
  "https://api.openprospect.io/api/v1/orders/${ORDER_ID}/outputs" \
  -H "Authorization: Bearer ${OPENPROSPECT_API_KEY}" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: ${ORDER_OUTPUT_IDEMPOTENCY_KEY}" \
  -d '{"output_type":"xlsx","output_language":"en"}'

Supported output_type values are csv, xlsx, and google_sheets. Google Sheets also requires spreadsheet_id.

Persist one output idempotency key before the first request and retry an uncertain response with the same key and identical body. Each result-set destination is one logical output. Omitting the Idempotency-Key header binds the output to a server-derived key that the response discloses as idempotency_key; requests without a key always replay the existing output for that destination. The created field distinguishes a fresh dispatch from an idempotent replay. 409 / OUTPUT_IDEMPOTENCY_CONFLICT occurs only when two different explicit keys claim the same destination; retry with the original key, or omit the header to replay. A different destination is a separate logical output.

Each published order accepts at most 20 logical outputs. Further new destinations return 409 / OUTPUT_QUOTA_EXCEEDED; poll or retry an existing output instead.

The response includes output_id, created, status, result_count, result_sha256, export_job_id, and transport receipt fields. Poll GET /api/v1/orders/{order_id}/outputs/{output_id}. Treat COMPLETED as success and FAILED as an output-specific failure; in either case the primary order results remain available through the API.

Retrieve a finished CSV or XLSX file through the export download endpoint using the output's export_job_id:

curl --fail-with-body -sS -L \
  "https://api.openprospect.io/api/v1/exports/jobs/${EXPORT_JOB_ID}/download" \
  -H "Authorization: Bearer ${OPENPROSPECT_API_KEY}" \
  -o order-results.zip

Google Sheets outputs report the spreadsheet URL in the receipt's location field instead; there is no file to download.

What to Store

Store these IDs in your system:

ID Why
profile_creation_id Poll profile creation and debug failed synthesis
profile_id Reuse the same profile for discovery and enrichment orders
order_id Poll order status and fetch delivered results
Your idempotency keys Retry safely without creating duplicates

If you send external_id for enrichment companies, store it too. Results return that value as source_id.

Reliability Rules

  • Send Idempotency-Key on profile creation and order creation.
  • Retry 429, 500, 502, 503, and 504 with backoff.
  • Retry POST requests with the same idempotency key only when the body is the same.
  • Use a new idempotency key when you intentionally change the request body.
  • Treat 409 as an idempotency conflict and create a new key for the changed request.
  • Do not fetch results until the order is COMPLETED and results_published is true.

Next Steps