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
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 insidestages[]:
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, orlost(matched case-insensitively, soWonandWONare accepted). - Any other value — or a missing
kind— is rejected as an error. It fails the page and, because/pipelinesis required, fails the sync. It is not silently classified asopen.
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_aton a pipeline or stage —/pipelinesis not incremental, so timestamps here are not read. typeon a stage — HunterAI does not read it; won/lost comes fromkind.- Any other key not listed in the Pipeline fields or Stage fields tables — ignored.
Identity & cross-references
- Pipeline identity:
idis the stable primary key. HunterAI upserts by(connection, id), so a pipeline’sidmust never change. - Stage identity: a stage is keyed by
(connection, pipeline, id). The same stageidmay appear in more than one pipeline and is stored once per pipeline, so always return each stage inside its owning pipeline’sstages[]. - Referenced by leads: each lead’s
pipeline_idandstage_idresolve here, and the stage’skindis what classifies that lead won/lost. See/leads. This dependency is why/pipelinessyncs 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 nois_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-lengthid, or akindthat is notopen,won, orlost— none of the records on that page are saved. This is page-level, not per-record. - A failed page fails the sync. Because
/pipelinesis 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
kindis rejected, not silently treated asopen— it fails the page as above. - A missing or
nullstageson a pipeline is rejected and fails the page. An emptystages: []is valid — a genuinely empty funnel — but its leads land withis_won = is_lost = falsebecause 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 a5xx. 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.