Partner integration specification
Cost Reporting API
The reporting API Singular pulls from to ingest aggregated campaign cost data on behalf of a mutual customer. Daily pull, one credential per advertiser.
- Integration type
- API (pull)
- Endpoint
https://api.adsfive.com/reporting- Protocol
- HTTPS,
GETonly - Formats
- JSON (default) or CSV
- Timezone
- UTC
- Currency
- USD
- Granularity
- Date × App × Campaign
- History
- 90 days
- Recommended pull
- Once daily, trailing 7 days
1Overview
A single authenticated GET returns day-level cost and install data for one advertiser, aggregated to date × app × campaign. Every request is independent and recomputed from source, so re-pulling a window always reflects the latest state.
Rows carry only the six fields listed in §4. Columns we do not populate are omitted from the payload entirely rather than returned blank.
2Authentication
A distinct API key is issued per customer, so each advertiser's data is pulled and differentiated separately.
Authorization: Bearer <api_key>
X-API-Key: <api_key> and ?api_key=<api_key> are also accepted.
3Endpoint
GET https://api.adsfive.com/reporting
| Parameter | Required | Format | Description |
|---|---|---|---|
| start_date | Yes | YYYY-MM-DD | First day of the report, inclusive (UTC) |
| end_date | Yes | YYYY-MM-DD | Last day of the report, inclusive (UTC) |
| format | No | json | csv | Defaults to json |
start and end are accepted as aliases.
A single request may span any date range, so the recommended pattern is one request per pull — the trailing 7 days in one call — rather than one request per day. Day-by-day iteration is equally supported if that suits your connector.
GET /reporting?start_date=2026-06-01&end_date=2026-06-07
Authorization: Bearer <api_key>
4Response fields
| Singular dimension | JSON key | CSV header | Type | Notes |
|---|---|---|---|---|
| Date | date | Date | YYYY-MM-DD | UTC |
| App | app | App | string | Matches the app name in the advertiser's Singular account |
| Store ID | store_id | Store ID | string | iOS Store ID or Android package name |
| Campaign Name | campaign_name | Campaign Name | string | — |
| Cost | cost | Cost | number | Total spend for the row in USD, 2 decimal places — not a per-install rate |
| Installs | installs | Installs | integer | Installs reported by us |
{
"status": "ok",
"start_date": "2026-06-01",
"end_date": "2026-06-07",
"timezone": "UTC",
"currency": "USD",
"row_count": 2,
"rows": [
{
"date": "2026-06-01",
"app": "SkeeBoost",
"store_id": "6449432839",
"campaign_name": "Skeeboost_US_iOS_1",
"cost": 184.80,
"installs": 56
},
{
"date": "2026-06-02",
"app": "SkeeBoost",
"store_id": "6449432839",
"campaign_name": "Skeeboost_US_iOS_1",
"cost": 234.30,
"installs": 71
}
]
}
Date,App,Store ID,Campaign Name,Cost,Installs
2026-06-01,SkeeBoost,6449432839,Skeeboost_US_iOS_1,184.8,56
2026-06-02,SkeeBoost,6449432839,Skeeboost_US_iOS_1,234.3,71
5Data freshness and history
- Figures are finalised by a daily process that runs at 00:00 UTC for the day that just closed. The most recent complete day is therefore yesterday.
- If
end_dateis later than yesterday it is clamped to yesterday, and the adjustment is reported in anoticesarray on the response. The request still succeeds. - 90 days of history are available, so an initial ~3-month backfill is served in full. A request reaching further back is clamped to the earliest available day, again reported in
notices, rather than returning an error. - Figures for a given day may be restated for a short period as conversions settle. Re-pulling the trailing 7 days daily, as is standard, picks these up automatically.
6Errors
| Status | Meaning |
|---|---|
| 200 | Success |
| 400 | Missing or malformed parameters (bad date format, inverted range) |
| 401 | Missing or invalid API key |
| 500 | Internal error; safe to retry |
Errors return {"status": "error", "error": "<description>"}.
An empty rows array with 200 means there was no qualifying activity in the window — a valid, successful response, not an error.