Start an async file-based identity resolution job
const url = 'https://dev-api.infiniteaudience.ai/v1/match/file';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://dev-api.infiniteaudience.ai/v1/match/file \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{}'Creates a matched segment by uploading a customer list for identity resolution. Equivalent to POST /v1/segments with subtype: matched.
Upload csv, newline-delimited json/jsonl, or Avro records to the Infinite Audience identity graph and receive an enriched file back. Each format may be raw or gzip. Useful for CRM onboarding, suppression list resolution, contact data hygiene, and data co-op workflows.
File structure: there is no fixed column schema — column names are inferred via AI (POST /v1/match/{segment_id}/analyze reports the mapping, a confidence score per column, and any warnings). For the best match quality, name your columns (or use names that closely resemble) the standard identity attributes: email, phone, full_name (or separately, first_name, middle_name, last_name, name_suffix), address_1, address_2, city, state, zip, dob, iag_person_id (a re-upload of an id previously returned by this platform — format CLIENTCODE_TIER_HASH — resolved server-side before matching). Only map a column to full_name when the file has a single combined-name column — if separate first/last name columns exist, map those instead. A column that can’t be confidently mapped is excluded from identity resolution — if a critical attribute (email, phone, last_name) ends up unmapped, match accuracy drops or the segment may fail to resolve at all.
Pre-hashed identity columns: for clients whose own systems never expose raw email/phone values, map a column to email_sha256 or phone_sha256 (lowercase-hex SHA-256 digests) instead of the raw email/phone target — the platform passes these through without re-hashing. Do not map an already-hashed column to the raw email/phone target (it would be hashed a second time and never match), and do not map a raw email/phone column to email_sha256/phone_sha256 just because of its name — the mapper trusts sample-value shape over column name. avro/json/ jsonl uploads (which support array columns) may also supply emails, phones, addresses, emails_sha256, and phones_sha256 as extra match permutations beyond the primary identity fields. If your upload includes row_id, every value must be unique across all shards. When it is absent, the platform assigns stable row_0, row_1, … values. Duplicate ids or collisions with generated values fail the match before its result can be delivered.
Billing: Upload, analysis, and matching completion emit no billable usage. The first successful POST /v1/audiences/{id}/deliveries or POST /v1/match/{id}/deliveries involving the current run emits its one aggregate platform_match usage set together with audience, destination, and enrichment usage. Retries, duplicates, and later deliveries do not emit that file-match usage again.
Workflow (hitl unset/false — default, upload resolves automatically):
-
POST /v1/match/file — receive a
segment_idand a 30-minute presignedupload_url. Passfile_formatto specify your file type (defaultcsv). Whencreate_audience: true(default), also receives anaudience_id. -
Upload your file —
PUTtoupload_urlwith the underlying format’s Content-Type. For gzip, send raw gzip bytes and do not set Content-Encoding. NoAuthorizationheader is needed. -
(Optional)
POST /v1/match/{segment_id}/analyze— preview column mapping. Note that by the time this can return real data, the upload has already triggered automatic resolution — this step does not pause anything. -
Automatic column analysis — the platform always runs column analysis as part of the match workflow. If no usable identity attributes can be resolved, the segment transitions to
failedanderror_messagedescribes the issue.Standard column names for best results:
email,phone,full_name,first_name,middle_name,last_name,name_suffix,address_1,address_2,city,state,zip,dob,iag_person_id. Pre-hashedemail_sha256/phone_sha256are also supported — see below. -
Poll
GET /v1/match/{match_id}untilmatching_status: completed(or use asegment.readywebhook). -
POST /v1/match/{match_id}/deliveries— export the already resolved result. PollGET /v1/match/{match_id}/deliveriesfor status; it takes the match id directly and needs no audience id — if you only want matching/enrichment and don’t need audience-building concepts, this and step 1’ssegment_id/match_idare the only ids you need to track end to end. (The audience-scopedPOST /v1/audiences/{audience_id}/deliveriesalso works and is what this endpoint forwards to internally, but requires the audience id from step 1.)
Workflow (hitl: true — requires an explicit confirm before resolution runs):
-
POST /v1/match/file
{"hitl": true}— receive asegment_idandupload_url. -
Upload your file — lands at a staging location, NOT the path that triggers automatic resolution.
-
POST /v1/match/{segment_id}/analyze— reads the staged file; safe to call any time after upload, since nothing has started yet. -
POST /v1/segments/{segment_id}/mappingsto confirm (moves the file into place and starts resolution) orPOST /v1/segments/{segment_id}/mappings/cancelto abort (nothing ever ran). -
Poll
GET /v1/match/{match_id}untilmatching_status: completed, thenPOST /v1/match/{match_id}/deliveries— same match-namespaced export and polling as the default flow above (see step 6 there).
Sharded uploads: set shard_count > 1 for same-format files. The response returns index-ordered upload_urls; upload every declared shard. Every CSV shard must include the same header row, and all shards must share schema and compression. Analysis samples shard 0; a later mismatch fails the job explicitly.
Retries: pass an Idempotency-Key header to make a retried create call safe to repeat: the same key with an identical body returns the original segment/audience (and freshly re-signed upload URL(s), if the originals already expired) instead of creating a duplicate. Unlike POST /v1/match, this endpoint isn’t billed at creation, so a duplicate without this header is an orphan Library entry, not a double charge — recommended for any integration that may retry.
Requires ‘purchase’ scope.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Header Parameters
Section titled “Header Parameters”Optional. Makes a retried create call safe to repeat — see the endpoint description’s Retries section.
Request Body
Section titled “Request Body”All attributes are optional. You may omit the request body entirely or send {} — both are equivalent and will create a CSV match job with an auto-generated name.
object
Optional label for this match job. Defaults to "File Match — {ISO date}" if omitted.
Input file format. csv (default) treats every column as a single scalar value — multi-value/array attributes (email, phone, address_1, etc.) are not supported in csv. avro supports native array columns — use it when your file already encodes multi-value attributes as proper arrays. json and jsonl also support native array columns and are parsed identically — newline-delimited JSON, one record object per line (not a single top-level JSON array).
Gzip means the complete underlying file is a gzip stream. Upload raw gzip bytes with the underlying format’s Content-Type and no Content-Encoding. gzip is not supported with file_format=avro (avro is already internally compressed) — rejected with 400 UNSUPPORTED_INPUT_COMPRESSION.
When true (default), automatically creates a thin audience wrapper referencing the new matched segment. The audience_id is returned in the response and can be used for delivery immediately once the segment is active.
Optional. If provided and create_audience is true, the created audience is automatically linked to this campaign on creation. Omit if you are not using campaign workspaces.
Optional HTTPS URL to receive segment.ready or segment.failed events when the identity matching job completes. Overrides the org-level webhook URL for this request only.
Requires an explicit confirmation step before identity resolution runs — see the two workflow sequences above. Defaults to false (upload alone resolves automatically, the existing behavior).
Filter which match levels are accepted for this job. I = individual, H = household, D = digital (email/phone only match), S = spatial (nearby-address proximity match), A = address-level. Defaults to all 5 levels (['I', 'H', 'D', 'S', 'A']) if omitted. This only affects which rows match and at what level — field selection (field_list/template_id) happens separately, per delivery (POST /v1/audiences/{id}/deliveries or POST /v1/match/{id}/deliveries), where individual-level attributes are nulled out per row for rows that didn’t match at a level that qualifies for individual-level data.
Set > 1 for same-format shards. Every CSV shard must include the same header row, and all shards must share schema and compression. Returns upload_urls instead of upload_url.
Examples
Minimal request — omit the body entirely or send `{}` (CSV, auto-named)
{}Named match job — CSV
{ "name": "Q2 2026 CRM Refresh"}Match job linked to a campaign
{ "name": "Q2 2026 CRM Refresh", "campaign_id": "camp_abc123"}Responses
Section titled “Responses”File match job created — upload your file to the returned upload_url to proceed.
object
Backward-compatible alias of segment_id.
Unique ID for this matched segment. Poll GET /v1/segments/{segment_id} until status is active.
ID of the auto-created audience wrapper. Present when create_audience is true. Use for deliveries once the segment is active.
Label assigned to the job (supplied or auto-generated).
Always pending on creation — the segment is awaiting file upload. Poll GET /v1/segments/{segment_id} — it will show status: pending until identity resolution completes, then status: active.
30-minute presigned GCS PUT URL. Upload your file to this URL with the Content-Type matching your file_format. No Authorization header required. Present when shard_count is 1 (the default) — absent when sharded, use upload_urls instead.
30-minute presigned GCS PUT URLs, one per shard, index-ordered. Present only when shard_count > 1 was requested — upload_url is absent. Every CSV shard must include the same header row.
ISO timestamp when upload_url/upload_urls expires (30 minutes from creation).
ISO date — 90-day hard expiry for this segment. After this date the segment and associated files are permanently deleted.
Confirmed file format for this job.
Confirmed input artifact compression.
Examples
CSV job with audience (default)
{ "match_id": "seg_csv123", "segment_id": "seg_csv123", "audience_id": "aud_csv123", "name": "Q2 2026 CRM Refresh", "status": "pending", "upload_url": "https://storage.googleapis.com/cf-uploads/enrichment-uploads/org_x/seg_csv123/input.csv?X-Goog-Signature=...", "upload_expires_at": "2026-06-22T19:30:00.000Z", "expires_at": "2026-09-27", "file_format": "csv", "compression": "none"}Invalid request — malformed body, missing required attribute, or failed validation. See error and message for details.
object
Stable machine-readable error code (e.g. INVALID_STATUS_TRANSITION, BILLING_INSUFFICIENT_BALANCE). Always present.
Human-readable explanation of the error.
Alternate machine-readable code — present on some endpoints as an alias for error for backward compatibility.
Opaque support/debug identifier when available.
Examples
{ "error": "Bad Request", "code": "MISSING_SEGMENTS", "message": "segment_ids is required for filter audiences."}Missing or invalid Bearer token. Obtain one via POST /v1/auth/token. When a token was supplied but rejected, code distinguishes TOKEN_EXPIRED (the token’s lifetime has passed — request a new one via POST /v1/auth/token and retry) from TOKEN_INVALID (malformed or revoked — re-authenticate).
object
Stable machine-readable error code (e.g. INVALID_STATUS_TRANSITION, BILLING_INSUFFICIENT_BALANCE). Always present.
Human-readable explanation of the error.
Alternate machine-readable code — present on some endpoints as an alias for error for backward compatibility.
Opaque support/debug identifier when available.
Examples
{ "error": "Unauthorized: Missing or invalid Authorization header"}{ "error": "Unauthorized", "code": "TOKEN_EXPIRED", "message": "Your session has expired. Please sign in again."}Token is valid but lacks the required scope for this endpoint. Check the endpoint description for the required scope (discovery, purchase, or account).
object
Stable machine-readable error code (e.g. INVALID_STATUS_TRANSITION, BILLING_INSUFFICIENT_BALANCE). Always present.
Human-readable explanation of the error.
Alternate machine-readable code — present on some endpoints as an alias for error for backward compatibility.
Opaque support/debug identifier when available.
Examples
{ "error": "SCOPE_REQUIRED", "message": "This endpoint requires the purchase scope."}IDEMPOTENCY_KEY_CONFLICT — the Idempotency-Key header was already used with a different request body. IDEMPOTENCY_REQUEST_IN_PROGRESS — another request with this key is in flight; retry after the seconds in Retry-After.
object
Example
{ "code": "IDEMPOTENCY_KEY_CONFLICT"}