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

# Runs auflisten

> Alle selbst gestarteten Runs auflisten. Filter nach Status, App, Credential, Kanal, Kind und Zeitraum.

**`GET`** `https://api-datahub.octoparse.com/v1/runs`

Authentifizierung: API-Schlüssel erforderlich (`Authorization: Bearer <API Key>`).

Alle von Ihnen gestarteten Runs. Die Zuordnung erfolgt über das **Konto**: Runs, die per API-Schlüssel, SDK, MCP oder Web-Login gestartet wurden, erscheinen in derselben Liste. Immer nach Startzeit sortiert, neueste zuerst. `pagination.total` ist die gefilterte Gesamtzahl.

Filter sind kombinierbar. `status` akzeptiert kommagetrennte Werte (OR). `credential` ist die nicht-sensitive stabile ID der startenden Credential, nützlich um zu tracken welcher Key Quota verbraucht. `created_from` / `created_to` nutzen die Startzeit, Start inklusiv und Ende exklusiv. Das Vokabular entspricht <a href="/docs/de/datahub/api/reference/account/get-billing">Abrechnungsaggregation</a>: einen Billing-Gruppenkey unverändert durchreichen, um in die passenden Runs zu drill-downen.

Jeder Eintrag enthält `billing` und `usage`, sodass für den Abgleich pro Run kein separater Detailaufruf nötig ist. Die Schwärzung des Input-Echos entspricht dem Run-Detail.

## Anfrage

### Abfrageparameter

<ParamField query="status" type="string">
  Run-Status. Kommagetrennte Mehrfachwerte. Werte außerhalb des Vokabulars liefern `400`.
</ParamField>

<ParamField query="credential" type="string">
  Stabile ID der startenden Credential. Übernehmen Sie den Wert aus der Abrechnungsaggregation `group_by=credential` → `credential`.
</ParamField>

<ParamField query="data_app" type="string">
  App-Referenz: `<namespace>/<app_name>` oder `app_<hex>`.
</ParamField>

<ParamField query="triggered_by" type="string">
  Start channel, z. B. `api` / `sdk` / `mcp` / `cli` / `web`.
</ParamField>

<ParamField query="created_from" type="string">
  Untere Grenze der Startzeit, inklusiv. Absoluter ISO-8601-Zeitstempel.
</ParamField>

<ParamField query="created_to" type="string">
  Startzeit-Obergrenze, exklusiv.
</ParamField>

<ParamField query="run_kind" type="string">
  `production` für normale Runs; `test` für Autor-Debug-Runs.

  Werte: `test` / `production`.
</ParamField>

<ParamField query="offset" type="integer" default="0">
  Paginierungs-Offset.

  Bereich ≥ 0.
</ParamField>

<ParamField query="limit" type="integer" default="50">
  Seitengröße, max 200.

  Bereich 1 bis 200.
</ParamField>

### Beispielanfrage

```bash theme={null}
curl \
  -H "Authorization: Bearer $OCTOPARSE_API_KEY" \
  "https://api-datahub.octoparse.com/v1/runs?data_app=carol/probe-b&status=SUCCEEDED,PARTIALLY_SUCCEEDED&limit=50"
```

## Antwort

### 200 Erfolg

```json theme={null}
{
  "data": {
    "items": [
      {
        "run_id": "run_3b750088f51c",
        "namespace": "carol",
        "app_name": "probe-b",
        "app_version": "0.1.0",
        "build_id": null,
        "run_kind": "production",
        "state": "RUNNING",
        "input": {
          "product": "p-doc"
        },
        "progress": {
          "done": 0,
          "total": null,
          "status_text": null
        },
        "dataset_id": "ds_ec3ba97b8534",
        "partial": false,
        "cancel_requested": false,
        "triggered_by": "api",
        "upstream_ref": null,
        "created_at": "2026-09-15T07:45:41.876601+00:00",
        "started_at": "2026-09-15T07:45:41.883082+00:00",
        "first_started_at": "2026-09-15T07:45:41.883082+00:00",
        "finished_at": null,
        "usage": {
          "metrics": {
            "records_collected": 0
          },
          "duration_ms": null
        },
        "billing": {
          "events": [],
          "total": 0.0,
          "currency": "USD",
          "charged": false
        },
        "error": null
      },
      "…"
    ],
    "pagination": {
      "offset": 0,
      "limit": 2,
      "count": 2,
      "total": 2,
      "has_more": false
    }
  }
}
```

Payload ist in `data` gewrappt. Felder:

<ResponseField name="items" type="object[]" required>
  Run-Liste. Jeder Eintrag entspricht den Feldern des Run-Details (ohne `sample_records`).

  <Expandable title="fields">
    <ResponseField name="run_id" type="string" required>
      —
    </ResponseField>

    <ResponseField name="namespace" type="string">
      —
    </ResponseField>

    <ResponseField name="app_name" type="string">
      —
    </ResponseField>

    <ResponseField name="app_version" type="string">
      —
    </ResponseField>

    <ResponseField name="build_id" type="string">
      —
    </ResponseField>

    <ResponseField name="run_kind" type="string">
      —
    </ResponseField>

    <ResponseField name="state" type="enum" required>
      Werte: `PENDING` / `QUEUED` / `RUNNING` / `SUCCEEDED` / `PARTIALLY_SUCCEEDED` / `FAILED` / `CANCELLED` / `EXPIRED`.
    </ResponseField>

    <ResponseField name="input" type="object">
      —
    </ResponseField>

    <ResponseField name="progress" type="object">
      —

      <Expandable title="fields">
        <ResponseField name="done" type="integer">
          —
        </ResponseField>

        <ResponseField name="total" type="integer">
          —
        </ResponseField>

        <ResponseField name="status_text" type="string">
          —
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="dataset_id" type="string">
      —
    </ResponseField>

    <ResponseField name="partial" type="boolean">
      —
    </ResponseField>

    <ResponseField name="cancel_requested" type="boolean">
      `true`, solange ein Abbruch angefordert wurde und der Run noch ausläuft (kooperativer Stopp / Wiederherstellung von Teilergebnissen). In Endzuständen immer `false` (serverseitig normalisiert), sodass Clients es nicht aus `state` ableiten müssen.
    </ResponseField>

    <ResponseField name="triggered_by" type="string">
      —
    </ResponseField>

    <ResponseField name="upstream_ref" type="string">
      —
    </ResponseField>

    <ResponseField name="created_at" type="string">
      —
    </ResponseField>

    <ResponseField name="started_at" type="string">
      —
    </ResponseField>

    <ResponseField name="first_started_at" type="string">
      Wann ein Worker den Run zuerst geclaimed hat. Anders als `started_at` wird dies bei Retry nie überschrieben — Anker für Queue-Zeit: queued = `first_started_at - created_at`, Gesamtwandzeit = `finished_at - first_started_at`. Queue-Zeit aus `started_at` abzuleiten zählt frühere Attempts als Queuing. `null` nur bei nie geclaimten Runs.
    </ResponseField>

    <ResponseField name="finished_at" type="string">
      —
    </ResponseField>

    <ResponseField name="usage" type="object">
      Objektives Usage-Metering: wie viel der Run geleistet hat. Getrennt von der Abrechnung; das vergleichen Evaluations.

      <Expandable title="fields">
        <ResponseField name="metrics" type="object">
          —
        </ResponseField>

        <ResponseField name="duration_ms" type="integer">
          —
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="billing" type="object">
      Abrechnungsbuch = Nutzung × Preise × Abrechnungsregeln: wie viel berechnet wird.

      <Expandable title="fields">
        <ResponseField name="events" type="object[]">
          —
        </ResponseField>

        <ResponseField name="total" type="number">
          —
        </ResponseField>

        <ResponseField name="currency" type="string">
          —
        </ResponseField>

        <ResponseField name="charged" type="boolean">
          —
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="error" type="object">
      —

      <Expandable title="fields">
        <ResponseField name="code" type="string" required>
          —
        </ResponseField>

        <ResponseField name="category" type="string">
          —
        </ResponseField>

        <ResponseField name="message" type="string" required>
          —
        </ResponseField>

        <ResponseField name="retryable" type="boolean">
          —
        </ResponseField>

        <ResponseField name="retry_after" type="number">
          —
        </ResponseField>

        <ResponseField name="item_index" type="integer">
          —
        </ResponseField>

        <ResponseField name="details" type="object[]">
          —
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="pagination" type="object">
  Paginierungsobjekt.

  <Expandable title="fields">
    <ResponseField name="offset" type="integer">
      —
    </ResponseField>

    <ResponseField name="limit" type="integer">
      —
    </ResponseField>

    <ResponseField name="count" type="integer">
      —
    </ResponseField>

    <ResponseField name="total" type="integer">
      —
    </ResponseField>

    <ResponseField name="has_more" type="boolean">
      —
    </ResponseField>
  </Expandable>
</ResponseField>

### Fehler

| HTTP | `code`           | `category`      | Beschreibung                                          |
| ---- | ---------------- | --------------- | ----------------------------------------------------- |
| 401  | `unauthorized`   | `forbidden`     | Fehlender oder ungültiger API-Schlüssel.              |
| 400  | `invalid-status` | `invalid_input` | `status` enthält einen Wert außerhalb des Vokabulars. |

Fehlerantworten nutzen `{"error": {code, category, message, retryable}}`. Siehe <a href="/docs/de/datahub/api/reference/introduction#errors">Fehler</a>.

## Client-Bibliotheken

<CodeGroup>
  ```python Python theme={null}
  # Auto-paginate
  for r in client.iterate_runs(data_app="carol/probe-b", created_from="2026-09-01T00:00:00+08:00"):
      print(r["run_id"], r["state"], r["billing"]["total"])

  # Use the page form when you need totals
  page = client.list_runs_page(status="QUEUED,RUNNING", limit=50)
  print(page["pagination"]["total"])
  ```

  ```js JavaScript theme={null}
  // Auto-paginate
  for await (const r of client.iterateRuns({ dataApp: "carol/probe-b", createdFrom: "2026-09-01T00:00:00+08:00" })) {
    console.log(r.run_id, r.state, r.billing.total);
  }

  // Use the page form when you need totals
  const page = await client.listRunsPage({ status: "QUEUED,RUNNING", limit: 50 });
  console.log(page.pagination.total);
  ```
</CodeGroup>
