> ## Documentation Index
> Fetch the complete documentation index at: https://docs.brainstormer.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Build Snapshot

> GET /v1/agents/builds/:buildId — poll the latest ProvisioningEvent for a build. Stateless alternative to the SSE stream.

# Get Build Snapshot

Return the **latest `ProvisioningEvent`** for a build. This is the stateless
alternative to the [SSE stream](/api-reference/provisioning/build-events-sse) —
ideal for "email-me-a-link" backends that don't hold a connection, or for a
quick status check. The payload is the **same shape** as the SSE `data` and the
[webhook](/api-reference/provisioning/webhook) body, so there is no separate
client code path.

<ParamField method="GET" path="/v1/agents/builds/:buildId" />

## Authentication

| Header          | Value                      | Required |
| --------------- | -------------------------- | -------- |
| `Authorization` | `Bearer brs_live_YOUR_KEY` | Yes      |

Same `agents:write`-scoped key as
[from-url](/api-reference/provisioning/from-url). NEVER call this from a browser.

## Path Parameters

<ParamField path="buildId" type="string" required>
  The `bld_…` id returned by `from-url` (also available as the `pollUrl`).
</ParamField>

## Response — `200 OK`

Returns a single [`ProvisioningEvent`](/api-reference/provisioning/build-events-sse#provisioningevent-contract).

<ResponseField name="buildId" type="string">Build identifier.</ResponseField>

<ResponseField name="status" type="string">
  One of `queued`, `detecting`, `scraping`, `analyzing`, `provisioning`,
  `indexing`, `ready`, `failed`.
</ResponseField>

<ResponseField name="progress" type="number">0–100, monotonic, phase-weighted.</ResponseField>
<ResponseField name="step" type="string">Current phase (same enum as `status`).</ResponseField>
<ResponseField name="stepLabel" type="string">Human-readable display copy.</ResponseField>
<ResponseField name="detail" type="string">Optional sub-status (e.g. "Indexed 6 of 8 videos").</ResponseField>
<ResponseField name="platform" type="string">`youtube` or `instagram`, once detected.</ResponseField>
<ResponseField name="channelTitle" type="string">Detected channel title.</ResponseField>
<ResponseField name="agentSlug" type="string">Present only when `status` is `ready`.</ResponseField>
<ResponseField name="starterQuestions" type="string[]">Present only when `ready` — seed the chat UI.</ResponseField>
<ResponseField name="warning" type="string">Soft issue (e.g. "Limited public content found").</ResponseField>

<ResponseField name="error" type="object">
  Present only when `status` is `failed`.

  <Expandable title="error object">
    <ResponseField name="code" type="string">A `ProvisioningErrorCode`.</ResponseField>
    <ResponseField name="message" type="string">Human-readable message.</ResponseField>
    <ResponseField name="retryable" type="boolean">Whether retrying may succeed.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="emittedAt" type="string">ISO8601 timestamp; also the SSE `id:` for resume.</ResponseField>

## Examples

<CodeGroup>
  ```bash curl theme={null}
  curl https://app.brainstormer.io/v1/agents/builds/bld_8c9d0e1f2a3b \
    -H "Authorization: Bearer brs_live_YOUR_KEY"
  ```

  ```typescript Node / TypeScript theme={null}
  async function pollBuild(buildId: string) {
    const res = await fetch(
      `https://app.brainstormer.io/v1/agents/builds/${buildId}`,
      { headers: { Authorization: "Bearer brs_live_YOUR_KEY" } },
    );
    if (!res.ok) throw new Error(`poll failed: ${res.status}`);
    return res.json(); // a ProvisioningEvent
  }

  // Poll until terminal:
  let event = await pollBuild("bld_8c9d0e1f2a3b");
  while (event.status !== "ready" && event.status !== "failed") {
    await new Promise((r) => setTimeout(r, 2000));
    event = await pollBuild("bld_8c9d0e1f2a3b");
  }
  if (event.status === "ready") console.log("Chat at slug:", event.agentSlug);
  ```
</CodeGroup>

**Response (200) — in progress:**

```json theme={null}
{
  "buildId": "bld_8c9d0e1f2a3b",
  "status": "analyzing",
  "progress": 55,
  "step": "analyzing",
  "stepLabel": "Learning the creator's voice",
  "detail": "Generating system prompt",
  "platform": "youtube",
  "channelTitle": "The Channel",
  "emittedAt": "2026-06-14T01:36:52.957Z"
}
```

**Response (200) — ready:**

```json theme={null}
{
  "buildId": "bld_8c9d0e1f2a3b",
  "status": "ready",
  "progress": 100,
  "step": "ready",
  "stepLabel": "Your agent is ready",
  "platform": "youtube",
  "channelTitle": "The Channel",
  "agentSlug": "the-channel-agent",
  "starterQuestions": [
    "What videos have you made about productivity?",
    "Summarize your latest upload",
    "What gear do you recommend?"
  ],
  "emittedAt": "2026-06-14T01:38:10.221Z"
}
```

## HTTP Status Codes

| Status                   | Meaning                                    |
| ------------------------ | ------------------------------------------ |
| `200 OK`                 | Snapshot returned.                         |
| `401`                    | Missing or invalid `Authorization` header. |
| `403 insufficient_scope` | Key lacks the `agents:write` scope.        |

<Tip>
  For live, push-based progress (a wait-on-page UX), prefer the
  [SSE stream](/api-reference/provisioning/build-events-sse). Use polling for
  stateless or email-me-a-link backends.
</Tip>
