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

# Pipeline Status

> Poll photo import, processing, and go-live pipeline status for an event

## Overview

Returns the current state of the event **photos** pipeline — the same status information the 9Pic dashboard refresh button uses. Call this after [Import](/api-reference/pipeline/photos/import), [Process](/api-reference/pipeline/photos/process), or [Go Live](/api-reference/pipeline/photos/go-live) to know when each stage has finished, failed, or is still running.

The response includes:

* **Media** — `media: "photos"` so the same path family can host other media types later.
* **Pipeline stages** — short keywords under `stages`: `import`, `process`, and `go_live`.
* **Counts** — how many items are `not_processed`, `processing`, `processed`, or `failed`.
* **Live flag** — `is_live` is `true` when the public gallery is live.
* **Gallery URL** — `gallery_url` follows the event visibility and domain settings from the dashboard (Bhaago India, 9Pic, or organiser custom domain).

Polling this endpoint can also advance stuck jobs to `failed` and reconcile processing completion — the same auto-recovery behavior as the dashboard status refresh.

## Recommended Pipeline Flow

1. `POST /pipeline/photos/import` — import photos from configured sources.
2. `GET /pipeline/photos/status` — poll until `stages.import.status` is `processed` or `failed`.
3. `POST /pipeline/photos/process` — run AI processing (watermark, BIB, face indexing).
4. `GET /pipeline/photos/status` — poll until `stages.process.status` is `processed`, `partially_processed`, or `failed`.
5. `POST /pipeline/photos/go-live` — publish processed photos to the public gallery.
6. `GET /pipeline/photos/status` — poll until `stages.go_live.status` is `processed` or `failed`, and `is_live` is `true`.

<Tip>
  Use exponential backoff (e.g. 3s, 5s, 10s, 15s, then every 15s) while any stage you care about has `status: "processing"`. Stop polling once all active stages reach a terminal state (`processed`, `failed`, or `partially_processed`).
</Tip>

## Endpoint

```
GET /api/v1/ext/{org_id}/event/{event_id}/pipeline/photos/status
```

## Path Parameters

| Parameter  | Type   | Required | Description                             |
| ---------- | ------ | -------- | --------------------------------------- |
| `org_id`   | number | Yes      | Your organisation ID.                   |
| `event_id` | number | Yes      | The event to fetch pipeline status for. |

## Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -i \
    -H "X-API-Key: <your_9pic_api_key>" \
    "https://api.9pic.ai/api/v1/ext/903/event/456/pipeline/photos/status"
  ```

  ```python Python theme={null}
  import time
  import requests

  URL = "https://api.9pic.ai/api/v1/ext/903/event/456/pipeline/photos/status"
  HEADERS = {"X-API-Key": "<your_9pic_api_key>"}

  STAGE_KEYS = ("import", "process", "go_live")

  def any_stage_processing(data: dict) -> bool:
      stages = data["stages"]
      return any(stages[key]["status"] == "processing" for key in STAGE_KEYS)

  for delay in (3, 5, 10, 15):
      response = requests.get(URL, headers=HEADERS)
      data = response.json()["data"]
      if not any_stage_processing(data):
          print(data["stages"], data["is_live"])
          break
      time.sleep(delay)
  else:
      while any_stage_processing(data):
          time.sleep(15)
          data = requests.get(URL, headers=HEADERS).json()["data"]
      print(data["stages"], data["is_live"])
  ```

  ```javascript JavaScript theme={null}
  const url =
    "https://api.9pic.ai/api/v1/ext/903/event/456/pipeline/photos/status";
  const headers = { "X-API-Key": "<your_9pic_api_key>" };
  const stageKeys = ["import", "process", "go_live"];

  const anyStageProcessing = (data) =>
    stageKeys.some((key) => data.stages[key].status === "processing");

  const delays = [3000, 5000, 10000, 15000];
  let data;

  for (const delay of delays) {
    data = (await (await fetch(url, { headers })).json()).data;
    if (!anyStageProcessing(data)) break;
    await new Promise((resolve) => setTimeout(resolve, delay));
  }

  while (anyStageProcessing(data)) {
    await new Promise((resolve) => setTimeout(resolve, 15000));
    data = (await (await fetch(url, { headers })).json()).data;
  }

  console.log(data.stages, data.is_live);
  ```
</CodeGroup>

## Example Response

<Tabs>
  <Tab title="processing">
    ```json theme={null}
    {
      "responseType": "success",
      "message": "Pipeline status",
      "data": {
        "event_id": 456,
        "media": "photos",
        "event_name": "Mumbai Marathon 2026",
        "event_slug": "mumbai-marathon-2026",
        "is_live": false,
        "gallery_url": "https://bhaagoindia.com/events/mumbai-marathon-2026/memories/",
        "last_updated": "2026-07-08T10:06:12",
        "stages": {
          "import": {
            "status": "processed",
            "updated_at": "2026-07-08T10:00:00",
            "message": null
          },
          "process": {
            "status": "processing",
            "updated_at": "2026-07-08T10:05:00",
            "message": null
          },
          "go_live": {
            "status": "not_processed",
            "updated_at": null,
            "message": null
          }
        },
        "counts": {
          "total": 500,
          "processed": 120,
          "processing": 80,
          "not_processed": 300,
          "failed": 0
        },
        "active_run": {
          "stage": "process",
          "run_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
          "started_at": "2026-07-08T10:05:00",
          "effective_count": 500,
          "requested_count": 500
        }
      }
    }
    ```
  </Tab>

  <Tab title="completed">
    ```json theme={null}
    {
      "responseType": "success",
      "message": "Pipeline status",
      "data": {
        "event_id": 456,
        "media": "photos",
        "event_name": "Mumbai Marathon 2026",
        "event_slug": "mumbai-marathon-2026",
        "is_live": true,
        "gallery_url": "https://bhaagoindia.com/events/mumbai-marathon-2026/memories/",
        "last_updated": "2026-07-08T10:26:01",
        "stages": {
          "import": {
            "status": "processed",
            "updated_at": "2026-07-08T10:00:00",
            "message": null
          },
          "process": {
            "status": "processed",
            "updated_at": "2026-07-08T10:20:00",
            "message": null
          },
          "go_live": {
            "status": "processed",
            "updated_at": "2026-07-08T10:25:00",
            "message": null
          }
        },
        "counts": {
          "total": 500,
          "processed": 500,
          "processing": 0,
          "not_processed": 0,
          "failed": 0
        },
        "active_run": {
          "stage": "process",
          "run_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
          "started_at": "2026-07-08T10:05:00",
          "effective_count": 500,
          "requested_count": 500
        }
      }
    }
    ```
  </Tab>

  <Tab title="failed">
    ```json theme={null}
    {
      "responseType": "success",
      "message": "Pipeline status",
      "data": {
        "event_id": 456,
        "media": "photos",
        "event_name": "Mumbai Marathon 2026",
        "event_slug": "mumbai-marathon-2026",
        "is_live": false,
        "gallery_url": "https://bhaagoindia.com/events/mumbai-marathon-2026/memories/",
        "last_updated": "2026-07-08T10:16:01",
        "stages": {
          "import": {
            "status": "failed",
            "updated_at": "2026-07-08T10:16:00",
            "message": "Import stuck. Please run import again."
          },
          "process": {
            "status": "not_processed",
            "updated_at": null,
            "message": null
          },
          "go_live": {
            "status": "not_processed",
            "updated_at": null,
            "message": null
          }
        },
        "counts": {
          "total": 0,
          "processed": 0,
          "processing": 0,
          "not_processed": 0,
          "failed": 0
        },
        "active_run": null
      }
    }
    ```
  </Tab>
</Tabs>

## Response Models

| Field            | Type           | Description                                                                                                                                |
| ---------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `event_id`       | number         | Event ID.                                                                                                                                  |
| `media`          | string         | Always `"photos"` for this endpoint.                                                                                                       |
| `event_name`     | string \| null | Event display name (same field naming as [Event Details](/api-reference/event-details)).                                                   |
| `event_slug`     | string \| null | Event URL slug.                                                                                                                            |
| `is_live`        | boolean        | `true` when the public gallery is live.                                                                                                    |
| `gallery_url`    | string         | Public gallery URL for the event.                                                                                                          |
| `last_updated`   | string         | ISO 8601 timestamp for this snapshot.                                                                                                      |
| `stages`         | object         | Product-facing pipeline stages. Each stage has `status`, `updated_at`, and optional `message`.                                             |
| `stages.import`  | object         | Import stage triggered by [Import](/api-reference/pipeline/photos/import).                                                                 |
| `stages.process` | object         | AI processing stage triggered by [Process](/api-reference/pipeline/photos/process).                                                        |
| `stages.go_live` | object         | Publish stage triggered by [Go Live](/api-reference/pipeline/photos/go-live).                                                              |
| `counts`         | object         | Aggregate counts of media items by processing state.                                                                                       |
| `active_run`     | object \| null | Summary of the most recent process run (`stage`, `run_id`, `started_at`, `effective_count`, `requested_count`). `null` when no run exists. |

### Stage `status` values

| Value                 | Meaning                                                 |
| --------------------- | ------------------------------------------------------- |
| `not_processed`       | Stage has not started.                                  |
| `processing`          | Stage is in progress — keep polling.                    |
| `processed`           | Stage completed successfully.                           |
| `failed`              | Stage failed or timed out. Check `message` for details. |
| `partially_processed` | Batch incomplete. Re-run the stage to continue.         |

## Error Responses

| Status | Meaning                                                                     |
| ------ | --------------------------------------------------------------------------- |
| `401`  | API key is missing.                                                         |
| `403`  | API key is invalid, inactive, or token/event ownership mismatch.            |
| `404`  | Event configuration not found. Ensure the event is set up in the dashboard. |
| `429`  | Rate limit exceeded. Back off and retry.                                    |

See [Errors](/api-reference/errors) for canonical descriptions and retry guidance.
