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

# Uso del publicador

> Cómo se llamaron sus apps publicadas en un periodo: totales más desgloses por día, hora, app, canal, estado, versión, código de error o llamador.

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

Autenticación: se requiere API key (`Authorization: Bearer <API Key>`).

Cómo se llamaron sus apps en un periodo: totales del rango, más desgloses por día (o hora en rangos cortos), app y canal de llamada (se pueden cruzar dos cualesquiera), o desgloses de diagnóstico por estado terminal, versión o código de error. Es la contraparte del lado publicador de la agregación de facturación: el mismo vocabulario (`created_from` / `created_to` por hora de inicio de la ejecución, inicio inclusivo y fin exclusivo; `tz_offset` solo mueve límites de día; `data_app` / `triggered_by` acotan el alcance), con la propiedad invertida de «ejecuciones que inicié» a «apps que poseo» (incluidas apps con cero releases).

Los desgloses día/hora/app/canal salen de buckets horarios acumulados en estado terminal, así que cualquier rango y offset de hora completa se mantienen exactos y baratos. Los desgloses estado/versión/error se calculan bajo demanda desde detalles de ejecución, así que ambos límites son obligatorios y el tramo debe ser de como máximo 92 días (`400 range-too-wide`). Los grupos de error solo cubren ejecuciones con error; cada grupo incluye el mensaje de error más reciente como `sample_message`. Las depuraciones del autor se excluyen por defecto; los probes de salud de la plataforma nunca cuentan. El éxito incluye el éxito parcial; las canceladas quedan fuera del denominador de la tasa de éxito; las métricas sin ejecuciones terminales son `null`. `amount` es la tarifa de datos que pagaron los llamadores por estas ejecuciones, no el ingreso liquidado del publicador.

Los grupos día/hora ascienden (las claves `hour` son reloj local `YYYY-MM-DDTHH:00` bajo `tz_offset`, sin sufijo de zona). Los demás grupos descienden por recuento de ejecuciones.

`totals.callers` es el recuento de usuarios llamadores distintos en el rango, desde detalles de ejecución, y solo se establece cuando el rango está acotado y tiene como máximo 92 días. `group_by=caller` desglosa una **única app privada o compartida** por llamador: el autor (`caller_kind=owner`) y los usuarios actualmente en la lista de grants (`grantee`) aparecen bajo su username actual; el resto (ex-grantees, llamadores de un periodo público) se fusiona en un grupo `other`. Apps públicas o varias apps devuelven `400 caller-group-unavailable`: los llamadores de apps públicas permanecen anónimos y solo se cuentan.

## Solicitud

### Parámetros de consulta

<ParamField query="group_by" type="string" default="day">
  Una o dos dimensiones, separadas por comas: `day` / `hour` / `data_app` / `triggered_by` / `state` / `version` / `error` / `caller` (por ejemplo `day,data_app`). `day` y `hour` no se combinan; `state` / `version` / `error` / `caller` necesitan un rango acotado de como máximo 92 días; `caller` también exige exactamente una app privada o compartida. Predeterminado `day`.
</ParamField>

<ParamField query="data_app" type="string[]">
  Limitar a estas apps (`<username>/<app_name>`, repetible). Predeterminado: todas las suyas.
</ParamField>

<ParamField query="created_from" type="string">
  Inicio inclusivo.
</ParamField>

<ParamField query="created_to" type="string">
  Fin exclusivo.
</ParamField>

<ParamField query="tz_offset" type="integer" default="0">
  Offset de zona horaria en minutos para buckets día/hora. Use `480` para la hora estándar de China. Buckets de grano horario; offsets de media hora se redondean a la hora.

  Rango de -720 a 840.
</ParamField>

<ParamField query="triggered_by" type="string">
  Limitar a un canal de llamada (`api` / `sdk` / `mcp` / `web`, etc.).
</ParamField>

<ParamField query="include_test" type="boolean" default="False">
  Si incluir ejecuciones de depuración del autor.
</ParamField>

<ParamField query="compare" type="boolean" default="False">
  También devuelve `previous_totals` de la ventana de igual longitud justo antes de `created_from`. Requiere ambos límites.
</ParamField>

### Ejemplo de solicitud

```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"
```

## Respuesta

### 200 correcto

```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
      }
    ]
  }
}
```

La carga útil va envuelta en `data`. Campos:

<ResponseField name="range" type="object" required>
  El rango y el offset realmente usados.

  <Expandable title="campos">
    <ResponseField name="created_from" type="string">
      Inicio inclusivo realmente aplicado.
    </ResponseField>

    <ResponseField name="created_to" type="string">
      Fin exclusivo realmente aplicado.
    </ResponseField>

    <ResponseField name="tz_offset" type="integer">
      Offset del bucket día/hora en minutos.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="currency" type="string">
  Divisa.
</ResponseField>

<ResponseField name="totals" type="object" required>
  Totales del rango.

  <Expandable title="campos">
    <ResponseField name="runs" type="integer">
      Recuento de ejecuciones.
    </ResponseField>

    <ResponseField name="succeeded" type="integer">
      Recuento de éxitos (incluye éxito parcial).
    </ResponseField>

    <ResponseField name="partial" type="integer">
      Recuento de éxitos parciales.
    </ResponseField>

    <ResponseField name="failed" type="integer">
      Recuento de fallos.
    </ResponseField>

    <ResponseField name="cancelled" type="integer">
      Recuento de cancelaciones.
    </ResponseField>

    <ResponseField name="success_rate" type="number">
      Tasa de éxito; las canceladas no entran en el denominador. `null` si no hay ejecuciones terminales.
    </ResponseField>

    <ResponseField name="records" type="integer">
      Total de registros escritos de vuelta.
    </ResponseField>

    <ResponseField name="avg_duration_ms" type="integer">
      Duración media de ejecución en milisegundos.
    </ResponseField>

    <ResponseField name="amount" type="number">
      Total de tarifas de datos pagadas por llamadores.
    </ResponseField>

    <ResponseField name="apps_active" type="integer">
      Número de apps con al menos una ejecución.
    </ResponseField>

    <ResponseField name="callers" type="integer">
      Usuarios llamadores distintos. `null` si el rango no está acotado o supera 92 días.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="previous_totals" type="object">
  Totales de la ventana previa de igual longitud cuando `compare=true`.

  <Expandable title="campos">
    <ResponseField name="runs" type="integer">
      Recuento de ejecuciones.
    </ResponseField>

    <ResponseField name="succeeded" type="integer">
      Recuento de éxitos (incluye éxito parcial).
    </ResponseField>

    <ResponseField name="partial" type="integer">
      Recuento de éxitos parciales.
    </ResponseField>

    <ResponseField name="failed" type="integer">
      Recuento de fallos.
    </ResponseField>

    <ResponseField name="cancelled" type="integer">
      Recuento de cancelaciones.
    </ResponseField>

    <ResponseField name="success_rate" type="number">
      Tasa de éxito; las canceladas no entran en el denominador.
    </ResponseField>

    <ResponseField name="records" type="integer">
      Total de registros escritos de vuelta.
    </ResponseField>

    <ResponseField name="avg_duration_ms" type="integer">
      Duración media de ejecución en milisegundos.
    </ResponseField>

    <ResponseField name="amount" type="number">
      Total de tarifas de datos pagadas por llamadores.
    </ResponseField>

    <ResponseField name="apps_active" type="integer">
      Número de apps con al menos una ejecución.
    </ResponseField>

    <ResponseField name="callers" type="integer">
      Llamadores (usuarios) distintos en el rango; se calcula desde detalles de ejecución, así que `null` salvo que ambos límites estén dados y a lo sumo 92 días de distancia.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="group_by" type="string">
  Dimensión(es) realmente usada(s).
</ResponseField>

<ResponseField name="groups" type="object[]">
  Filas de grupo. Cada fila lleva las mismas métricas que `totals`, más claves de dimensión (`day` / `hour` / `data_app` / `triggered_by` / `state` / `version` / `error` / `caller` según `group_by`).

  <Expandable title="campos">
    <ResponseField name="runs" type="integer">
      Recuento de ejecuciones del grupo.
    </ResponseField>

    <ResponseField name="succeeded" type="integer">
      Recuento de éxitos (incluye éxito parcial).
    </ResponseField>

    <ResponseField name="partial" type="integer">
      Recuento de éxitos parciales.
    </ResponseField>

    <ResponseField name="failed" type="integer">
      Recuento de fallos.
    </ResponseField>

    <ResponseField name="cancelled" type="integer">
      Recuento de cancelaciones.
    </ResponseField>

    <ResponseField name="success_rate" type="number">
      Tasa de éxito del grupo.
    </ResponseField>

    <ResponseField name="records" type="integer">
      Registros escritos de vuelta en el grupo.
    </ResponseField>

    <ResponseField name="avg_duration_ms" type="integer">
      Duración media de ejecución en milisegundos.
    </ResponseField>

    <ResponseField name="amount" type="number">
      Tarifa de datos pagada por llamadores del grupo.
    </ResponseField>

    <ResponseField name="day" type="string">
      Clave de día al agrupar por día, `YYYY-MM-DD`.
    </ResponseField>

    <ResponseField name="hour" type="string">
      Clave de hora al agrupar por hora: `YYYY-MM-DDTHH:00` local bajo `tz_offset`.
    </ResponseField>

    <ResponseField name="namespace" type="string">
      Nombre de usuario del publicador al agrupar por app.
    </ResponseField>

    <ResponseField name="app_name" type="string">
      Nombre de la app al agrupar por app.
    </ResponseField>

    <ResponseField name="channel" type="string">
      Canal de llamada al agrupar por `triggered_by`.
    </ResponseField>

    <ResponseField name="state" type="string">
      Estado terminal al agrupar por estado.
    </ResponseField>

    <ResponseField name="version" type="string">
      Dimensión de versión: la versión de release fijada; `null` en depuración (fijan un snapshot de build).
    </ResponseField>

    <ResponseField name="error_code" type="string">
      Código de error al agrupar por error.
    </ResponseField>

    <ResponseField name="error_category" type="string">
      Categoría de error al agrupar por error.
    </ResponseField>

    <ResponseField name="sample_message" type="string">
      Dimensión de error: mensaje de la ejecución más reciente de este grupo.
    </ResponseField>

    <ResponseField name="last_seen_at" type="string">
      Marca de tiempo de la ejecución más reciente del grupo.
    </ResponseField>

    <ResponseField name="username" type="string">
      Dimensión de llamador: nombre de usuario actual del llamador; `null` en el grupo `other` o sin username.
    </ResponseField>

    <ResponseField name="caller_kind" type="string">
      Dimensión de llamador: `owner` (ejecuciones del publicador), `grantee` (usuario actualmente en la lista de grants) u `other` (resto de llamadores fusionados).
    </ResponseField>
  </Expandable>
</ResponseField>

### Errores

| HTTP | `code`                     | `category`      | Descripción                                                                                                    |
| ---- | -------------------------- | --------------- | -------------------------------------------------------------------------------------------------------------- |
| 401  | `unauthorized`             | `forbidden`     | API key ausente o no válida.                                                                                   |
| 400  | `invalid-group-by`         | `invalid_input` | `group_by` no está permitido, o la combinación es ilegal.                                                      |
| 400  | `range-too-wide`           | `invalid_input` | Esta dimensión exige `created_from` y `created_to`, a lo sumo 92 días de distancia.                            |
| 400  | `caller-group-unavailable` | `invalid_input` | `group_by=caller` admite exactamente una app privada o compartida.                                             |
| 404  | `app-not-found`            | `not_found`     | La app no existe, se renombró o es invisible para la credencial actual (fuera del alcance privado/compartido). |

Las respuestas de error usan `{"error": {code, category, message, retryable}}`. Véase <a href="/docs/es/datahub/api/reference/introduction#errors">Errores</a>.

## Bibliotecas cliente

Los SDK de Python y JavaScript aún no encapsulan este endpoint. Llame a REST directamente.
