Skip to content

Reporting API

The Reporting API gives you programmatic, read-only access to your ad revenue and performance data — the same data that powers the publisher dashboard.

EndpointUse it for
Impression-level reportOne row per impression, with CPM, ad unit, format, country, OS, and your user ID. Ideal for revenue attribution and data-warehouse ingestion.
Aggregate reportGrouped metrics (revenue, impressions, fill rate, …) by date, ad unit, format, country, OS, or status. Ideal for dashboards and finance reporting.

Base URL

text
https://simula-api-701226639755.us-central1.run.app/reporting/v1/publisher

Authentication

Every request requires a reporting API key in the Authorization header:

text
Authorization: Bearer <your-reporting-key>

Keys are issued by your Simula account manager and are scoped to one or more publisher IDs. If you haven't received yours, reach out over your usual channel — Email, Slack, WhatsApp, or WeChat.

Conventions

  • Timezone — all timestamps are UTC, and daily buckets are UTC calendar days. A trailing Z on datetimes is accepted.
  • Currency — all monetary values are USD.
  • Date range — each request may span at most 31 days. For longer windows, issue multiple requests.
  • Impressions — an ad counts as an impression only once it is actually displayed to the user. Ads served but never shown count toward SERVED, earn no revenue, and never appear in the impression-level report.

Estimated vs. Final Revenue

Every impression carries a status:

StatusMeaning
estimatedServe-time revenue estimate, available immediately.
finalSettled revenue. Settlement completes 7 days after the impression is served; the final value then supersedes the estimated value.

Syncing revenue into your own systems

Data starts as estimated and becomes final 7 days after serve. Re-pull the last 7 days on each sync and overwrite rows by key (impression ID, or dimension combination for aggregates) rather than appending, so finalized values replace estimates.

Pagination

Both endpoints use cursor-based pagination. Each response includes:

json
{
  "pagination": {
    "next_cursor": "eyJvIjo1MDAwLCJlIjoi...",
    "has_more": true
  }
}

Omit cursor on the first request. While has_more is true, repeat the request with cursor set to next_cursor, keeping all other parameters identical.

  • Cursors are bound to the exact query that produced them — changing any parameter invalidates the cursor (400 Invalid cursor).
  • Cursors expire after 24 hours.

Rate Limits

ScopeLimit
Per API key60 requests / minute
Per IP (unauthenticated)20 requests / minute

Exceeding a limit returns 429. Back off and retry after a short delay — with page sizes of up to 10,000 rows, most workloads fit comfortably under the limit.

Errors

StatusMeaning
400Invalid request — malformed dates, date_end not after date_start, range over 31 days, invalid or expired cursor, or an unsupported metric/dimension combination. The detail field explains the problem.
401Missing or unknown API key.
403Key is not authorized for the requested publisher_id.
429Rate limit exceeded.
json
{
  "detail": "Date range exceeds 31 days"
}