Export Events to CSV

Paginate and export visitor data to CSV with multi-day chunking

Steps

1. Choose Your Fields

Use select to return only the fields you need. This reduces response size and makes the CSV cleaner.

select=first_name,last_name,email,company_name,company_domain,job_title,event_data,timestamp

Fields that are null for a given row are omitted from the response. See the Events API schema endpoint for all available fields.

2. Export with Pagination

The API returns a maximum of limit rows per request. Use offset to paginate.

import csv
import time
import requests

API_KEY = "your_api_key"
API_SECRET = "your_api_secret"
PIXEL_ID = "your_pixel_id"

HEADERS = {
    "X-Api-Key": API_KEY,
    "X-Api-Secret": API_SECRET,
}

FIELDS = [
    "first_name", "last_name", "email", "current_business_email",
    "company_name", "company_domain", "job_title", "department",
    "seniority_level", "company_industry", "company_employee_count_range",
    "linkedin_url", "event_data", "timestamp",
]

# Last 24 hours
end_ms = int(time.time() * 1000)
start_ms = end_ms - (24 * 60 * 60 * 1000)

all_rows = []
offset = 0
limit = 100

while True:
    resp = requests.get(
        "https://api.delivr.ai/api/v3/events/resolution_full_profile",
        headers=HEADERS,
        params={
            "source": "pixel",
            "pixel_id": PIXEL_ID,
            "start_ms": start_ms,
            "end_ms": end_ms,
            "limit": limit,
            "offset": offset,
            "filter": "resolved:eq:true",
            "select": ",".join(FIELDS),
            "orderby": "timestamp:desc",
        },
    )
    data = resp.json()
    rows = data.get("rows", [])
    all_rows.extend(rows)

    if len(rows) < limit:
        break  # No more rows
    offset += limit

# Write CSV
with open("visitors.csv", "w", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=FIELDS, extrasaction="ignore")
    writer.writeheader()
    for row in all_rows:
        writer.writerow(row)

print(f"Exported {len(all_rows)} rows to visitors.csv")

Multi-Day Export

The Events API has a 25-hour maximum time window per request. For longer ranges, loop through 24-hour chunks.

import csv
import time
import datetime
import requests

API_KEY = "your_api_key"
API_SECRET = "your_api_secret"
PIXEL_ID = "your_pixel_id"

HEADERS = {
    "X-Api-Key": API_KEY,
    "X-Api-Secret": API_SECRET,
}

FIELDS = [
    "first_name", "last_name", "email", "current_business_email",
    "company_name", "company_domain", "job_title", "timestamp",
]

ONE_DAY_MS = 24 * 60 * 60 * 1000
DAYS_BACK = 7

now_ms = int(time.time() * 1000)
all_rows = []

for day in range(DAYS_BACK):
    end_ms = now_ms - (day * ONE_DAY_MS)
    start_ms = end_ms - ONE_DAY_MS
    offset = 0

    while True:
        resp = requests.get(
            "https://api.delivr.ai/api/v3/events/resolution_full_profile",
            headers=HEADERS,
            params={
                "source": "pixel",
                "pixel_id": PIXEL_ID,
                "start_ms": start_ms,
                "end_ms": end_ms,
                "limit": 100,
                "offset": offset,
                "filter": "resolved:eq:true",
                "select": ",".join(FIELDS),
            },
        )
        rows = resp.json().get("rows", [])
        all_rows.extend(rows)

        if len(rows) < 100:
            break
        offset += 100

    date_str = datetime.datetime.fromtimestamp(
        start_ms / 1000, tz=datetime.timezone.utc
    ).strftime("%Y-%m-%d")
    print(f"  {date_str}: fetched to offset {offset + len(rows)}")

with open("visitors_7day.csv", "w", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=FIELDS, extrasaction="ignore")
    writer.writeheader()
    for row in all_rows:
        writer.writerow(row)

print(f"Exported {len(all_rows)} rows to visitors_7day.csv")

Variations

Deduplicated Export (One Row Per Person)

Add distinct=hem to get one row per unique visitor instead of one row per page view:

params={
    "source": "pixel",
    "pixel_id": PIXEL_ID,
    "start_ms": start_ms,
    "end_ms": end_ms,
    "limit": 100,
    "offset": offset,
    "filter": "resolved:eq:true",
    "distinct": "hem",
    "has_valuable_data": "true",
    "select": ",".join(FIELDS),
}

Deduplicated by Company

One row per unique company:

"distinct": "company_domain",
"has_valuable_data": "true",

Sort Order

Use orderby to control row order:

orderby=timestamp:desc    # Newest first
orderby=timestamp:asc     # Oldest first

Notes

  • The select parameter only returns fields that have values. If a field is null for a row, it's omitted from the response. Your CSV writer should handle missing keys gracefully (the extrasaction="ignore" and DictWriter handle this).
  • offset pagination with no overlap is confirmed. Each page returns distinct rows.
  • To enrich exported visitors with your own data provider, add hem to select. It is the hashed email the visit resolved to, which is not always the person's primary email. See Include the Hashed Email for Enrichment.
  • For very large exports (10,000+ rows per day), consider adding a short delay between requests to avoid rate limits.
  • The has_valuable_data parameter filters to rows with a populated profile. It keeps a row only when all four of these hold: an email of some kind (business, personal, or flagged as business); an email address or a company name; a first name or a company name; and a last name. A row carrying only a business address does not qualify.

Next Steps


Did this page help you?