Skip to main content
Required. /pipelines returns your pipelines, each with its stages nested in stages[]. HunterAI reads this one endpoint for both — there is no separate stages endpoint — and syncs it before /leads so each lead’s won/lost can be resolved from its stage.

Purpose

A pipeline is one sales funnel; its stages are the steps a lead moves through. HunterAI reads /pipelines to build the funnel shown in dashboards (stage order and archived pipelines) and, most importantly, to learn which stages mean a lead was won or lost. That classification is read from each stage’s kind and nothing on the lead itself, which is why pipelines and their stages sync before leads.

Request

/pipelines is not incremental — it receives no updated_since and is fetched in full on every sync. Return your complete current list each time.

Response envelope

200 OK
The envelope (data, has_more, page, limit) is the same on every endpoint — see How sync works → The envelope. Only data and has_more are read.

Fields

Pipeline fields

Stage fields

Each object inside stages[]:

Stage kind classification

kind is how HunterAI knows which stage means a lead was won or lost. It is the single highest-stakes field in this integration — every revenue, win-rate, and conversion metric depends on it.
  • Accepted values: exactly open, won, or lost (matched case-insensitively, so Won and WON are accepted).
  • Any other value — or a missing kind — is rejected as an error. It fails the page and, because /pipelines is required, fails the sync. It is not silently classified as open.
Because an unrecognised kind is a hard error, a typo like "win" or "closed" stops the sync instead of quietly mis-classifying deals — you find out immediately rather than discovering corrupted win-rate later. Emit exactly open, won, or lost for every stage. Leads read their won/lost from this value; see /leads.

Timestamp format

This endpoint reads no timestamp fields. /pipelines is fetched in full every sync and is not watermarked, so any created_at or updated_at you send on a pipeline or stage is ignored.

Fields the adapter ignores

Sending any of these has no effect — do not spend effort populating them:
  • Any created_at / updated_at on a pipeline or stage — /pipelines is not incremental, so timestamps here are not read.
  • type on a stage — HunterAI does not read it; won/lost comes from kind.
  • Any other key not listed in the Pipeline fields or Stage fields tables — ignored.

Identity & cross-references

  • Pipeline identity: id is the stable primary key. HunterAI upserts by (connection, id), so a pipeline’s id must never change.
  • Stage identity: a stage is keyed by (connection, pipeline, id). The same stage id may appear in more than one pipeline and is stored once per pipeline, so always return each stage inside its owning pipeline’s stages[].
  • Referenced by leads: each lead’s pipeline_id and stage_id resolve here, and the stage’s kind is what classifies that lead won/lost. See /leads. This dependency is why /pipelines syncs before /leads.

Incremental sync

This endpoint is not incremental. /pipelines receives no updated_since and is fetched in full on every sync — return your complete current list of pipelines, each with its stages, every time. These collections are expected to be small (tens to low hundreds of rows). See How sync works → Incremental sync.

Deletion behaviour

Pipelines and stages have no tombstone — there is no is_deleted on either. Because the upsert only inserts and updates, a pipeline or stage you remove from your response is not deleted from HunterAI; it simply stops being refreshed and the historical row persists. Only leads support deletion, via is_deleted — see Limitations → Tombstones.

Failure modes

A page of pipelines — and the stages flattened out of it — is validated and written as one transaction. The consequences:
  • A single malformed pipeline or stage fails the whole page. If any pipeline or stage on a page cannot be processed — a missing id, an over-length id, or a kind that is not open, won, or lost — none of the records on that page are saved. This is page-level, not per-record.
  • A failed page fails the sync. Because /pipelines is required, a failed page takes both the pipelines and stages entities down and the overall sync is reported failed. Pages that already committed stay committed.
  • An unrecognised or missing stage kind is rejected, not silently treated as open — it fails the page as above.
  • A missing or null stages on a pipeline is rejected and fails the page. An empty stages: [] is valid — a genuinely empty funnel — but its leads land with is_won = is_lost = false because there is no stage to classify them.
  • 429, 5xx, and request timeouts are retried with backoff up to 5 times, then the entity fails; a timeout is retried the same way as a 5xx. HunterAI’s request rate limit is applied per connection.
  • A repeated or unbounded page — a page whose IDs match the previous page, or a run past the page ceiling — fails the entity. See How sync works → Paging.

If this endpoint is missing

/pipelines is required. A 404 fails both the pipelines and stages entities and the sync is reported failed. Leads then have no stages to classify against, so every lead lands with is_won = is_lost = false — corrupting revenue, win-rate, and conversion metrics.