API reference

Use the Public Reports API to pull approved app lists, daily active-device reports, country breakdowns, and monthly earnings history. SDK protocol notes are included below for diagnostics.

Public Reports API New in 2026-06-29

The Public Reports API lets approved developers export app, device, and earnings reports without using the dashboard UI.

Base URLhttps://app.getpassive.io/api/public/v1
AuthenticationSend an Api-Key: gpr_pk_... header. Create report keys in dashboard settings.
Content typeResponses are JSON. Request bodies are not used for the current GET endpoints.
Rate limitsNot enforced yet. Use reasonable backoff, cache monthly reports, and avoid tight polling loops.
GET /api/public/v1/apps HTTP/1.1
Host: app.getpassive.io
Api-Key: gpr_pk_...

Report API keys are separate from SDK developer keys. Use gpr_pk_... keys for reports and gp_pk_... keys for SDK clients.

GET /apps

Lists approved apps available to the report key. Use the returned app_id when requesting reports.

Example request

GET https://app.getpassive.io/api/public/v1/apps
Api-Key: gpr_pk_live_1234567890abcdef

Example response

{
  "ok": true,
  "apps": [
    {
      "app_id": 42,
      "name": "Example Desktop App",
      "platform": "Node.js desktop helper",
      "status": "approved",
      "created_at": "2026-05-30T12:00:00Z"
    }
  ]
}

GET /reports/daily

Returns daily active device counts for a month plus the monthly earnings total for the selected app.

Parameters

NameTypeRequiredDescription
app_idintegerYesApp ID from GET /apps.
monthstringYesMonth in YYYY-MM format.

Example request

GET https://app.getpassive.io/api/public/v1/reports/daily?app_id=42&month=2026-06
Api-Key: gpr_pk_live_1234567890abcdef

Example response

{
  "ok": true,
  "app_id": 42,
  "month": "2026-06",
  "currency": "USD",
  "monthly_earnings_total": "1842.35",
  "days": [
    { "date": "2026-06-01", "active_devices": 1284, "earnings": "59.42" },
    { "date": "2026-06-02", "active_devices": 1311, "earnings": "61.08" }
  ]
}

GET /reports/by_country

Returns a day-by-day country breakdown for active devices and earnings. Devices in restricted countries are not counted or monetized.

Parameters

NameTypeRequiredDescription
app_idintegerYesApp ID from GET /apps.
monthstringYesMonth in YYYY-MM format.

Example request

GET https://app.getpassive.io/api/public/v1/reports/by_country?app_id=42&month=2026-06
Api-Key: gpr_pk_live_1234567890abcdef

Example response

{
  "ok": true,
  "app_id": 42,
  "month": "2026-06",
  "currency": "USD",
  "days": [
    {
      "date": "2026-06-01",
      "countries": [
        { "country": "US", "active_devices": 820, "earnings": "41.20" },
        { "country": "GB", "active_devices": 144, "earnings": "7.18" },
        { "country": "DE", "active_devices": 96, "earnings": "4.31" }
      ]
    }
  ]
}

GET /reports/earnings

Returns monthly earnings history for an app. The response includes up to the most recent 36 months available to the report key.

Parameters

NameTypeRequiredDescription
app_idintegerYesApp ID from GET /apps.

Example request

GET https://app.getpassive.io/api/public/v1/reports/earnings?app_id=42
Api-Key: gpr_pk_live_1234567890abcdef

Example response

{
  "ok": true,
  "app_id": 42,
  "currency": "USD",
  "months": [
    { "month": "2026-06", "active_device_days": 39210, "earnings": "1842.35", "status": "estimated" },
    { "month": "2026-05", "active_device_days": 37104, "earnings": "1730.19", "status": "final" }
  ]
}

Errors

Errors use standard HTTP status codes and a JSON body with a stable error string.

StatusMeaning
400Missing or invalid query parameter, such as an invalid month.
401Missing, invalid, or revoked report API key.
403The key does not have access to the requested app.
404App or report not found.
500Unexpected server error. Retry with backoff.
{
  "ok": false,
  "error": "invalid_month",
  "message": "month must use YYYY-MM format"
}

SDK protocol

Most developers should use @getpassive/sdk rather than implementing this protocol directly. The notes below are useful for diagnostics and internal tooling.

WebSocket gateway handshake

GET wss://sdk.getpassive.io/
Upgrade: websocket

After the WebSocket opens, the SDK sends a single JSON handshake line:

{
  "device_uuid": "f2c1c1a0-9f4e-4b9a-9a30-1d4c8a0b1c2e",
  "dev_api_key": "gp_pk_********************************",
  "client_version": "0.1.1",
  "public_ip": "203.0.113.42"
}

The gateway validates the developer key, app status, consent confirmation, and device eligibility before keeping the connection alive. After validation, the SDK accepts approved stream frames over the WebSocket. This wire format is not a public stability contract; use the SDK package for production integrations.

Last updated June 29, 2026