Enrichment

Start an async file-based identity resolution job

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 valid tier 01 ID previously issued to this organization by a real match or a licensed audience delivery can go directly to refresh. A prior real match qualifies when its level is included in this file's match_level filter (all five levels by default); a settled record license also qualifies. Include I for direct ID lookup because the engine classifies that path as I. Delivered direct-Refresh rows report the latest real level within that filter, or null if none exists, rather than the engine's fixed ID-lookup label I. Derived tier 02–05 IDs cannot authorize direct Refresh; derived IDs are continuity labels for unmatched rows, not resolved identities; submit the row's identity signals again if you want to attempt resolution. 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. Column mapping covers only top-level columns: the keys inside each addresses entry are read by exact name and are never AI-mapped. Use address_1, address_2, city, state, and zip (zip5, postal_code, and zip_code are accepted as ZIP aliases). Any other key, such as street or postal, is ignored. This is the same shape as the MatchAddress schema used by POST /v1/match. 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. File workflows for one organization may run concurrently. At delivery, license coverage is checked per distinct identity against confirmed canonical history. A simultaneous purchase of the same identity can be charged by both workflows before either confirmation is visible.

Workflow (hitl unset/false — default, upload resolves automatically):

  1. POST /v1/match/file — receive a segment_id and a 30-minute presigned upload_url. Pass file_format to specify your file type (default csv). When create_audience: true (default), also receives an audience_id.

  2. Upload your file — PUT to upload_url with the underlying format's Content-Type. For gzip, send raw gzip bytes and do not set Content-Encoding. No Authorization header is needed.

  3. (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.

  4. 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 failed and error_message describes 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-hashed email_sha256/phone_sha256 are also supported — see below.

  5. Poll GET /v1/match/file/{match_id} until matching_status: completed (or use a segment.ready webhook).

  6. POST /v1/match/{match_id}/deliveries — export the already resolved result. Poll GET /v1/match/{match_id}/deliveries for 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's segment_id/match_id are the only ids you need to track end to end. (The audience-scoped POST /v1/audiences/{audience_id}/deliveries also 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):

  1. POST /v1/match/file {"hitl": true} — receive a segment_id and upload_url.

  2. Upload your file — lands at a staging location, NOT the path that triggers automatic resolution.

  3. POST /v1/match/{segment_id}/analyze — reads the staged file; safe to call any time after upload, since nothing has started yet.

  4. POST /v1/segments/{segment_id}/mappings to confirm (moves the file into place and starts resolution) or POST /v1/segments/{segment_id}/mappings/cancel to abort (nothing ever ran).

  5. Poll GET /v1/match/file/{match_id} until matching_status: completed, then POST /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 client that may retry.

When create_audience is true, an unknown campaign_id returns 400 INVALID_CAMPAIGN_ID and nothing is created. Requires 'creator' scope.

post/v1/match/file

Request

  • Base URL: https://api.infiniteaudience.ai
  • URL: https://api.infiniteaudience.ai/v1/match/file
  • Auth: HTTP bearer

Headers

Idempotency-Keystring

Optional. Makes a retried create call safe to repeat — see the endpoint description's Retries section.

X-Integration-Execution-Keystring

OAuth partnerships only. A provider-stable execution key that creates or replays a private partnership run. Use the returned integration_run_id for status and delivery requests.

Request body

namestring

Optional label for this match job. Defaults to "File Match — {ISO date}" if omitted.

file_format'csv' | 'avro' | 'json' | 'jsonl'

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).

compression'none' | 'gzip'

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.

create_audienceboolean

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.

campaign_idstring

Campaign this file match is built for. Recorded as the matched segment's origin_campaign_id and, with create_audience, links the wrapper audience to it (an audience belongs to at most one campaign). Optional — when omitted, a delegated chat/A2A session's campaign is used, otherwise there is no campaign. An unknown id returns 400 INVALID_CAMPAIGN_ID and nothing is created.

webhook_urlstring uri

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.

hitlboolean

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).

match_levelstring[]

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 affects which rows match and at what level; populated enrichment fields are returned for all accepted levels.

spatial_mode'residential' | 'work' | 'auto'

Phase 3 spatial trade-area profile. residential is the default; use work for workplace-oriented spatial matching, or auto for dynamic commercial workplace routing.

shard_countinteger

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.

Response

File match job created — upload your file to the returned upload_url to proceed.

match_idstring required

Backward-compatible alias of segment_id.

segment_idstring required

Unique ID for this matched segment. Poll GET /v1/segments/{segment_id} until status is active.

audience_idstring

ID of the auto-created audience wrapper. Present when create_audience is true. Use for deliveries once the segment is active.

integration_run_idstring

Present when X-Integration-Execution-Key created a private OAuth partnership run.

namestring required

Label assigned to the job (supplied or auto-generated).

status'pending' required

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.

upload_urlstring

30-minute signed upload 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.

upload_urlsstring[]

30-minute signed upload 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.

upload_expires_atstring date-time required

ISO timestamp when upload_url/upload_urls expires (30 minutes from creation).

expires_atstring required

ISO date — 90-day hard expiry for this segment. After this date the segment and associated files are permanently deleted.

file_format'csv' | 'avro' | 'json' | 'jsonl' required

Confirmed file format for this job.

compression'none' | 'gzip' required

Confirmed input artifact compression.

Changes

No recorded changes to this operation across all 1 revision of this API.