Automate reports — daily e-mails and pulling data over the API
Get yesterday's numbers without opening the console — schedule a saved report by e-mail, pull it over the analytics REST API from a script, and forward it to a chat or spreadsheet.
Two ways to get numbers out of Epom on a schedule: let Epom e-mail a saved report, or have your own script pull it over the analytics API and send it wherever you need — a chat, a spreadsheet, a billing system.
Who this is for
Anyone who can run reports. The API needs your API key or your password-based hash; both are described in the API overview.
Prerequisites
- Access to Analytics, and a report you can build there — see Run a report.
- For e-mail: at least one recipient address on the saved report, and outbound mail configured by Epom for your network.
- For the API: your login and password (for the signed URL), or an API key. Calling with an API key needs the API Key Access permission on your role — no stock role has it, so ask your network administrator; see the API overview.
Steps
Pick one of the two options below — or both: e-mail for people, the API for scripts.
Option 1 — a daily e-mail (no code)
- Account → Analytics, build the report: type, Yesterday as the date range, group-by and columns.
- Save it as a template.
- In Saved reports, click the clock icon, pick the days (every weekday, or days of the month), an hour in UTC and a format — CSV, XLSX, PDF, HTML or JSON — and click Add.
- Add recipients under Report recipients.
The schedule is checked once an hour; the report runs with its saved range relative to the run day, so Yesterday always means the day before the e-mail. Details and every option: Save, reuse and schedule reports.
Option 2 — pull yesterday’s data from a script
The analytics API runs the same reports as the console. One call returns yesterday’s figures grouped by site and country as CSV:
TS=$(date +%s000) # Unix time in milliseconds
HASH=$(printf '%s%s' "$(printf '%s' "$PASSWORD" | md5sum | cut -d' ' -f1)" "$TS" | md5sum | cut -d' ' -f1)
curl -o yesterday.csv \
"https://<your-network-domain>/rest-api/analytics/CSV/$LOGIN/$HASH/$TS.do?range=YESTERDAY&groupBy=SITE&groupBy=COUNTRY"
Or with an API key, as JSON:
curl -H "X-Api-Key: $APIKEY" "https://<your-network-domain>/rest-api/analytics/JSON.do?range=YESTERDAY&groupBy=CAMPAIGN&groupRange=DAY&jsonKeys=id"
jsonKeys=id names each JSON field by its column id (impressions, sumGross) instead of the
column’s display name in your interface language, so the script reads the same keys whoever runs it
and no two columns share one — see JSON output.
Useful parameters (full list in the Analytics reports via API):
| Parameter | For |
|---|---|
range=YESTERDAY, LAST_7_DAYS, LAST_MONTH … or CUSTOM with customFrom / customTo | The period |
groupBy (repeatable) | Rows per site, campaign, country … |
groupRange=DAY / HOUR | One row per day / hour |
statisticType | Leave out for the General report; HADOOP for Advanced |
limit, offset | Paging; without limit you get up to your network’s records-per-request limit |
A saved report can be fetched by its definition too: GET /rest-api/saved-reports/{id}.do
returns its params under exactly these names.
Note — run it after midnight in the reporting time zone. “Yesterday” is the day before in the ad server’s reporting time zone (General) or in the report’s own time zone (Advanced). A script run at 00:05 gets a complete yesterday from General; late-arriving data can still move it slightly for a few hours. See Which time zone do reports use?.
Steps for a scripted pull
- Check your quota once:
GET /rest-api/network/settings.doreturnsanalyticsApiwithdailyRequestLimit,requestsUsedTodayandrecordsPerRequestLimit. - Build the report in the console first, so you know which
groupBy,rangeandstatisticTypegive the rows you want — or save it and read itsparamsfromGET /rest-api/saved-reports/{id}.do. - Put one of the calls above in a scheduled job, timed after midnight in the reporting time zone.
- Check the HTTP status before using the body:
200is a report;400,401,403and429keep a JSON body withsuccess:falseand the reason.
Forward it to a chat, a sheet or a bot
Epom does not post to messengers itself. Put the call above in a scheduled job (cron, a CI
scheduler, a cloud function), turn the JSON or CSV into a message, and send it with the
destination’s own API — Telegram’s sendMessage / sendDocument, a Slack incoming webhook, a
Google Sheets append. The analytics call is the only Epom part.
Limits to plan for
- Each user has a daily number of report requests; once used up, calls answer
429until the next day.GET /rest-api/network/settings.doshowsdailyRequestLimitandrequestsUsedTodayunderanalyticsApi. - A
limitabove the records-per-request limit is a400. Page withoffsetinstead. - Pull one report grouped by the dimension you need — not one call per campaign.
- Advanced reports only cover the short window of days the event logs are kept for; daily jobs over long periods belong on the General report.
Corner cases and gotchas
Corner case: a scheduled report with no recipients is rendered on time and sent to nobody. The owner is not added automatically — add your own address if you want a copy.
Corner case: a report scheduled on day 29, 30 or 31 of the month is skipped in months that have no such day. To get a month-end report every month, schedule day 1 with a Last month range instead.
Corner case: nothing is sent while the account that owns the saved report — or its parent account — is inactive. The schedule stays in place and resumes when the account is re-activated.
Corner case: the e-mailed file is cut at your network’s row limit for its format (CSV, XLSX, PDF, HTML and JSON each have their own). If the file looks truncated, group more coarsely or pull it over the API with
limitandoffset.
Corner case: the e-mail runs the report as its owner — with the owner’s permissions, in the owner’s interface language and with the columns saved in the report — whoever the recipients are.
Corner case: a signed (login / hash / timestamp) call from a deactivated account is refused with
401, like every other REST call — a script under a departed colleague’s login stops working the day the account is switched off. Use a dedicated reporting user.
Per-role notes
- Network manager, publisher, advertiser — identical. Both the e-mail and the API return only the entities and columns your role may see in the console; shared inventory and campaigns show the names your share allows.
- Saved reports are private to each login — a colleague cannot schedule yours; add them as a recipient instead.
- Custom-role users — an API key needs API Key Access; a report type or column the role lacks
answers
403naming the missing reporting permission.