Skip to content

API Changelog

The public API contract is versioned independently of the platform release. The current contract version appears as info.version in the OpenAPI document.

1.3.0 (unreleased)

Order results are now one item per submitted slot, and an enrichment order returns every row you submitted — in the order you submitted it — whether or not the identity resolved or passed the profile's quality policy. Every row that was not fully enriched now says why.

Added

  • reasons on every result slot. Each reason carries a stable code, an English message, and a detail when there is a fact behind it. New codes name the pipeline stage that stopped: WEBSITE_UNREACHABLE (detail: the URL tried), WEBSITE_MOVED (detail: the origin it redirects to), WEBSITE_BLOCKED, WEBSITE_EMPTY, NO_PEOPLE_FOUND, NO_EMAIL_FOUND, and NOT_PROCESSED. reason_codes is unchanged and lists the same codes.
  • summary on every results page and result_summary on the order status once results_published is true: requested_count, fully_enriched_count, annotated_count, and the annotated rows counted per reason with their English message. result_summary is null before publication.
  • CSV and XLSX outputs render the Result Reasons column as the English message with the detail in parentheses.

Breaking changes

  • GET /api/v1/orders/{order_id}/results items are slot envelopes, not bare company objects. Each item carries input_position, external_id (the value you submitted), status, reason_codes, an optional duplicate_of_input_position, and company — the enriched company with embedded prospects, or null when the identity never resolved. Read item.company where you previously read the item itself.
  • Enrichment orders return every submitted row. total and available_briefing_quantity equal the submitted count. Rows that did not meet the profile's quality policy are returned with status: "PARTIAL" and a reason code instead of being omitted; unresolved rows are returned with status: "UNRESOLVED" and company: null. Filter on status if you only want policy-eligible companies. Discovery orders are unchanged: they return the companies the order found, each with status: "ENRICHED".
  • CSV, XLSX, and Google Sheets outputs of an enrichment order contain the same rows as the results API, with Result Status and Result Reasons columns.

Slot statuses: ENRICHED (resolved and policy-eligible), PARTIAL (resolved, policy annotated the row; no contacts selected), UNRESOLVED (identity could not be matched to a company), DUPLICATE (resolved to the same company as an earlier row, see duplicate_of_input_position), BLOCKED (held for operator review).

GET /api/v1/deliveries/{prospect_search_id}/companies remains available as legacy profile-wide CRM sync / drip. It is not an order door; reconcile orders through GET /api/v1/orders/{order_id}/results only.

1.2.0

API keys can no longer read live pipeline company and prospect lists. The remaining external company and prospect contract is delivered CRM sync plus website markdown.

Breaking changes

  • Live pipeline company and prospect routes are no longer part of the public API-key contract. Valid keys receive 403 with API_KEY_ROUTE_FORBIDDEN. First-party JWT (the Pipeline view) is unchanged. Use GET /api/v1/deliveries/{prospect_search_id}/companies for delivered companies and prospects, and GET /api/v1/deliveries/{prospect_search_id}/companies/{company_id}/website-markdown for optimized website markdown of a delivered company.
  • New API keys may only be issued remaining public-route scopes: orders:read, orders:write, companies:read, prospects:read, delivery:read, prospect_searches:read, blacklists:read, and blacklists:write. Existing stored keys are not rewritten; unused scopes on those keys no longer unlock a public route.

1.1.0

Orders became atomic and API-first: an order is COMPLETED only when its immutable result set is published, and GET /api/v1/orders/{order_id}/results is the primary delivery channel.

Breaking changes

  • Delivered-company prospect lists now contain only the delivered contacts. GET /api/v1/deliveries/{prospect_search_id}/companies and GET /api/v1/orders/{order_id}/results re-apply the search profile's delivery quality policy on read (qualification floor and per-company cap — the same selection that produced the delivery). Previously every prospect row linked to a delivered company was returned, including unqualified and unvalidated contacts that were never part of the delivery.
  • validation_confidence and bounce_risk_score were removed from delivered prospect responses. Both were derived from email_status and carried no independent signal, so ranking bounce risk by them was misleading. Use email_delivery_quality and email_client_deliverable instead.
  • estimated_cost was removed from the order create and order status responses. Pricing is agreed individually per client and is never derived from an automated estimate. Regenerate clients from the current OpenAPI document; previously generated clients that require this field will fail to parse order responses until regenerated.
  • delivered_since was removed from GET /orders/{order_id}/results. Results are now published once as one immutable set, so incremental delivery-time filtering no longer applies. Retrieve the full paginated set; each result item carries its own delivered_at.
  • admin_notes and webhook_url were removed from the customer order status response. Rejection follow-up goes through support; the webhook URL remains a write-only order-creation field for status notifications.
  • organization_id was removed from order list items. The authenticated API key already fixes the organization context.

Added

  • email_delivery_quality and email_delivery_quality_reason on delivered prospects: the authoritative email risk tier the delivery pipeline itself applies (for example client_deliverable, generic_company_tier, risky_internal_catchall), matching the columns CSV exports already ship.
  • GET /api/v1/deliveries/{prospect_search_id}/companies/{company_id}/website-markdown: verified website crawl ground truth for a delivered company — the aggregate optimized markdown that OpenProspect's own extraction and analysis consume, with crawl provenance (observed_at, URLs, content fingerprint).
  • results_published on order status and list responses: the readiness signal for result retrieval. A published zero-result order is valid.
  • Immutable order results: repeated retrieval always returns identical content, unaffected by later data changes.
  • Optional outputs (POST /api/v1/orders/{order_id}/outputs) projecting the published result set to CSV, XLSX, or Google Sheets, with durable receipts, idempotent replay, and the created flag distinguishing replays.

Changed

  • available_briefing_quantity now counts the immutable published result set rather than live delivery tracking rows.
  • Error responses for order results and exports now declare their complete status sets, including 409 and 500 invariant refusals. See Error Handling.

1.0.0

Initial public contract: orders, order results, profile companies, prospect searches, blacklists, and exports.