---
title: Poll a capture job
description: "Poll an EPCIS capture job's status, eventCount, capturedCount, and per-event errors[]. Use the captureJobId returned by the capture POST."
canonical: "https://www.tracepass.eu/docs/capture-job"
locale: en
source: "https://www.tracepass.eu/docs/capture-job"
---

# Poll a capture job

> Poll an EPCIS capture job's status, eventCount, capturedCount, and per-event errors[]. Use the captureJobId returned by the capture POST.

```http
GET /api/v1/epcis/capture/{id}
```

Reads the status of an asynchronous EPCIS capture job — the read side of the EPCIS 2.0 capture model. `POST /api/v1/epcis/capture` returns `202 Accepted` with a `captureJobId`; pass that id here to follow the job until it reaches a terminal state.

The response carries `status`, the `eventCount` submitted, the `capturedCount` stored so far, and a per-event `errors` array (`{index, message}`) for any events that failed validation or EPC resolution. `createdAt` and `finishedAt` bracket the run — `finishedAt` is `null` while the job is still in progress. Counts as one read.

Plan gate: EPCIS is included on every paid plan today, so the 403 path is only reachable on workspaces whose `epcisCaptureEnabled` flag has been disabled via per-tenant override. Unknown or expired job id returns `404`.

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `Authorization` | header | string | yes | `Bearer <token>` — either a `tp_` API key (Developer → API Keys; simplest, for server-to-server) or an OAuth 2.0 access token (Developer → OAuth Apps; for user-authorized apps, scoped + revocable). The Authentication page has the full OAuth flow and scope list. |
| `id` | path | string | yes | The capture job id returned by `POST /api/v1/epcis/capture`. |

## Examples

```bash
curl -sS https://app.tracepass.eu/api/v1/epcis/capture/6650c4d5e6f7a8b9c0d1e2f3 \
  -H "Authorization: Bearer tp_REDACTED_xxxxxxxxxxxx"
```

```typescript
const res = await fetch(
  `https://app.tracepass.eu/api/v1/epcis/capture/${captureJobId}`,
  { headers: { Authorization: `Bearer ${process.env.TRACEPASS_API_KEY}` } },
);
if (res.status === 404) throw new Error("Capture job not found");
const job = await res.json();

if (job.status === "success") {
  console.log(`Captured ${job.capturedCount}/${job.eventCount} events`);
} else if (job.status === "failed") {
  console.error(job.errors); // [{ index, message }]
}
```

```python
import os, requests

res = requests.get(
    f"https://app.tracepass.eu/api/v1/epcis/capture/{capture_job_id}",
    headers={"Authorization": f"Bearer {os.environ['TRACEPASS_API_KEY']}"},
)
res.raise_for_status()
job = res.json()

if job["status"] == "success":
    print(f"Captured {job['capturedCount']}/{job['eventCount']} events")
elif job["status"] == "failed":
    print(job["errors"])  # [{ "index": ..., "message": ... }]
```

## Responses

### 200 — OK

```json
{
  "captureJobId": "6650c4d5e6f7a8b9c0d1e2f3",
  "status": "success",
  "eventCount": 12,
  "capturedCount": 12,
  "errors": [],
  "createdAt": "2026-05-09T12:00:00.000Z",
  "finishedAt": "2026-05-09T12:00:03.420Z"
}
```

### 401 — Missing API key

```json
{ "error": "Missing or invalid API key" }
```

### 403 — Add-on not enabled

```json
{ "error": "epcis_capture_not_available" }
```

### 404 — Not found

```json
{ "error": "Capture job not found" }
```

## Related

- [Capture EPCIS events](https://www.tracepass.eu/docs/capture-events.md)
