429 after Retry-After seconds, and runs from cron.
The Query API needs the Builder plan or higher and an API key with the Query API permission.
Read Query API.
Files
The script uses the global
fetch of Node.js 18 or newer and has no runtime dependency.
.env.
GRAIN_REQUESTS_PER_MINUTE to the per-minute limit of your plan. Read the pace table
below.
The API client
send makes one request. On 429 it waits Retry-After seconds and retries, up to
MAX_RETRIES times. On a network error it waits with exponential backoff. On any other error
status it throws at once, because a retry cannot change a 401, a 403, or a 404.
The script
The script counts the events first, then reads pages of 1,000 with a growingoffset. Between
two requests it waits 60 / GRAIN_REQUESTS_PER_MINUTE seconds. The CSV has one column per
event field and one column per property key that appears in the export.
filterSet to request in main. Read
Filters.
Pace and budget
An export ofN events costs 1 + ceil(N / 1000) requests: one count and one request per page.
Both limits of the plan apply to the same API key:
- Pace: wait at least
60 / requests per minuteseconds between two requests. - Budget:
(requests per day - 1) * 1000events per day, if no other client uses the key.
If a date range holds more events than the daily budget, export it one day at a time on
consecutive days, or narrow it with
event or filterSet.
Scheduled run
Run the script from cron at a fixed time. The line below exports yesterday every day at 02:00 and appends the log toexport.log.
- Load
.envin the cron environment. Cron does not read your shell profile. Usenode --env-file=.env(Node.js 20.6 or newer) or export the variables in the crontab. - Leave a gap between two scheduled exports that share a key. Both count against one budget.
- Make sure that a run finishes before the next one starts. A Builder export of 19,000 events takes about 10 minutes at 30 seconds per page.
Errors
Limits
Read Custom dashboard for a Next.js page that polls the
same endpoints.