Build the import payload as a JSON:API request body with type: profile-bulk-import-job and a profiles array (or relationships to a pre-uploaded CSV via Imports endpoint)
POST to /api/profile-bulk-import-jobs/ with the profiles data embedded or a list_id to subscribe the imported profiles; include custom properties in the properties object per profile
Note the job id from the 202 response and poll GET /api/profile-bulk-import-jobs/{id} checking the attributes.status field for completed or failed
On completion, GET /api/profile-bulk-import-jobs/{id}/import-errors to retrieve per-record validation failures (invalid email, missing required fields) with row-level detail
Re-submit a corrected batch for failed rows; do not re-submit the full original file or you will create duplicate profiles for rows that succeeded
Known gotchas
Klaviyo deduplicates profiles by email address — if a profile with the same email already exists, the import merges properties rather than creating a new profile; this can silently overwrite existing custom properties with null if the import omits them
The bulk import job has a maximum profile count per job; split very large lists and fan-out multiple jobs rather than submitting one massive payload
List subscription via list_id during import bypasses Klaviyo's double-opt-in flow; ensure GDPR/CCPA consent was obtained before importing profiles with list association
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp