Skip to main content
This example builds a Node.js script that pages through the events of a date range and writes them to a CSV file and a JSON file. The script waits between pages to stay inside the rate limit of your plan, retries on 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.
Put the tenant alias, the key, and the pace in .env.
Set 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 growing offset. 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.
Run the script with a start date, an end date, and an optional event name. Without arguments it exports yesterday.
The JSON file holds the events with the shape that the Query API returns:
To export one segment, add a filterSet to request in main. Read Filters.

Pace and budget

An export of N 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 minute seconds between two requests.
  • Budget: (requests per day - 1) * 1000 events 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 to export.log.
Rules for the schedule:
  1. Load .env in the cron environment. Cron does not read your shell profile. Use node --env-file=.env (Node.js 20.6 or newer) or export the variables in the crontab.
  2. Leave a gap between two scheduled exports that share a key. Both count against one budget.
  3. 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.