Overview
Describe the feed you want in prose, answer the builder's questions, approve the result.
The Feed Builder API turns a plain-English description of a dataset into a running feed. You post what you want, the builder researches the source and drafts a schema, and it stops to ask you things along the way — those stops are called gates. Approve the last one and the feed is published on a schedule.
This API serves supervised builds only
mode: "autonomous", mode: "fast" and publication.policy: "auto" all return 501. A build with nobody
answering its gates would run to a finished feed and then have no way to hand it to you. See
Limits before you plan an unattended integration around this API.
Base URL
Ask us for your base URL
The Feed Builder API is issued per customer and is not yet on a shared public hostname. Your base URL comes with your
API key. Every example below writes it as $FEEDBUILDER_API.
Every route is under /v1, and every route under /v1 needs an API key. The two documentation routes —
GET /openapi.yaml and GET /docs — take no key, so you can evaluate the contract before you have one.
The shape of a build
Start it. POST /v1/builds with your request in prose and mode: "supervised". You get a build id back
immediately; the build runs asynchronously.
Watch it. Subscribe to GET /v1/builds/{id}/events for server-sent events, or poll GET /v1/builds/{id}.
Answer its gates. When status is awaiting_input, the build is parked on pending_gate. Answer with
POST /v1/builds/{id}/gates/{gate_id} and it continues.
Approve publication. The last gate is usually publish_review. Approving it is what opens the pull request
and registers the delivery subscription — it is the step that makes the data reachable.
Your first build
curl -X POST "$FEEDBUILDER_API/v1/builds" \
-H "Authorization: Bearer $STRING_FEED_BUILDER_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"query": "a feed of laptop listings from example.com, with price, title and URL",
"mode": "supervised"
}'{ "object": "build", "id": "bld_01J8..." }The Location response header carries the build's URL.
Endpoints
| Method | Path | What |
|---|---|---|
POST | /v1/builds | Start a build |
GET | /v1/builds | List your builds |
GET | /v1/builds/{id} | Get one build |
PATCH | /v1/builds/{id} | Set auto-proceed |
DELETE | /v1/builds/{id} | Soft-delete a build |
POST | /v1/builds/{id}/cancel | Cancel a build |
GET | /v1/builds/{id}/events | Stream progress |
POST | /v1/builds/{id}/gates/{gate_id} | Answer a gate |
POST | /v1/builds/{id}/messages | Send a message |
GET | /v1/builds/{id}/sample | Get sample rows |
GET | /v1/usage | Always 501 — see Limits |
Generating a client
GET /openapi.yaml serves an OpenAPI 3.1 document generated from the service's own types, so it describes the binary
that answered you. Point any generator at it:
npx @openapitools/openapi-generator-cli generate \
-i "$FEEDBUILDER_API/openapi.yaml" -g typescript-fetch -o ./feedbuilder-clientOne endpoint your generated client will not handle
GET /v1/builds/{id}/events is a long-lived text/event-stream, and OpenAPI cannot describe a stream of framed
events. Every generator will emit a method that buffers the whole response or times out. Use your language's SSE
client for that one endpoint and the generated client for the other ten. See Streaming.