Bulk upsert users
Users
Bulk upsert users
POST /api/v1/users/bulk — backfill up to 1,000 users in one request.
POST
Bulk upsert users
The backfill counterpart to single-record upsert. Send up to 1,000 user records in one POST; per-record validation errors are surfaced in the response, the rest are queued.
SDK is the recommended path.
vf.users.identifyBulk() wraps this endpoint with strong typing and pairs cleanly with the exported chunk() helper for backfills larger than 1,000 records.Request
Body
Array of user records. Each entry has the same shape as the single-record body. Minimum 1, maximum 1,000 records.
Response
Records that passed validation and were enqueued.
Records that failed validation. Each has a corresponding entry in
data.errors.Per-record validation failures.
index correlates back to the position in the input users array — the record at that position was not enqueued.Total records in the request payload.
accepted + rejected === meta.received is an invariant — every record is accounted for.Idempotency is automatic. The
(project_id, external_user_id) uniqueness constraint on tracked_users means re-sending the same record with the same external_user_id is treated as an update, not a duplicate. Any chunk that returns 429 or 5xx is safe to retry.Examples
Common errors
401 auth_required
401 auth_required
Missing or malformed
Authorization header.400 validation_failed
400 validation_failed
The envelope failed validation —
users is missing, not an array, empty, or contains more than 1,000 records. Per-record validation failures do not trigger 400; they surface in data.errors.429 rate_limited
429 rate_limited
Standard per-project rate limit; honor
Retry-After.429 backfill_queue_full
429 backfill_queue_full
The project’s ingest queue is saturated (50,000+ jobs waiting or delayed). Back off, drain, then resume in smaller chunks.
5xx server_error
5xx server_error
Retry the same chunk — the upsert is idempotent via the unique
(project_id, external_user_id) constraint.Sizing
Max records per request
1,000
Recommended chunk size
1,000
Backfill queue cap
50,000 waiting jobs / project