> ## 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.

# Publisher-Nutzung

> Wie Ihre veröffentlichten Apps in einem Zeitraum aufgerufen wurden: Totals plus Aufschlüsselungen nach Tag, Stunde, App, Kanal, Status, Version, Fehlercode oder Caller.

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

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

Wie Ihre Apps in einem Zeitraum aufgerufen wurden: Summen für den Bereich sowie Aufschlüsselungen nach Tag (oder Stunde bei kurzen Bereichen), App und Aufrufkanal (zwei davon lassen sich kreuzen) oder diagnostische Aufschlüsselungen nach Endzustand, Version oder Fehlercode. Dies ist das Publisher-seitige Gegenstück zur Abrechnungsaggregation: dasselbe Vokabular (`created_from` / `created_to` bezogen auf die Startzeit des Runs, Beginn inklusiv und Ende exklusiv; `tz_offset` verschiebt nur die Tagesgrenzen; `data_app` / `triggered_by` grenzen den Umfang ein), wobei die Zuordnung von „von mir gestartete Runs“ zu „Apps, die mir gehören“ wechselt (einschließlich Apps ohne Release).

Aufschlüsselungen nach Tag / Stunde / App / Kanal stammen aus Stunden-Buckets, die beim Erreichen des Endzustands aufsummiert werden, sodass jeder Bereich und jeder volle Stunden-Offset exakt und günstig bleibt. Aufschlüsselungen nach Status / Version / Fehler werden bei Bedarf aus den Run-Details berechnet; daher sind beide Grenzen erforderlich und der Zeitraum darf höchstens 92 Tage umfassen (`400 range-too-wide`). Fehlergruppen umfassen nur Runs mit einem Fehler; jede Gruppe enthält die neueste Fehlermeldung als `sample_message`. Debug-Runs des Autors sind standardmäßig ausgeschlossen; Health-Probes der Plattform zählen nie. Erfolg schließt Teilerfolg ein; abgebrochene Runs bleiben aus dem Nenner der Erfolgsquote heraus; Kennzahlen ohne beendete Runs sind `null`. `amount` ist die Datengebühr, die Aufrufer für diese Runs bezahlt haben, nicht der abgerechnete Umsatz des Publishers.

Tages- und Stundengruppen sind aufsteigend sortiert (`hour`-Schlüssel sind lokale Uhrzeiten `YYYY-MM-DDTHH:00` unter `tz_offset`, ohne Zeitzonensuffix). Andere Gruppen sind absteigend nach Anzahl der Runs sortiert. Unbekannte oder fremde Apps in `data_app` liefern `404`.

`totals.callers` ist die Anzahl eindeutiger aufrufender Benutzer im Bereich, ermittelt aus den Run-Details, und wird nur gesetzt, wenn der Bereich begrenzt ist und höchstens 92 Tage umfasst. `group_by=caller` schlüsselt eine **einzelne private oder geteilte App** nach Aufrufer auf: Der Autor (`caller_kind=owner`) und Benutzer, die aktuell auf der Grant-Liste stehen (`grantee`), erscheinen unter ihrem aktuellen Benutzernamen; alle anderen (ehemalige Grantees, Aufrufer aus einer öffentlichen Phase) werden in einer Gruppe `other` zusammengefasst. Öffentliche Apps oder mehrere Apps liefern `400 caller-group-unavailable`: Aufrufer öffentlicher Apps bleiben anonym und werden nur gezählt.

## Anfrage

### Abfrageparameter

<ParamField query="group_by" type="string" default="day">
  Eine oder zwei Dimensionen, durch Kommas getrennt: `day` / `hour` / `data_app` / `triggered_by` / `state` / `version` / `error` / `caller` (zum Beispiel `day,data_app`). `day` und `hour` lassen sich nicht kombinieren; `state` / `version` / `error` / `caller` benötigen einen begrenzten Bereich von höchstens 92 Tagen; `caller` erfordert außerdem genau eine private oder geteilte App. Standard ist `day`.
</ParamField>

<ParamField query="data_app" type="string[]">
  Auf diese Apps beschränken (`<username>/<app_name>`, wiederholbar). Standard: alle Ihre Apps.
</ParamField>

<ParamField query="created_from" type="string">
  Inklusiver Start.
</ParamField>

<ParamField query="created_to" type="string">
  Exklusives Ende.
</ParamField>

<ParamField query="tz_offset" type="integer" default="0">
  Zeitzonen-Offset in Minuten für Tages- und Stunden-Buckets. Verwenden Sie `480` für China Standard Time. Buckets haben Stundengranularität; Offsets mit halben Stunden werden auf die volle Stunde gerundet.

  Bereich -720 bis 840.
</ParamField>

<ParamField query="triggered_by" type="string">
  Auf einen Aufrufkanal beschränken (`api` / `sdk` / `mcp` / `web` usw.).
</ParamField>

<ParamField query="include_test" type="boolean" default="False">
  Ob Autor-Debug-Runs einbezogen werden.
</ParamField>

<ParamField query="compare" type="boolean" default="False">
  Liefert zusätzlich `previous_totals` für das gleich lange Zeitfenster unmittelbar vor `created_from`. Erfordert beide Grenzen.
</ParamField>

### Beispielanfrage

```bash theme={null}
curl \
  -H "Authorization: Bearer $OCTOPARSE_API_KEY" \
  "https://api-datahub.octoparse.com/v1/publisher/usage?group_by=day,data_app&created_from=2026-09-01T00:00:00%2B08:00&created_to=2026-10-01T00:00:00%2B08:00&tz_offset=480"
```

## Antwort

### 200 Erfolg

```json theme={null}
{
  "data": {
    "range": {
      "created_from": null,
      "created_to": null,
      "tz_offset": 480
    },
    "currency": "CNY",
    "totals": {
      "runs": 2,
      "succeeded": 2,
      "partial": 0,
      "failed": 0,
      "cancelled": 0,
      "success_rate": 1.0,
      "records": 40,
      "avg_duration_ms": 422,
      "amount": 0.04,
      "apps_active": 1,
      "callers": null
    },
    "previous_totals": null,
    "group_by": "day",
    "groups": [
      {
        "runs": 2,
        "succeeded": 2,
        "partial": 0,
        "failed": 0,
        "cancelled": 0,
        "success_rate": 1.0,
        "records": 40,
        "avg_duration_ms": 422,
        "amount": 0.04,
        "day": "2026-09-15",
        "hour": null,
        "namespace": null,
        "app_name": null,
        "channel": null,
        "state": null,
        "version": null,
        "error_code": null,
        "error_category": null,
        "sample_message": null,
        "last_seen_at": null,
        "username": null,
        "caller_kind": null
      }
    ]
  }
}
```

Payload ist in `data` gewrappt. Felder:

<ResponseField name="range" type="object" required>
  Der tatsächlich verwendete Bereich und Offset.

  <Expandable title="fields">
    <ResponseField name="created_from" type="string">
      Tatsächlich angewendeter Beginn (inklusiv).
    </ResponseField>

    <ResponseField name="created_to" type="string">
      Tatsächlich angewendetes Ende (exklusiv).
    </ResponseField>

    <ResponseField name="tz_offset" type="integer">
      Offset der Tages- und Stunden-Buckets in Minuten.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="currency" type="string">
  Währung.
</ResponseField>

<ResponseField name="totals" type="object" required>
  Summen für den Bereich.

  <Expandable title="fields">
    <ResponseField name="runs" type="integer">
      Anzahl der Runs.
    </ResponseField>

    <ResponseField name="succeeded" type="integer">
      Anzahl erfolgreicher Runs (einschließlich Teilerfolgen).
    </ResponseField>

    <ResponseField name="partial" type="integer">
      Anzahl der Teilerfolge.
    </ResponseField>

    <ResponseField name="failed" type="integer">
      Anzahl der Fehlschläge.
    </ResponseField>

    <ResponseField name="cancelled" type="integer">
      Anzahl der Abbrüche.
    </ResponseField>

    <ResponseField name="success_rate" type="number">
      Erfolgsquote; abgebrochene Runs bleiben aus dem Nenner heraus. `null`, wenn es keine beendeten Runs gibt.
    </ResponseField>

    <ResponseField name="records" type="integer">
      Gesamtzahl der zurückgeschriebenen Datensätze.
    </ResponseField>

    <ResponseField name="avg_duration_ms" type="integer">
      Durchschnittliche Ausführungsdauer in Millisekunden.
    </ResponseField>

    <ResponseField name="amount" type="number">
      Summe der von Aufrufern gezahlten Datengebühren.
    </ResponseField>

    <ResponseField name="apps_active" type="integer">
      Anzahl der Apps mit mindestens einem Run.
    </ResponseField>

    <ResponseField name="callers" type="integer">
      Eindeutige aufrufende Benutzer. `null`, wenn der Bereich unbegrenzt oder größer als 92 Tage ist.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="previous_totals" type="object">
  Summen des gleich langen vorherigen Zeitfensters bei `compare=true`.

  <Expandable title="fields">
    <ResponseField name="runs" type="integer">
      Anzahl der Runs.
    </ResponseField>

    <ResponseField name="succeeded" type="integer">
      Anzahl erfolgreicher Runs (einschließlich Teilerfolgen).
    </ResponseField>

    <ResponseField name="partial" type="integer">
      Anzahl der Teilerfolge.
    </ResponseField>

    <ResponseField name="failed" type="integer">
      Anzahl der Fehlschläge.
    </ResponseField>

    <ResponseField name="cancelled" type="integer">
      Anzahl der Abbrüche.
    </ResponseField>

    <ResponseField name="success_rate" type="number">
      Erfolgsquote; abgebrochene Runs bleiben aus dem Nenner heraus.
    </ResponseField>

    <ResponseField name="records" type="integer">
      Gesamtzahl der zurückgeschriebenen Datensätze.
    </ResponseField>

    <ResponseField name="avg_duration_ms" type="integer">
      Durchschnittliche Ausführungsdauer in Millisekunden.
    </ResponseField>

    <ResponseField name="amount" type="number">
      Summe der von Aufrufern gezahlten Datengebühren.
    </ResponseField>

    <ResponseField name="apps_active" type="integer">
      Anzahl der Apps mit mindestens einem Run.
    </ResponseField>

    <ResponseField name="callers" type="integer">
      Eindeutige Aufrufer (Benutzer) im Bereich; aus den Run-Details berechnet, daher `null`, sofern nicht beide Grenzen angegeben sind und höchstens 92 Tage auseinanderliegen.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="group_by" type="string">
  Tatsächlich verwendete Dimension(en).
</ResponseField>

<ResponseField name="groups" type="object[]">
  Gruppenzeilen. Jede Zeile enthält dieselben Kennzahlen wie `totals` plus Dimensionsschlüssel (`day` / `hour` / `namespace` + `app_name` / `channel` / `state` / `version` / `error_code` + `error_category` + `sample_message` + `last_seen_at` / `username` + `caller_kind`). Nicht verwendete Schlüssel sind `null`.

  <Expandable title="fields">
    <ResponseField name="runs" type="integer">
      Run-Anzahl in der Gruppe.
    </ResponseField>

    <ResponseField name="succeeded" type="integer">
      Anzahl erfolgreicher Runs (einschließlich Teilerfolgen).
    </ResponseField>

    <ResponseField name="partial" type="integer">
      Anzahl der Teilerfolge.
    </ResponseField>

    <ResponseField name="failed" type="integer">
      Anzahl der Fehlschläge.
    </ResponseField>

    <ResponseField name="cancelled" type="integer">
      Anzahl der Abbrüche.
    </ResponseField>

    <ResponseField name="success_rate" type="number">
      Erfolgsquote der Gruppe.
    </ResponseField>

    <ResponseField name="records" type="integer">
      In der Gruppe zurückgeschriebene Datensätze.
    </ResponseField>

    <ResponseField name="avg_duration_ms" type="integer">
      Durchschnittliche Ausführungsdauer in Millisekunden.
    </ResponseField>

    <ResponseField name="amount" type="number">
      Von Aufrufern in der Gruppe gezahlte Datengebühr.
    </ResponseField>

    <ResponseField name="day" type="string">
      Tagesschlüssel bei Gruppierung nach Tag, `YYYY-MM-DD`.
    </ResponseField>

    <ResponseField name="hour" type="string">
      Stundenschlüssel bei Gruppierung nach Stunde: lokal `YYYY-MM-DDTHH:00` unter `tz_offset`.
    </ResponseField>

    <ResponseField name="namespace" type="string">
      Publisher-Benutzername bei Gruppierung nach App.
    </ResponseField>

    <ResponseField name="app_name" type="string">
      App-Name bei Gruppierung nach app.
    </ResponseField>

    <ResponseField name="channel" type="string">
      Aufrufkanal bei Gruppierung nach `triggered_by`.
    </ResponseField>

    <ResponseField name="state" type="string">
      Endzustand bei Gruppierung nach Status.
    </ResponseField>

    <ResponseField name="version" type="string">
      Versionsdimension: die Release-Version, an die der Run gebunden war; `null` bei Debug-Runs (sie sind an einen Build-Snapshot gebunden).
    </ResponseField>

    <ResponseField name="error_code" type="string">
      Fehlercode bei Gruppierung nach Fehler.
    </ResponseField>

    <ResponseField name="error_category" type="string">
      Fehlerkategorie bei Gruppierung nach Fehler.
    </ResponseField>

    <ResponseField name="sample_message" type="string">
      Fehlerdimension: Meldung des neuesten Runs in dieser Gruppe.
    </ResponseField>

    <ResponseField name="last_seen_at" type="string">
      Zeitstempel des neuesten Runs in der Gruppe.
    </ResponseField>

    <ResponseField name="username" type="string">
      Aufruferdimension: der aktuelle Benutzername des Aufrufers; `null` für die zusammengefasste Gruppe `other` oder wenn der Benutzer keinen Benutzernamen hat.
    </ResponseField>

    <ResponseField name="caller_kind" type="string">
      Aufruferdimension: `owner` (eigene Runs des Publishers), `grantee` (ein Benutzer, der aktuell auf der Grant-Liste der App steht) oder `other` (alle übrigen Aufrufer, in einer Gruppe zusammengefasst).
    </ResponseField>
  </Expandable>
</ResponseField>

### Fehler

| HTTP | `code`                     | `category`      | Beschreibung                                                                                                           |
| ---- | -------------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------- |
| 401  | `unauthorized`             | `forbidden`     | Fehlender oder ungültiger API-Schlüssel.                                                                               |
| 400  | `invalid-group-by`         | `invalid_input` | `group_by` ist nicht erlaubt, oder die Kombination ist unzulässig.                                                     |
| 400  | `range-too-wide`           | `invalid_input` | Diese Dimension erfordert sowohl `created_from` als auch `created_to`, höchstens 92 Tage auseinander.                  |
| 400  | `caller-group-unavailable` | `invalid_input` | `group_by=caller` unterstützt genau eine private oder geteilte App.                                                    |
| 404  | `app-not-found`            | `not_found`     | App existiert nicht, wurde umbenannt oder ist für die aktuelle Credential unsichtbar (außerhalb private/shared Scope). |

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

## Client-Bibliotheken

Die Python- und JavaScript-SDKs wrappen diesen Endpoint noch nicht. REST direkt aufrufen.
