Skip to content

Micro-batch synchronous match

POST
/v1/match
curl --request POST \
--url https://dev-api.infiniteaudience.ai/v1/match \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "records": [ { "email": "hello@example.com", "phone": "example", "email_sha256": "example", "phone_sha256": "example", "full_name": "example", "first_name": "example", "middle_name": "example", "last_name": "example", "name_suffix": "example", "emails": [ "hello@example.com" ], "emails_sha256": [ "example" ], "phones": [ "example" ], "phones_sha256": [ "example" ], "addresses": [ { "address_1": "example", "address_2": "example", "city": "example", "state": "example", "zip": "example" } ], "address_1": "example", "address_2": "example", "city": "example", "state": "example", "zip": "example", "dob": "example", "iag_person_id": "example" } ], "field_list": [ "example" ], "template_id": "example", "match_level": [ "I" ] }'

Synchronous inline matching for small record sets (up to 100 records). Submit your records and the list of attributes you want appended, and receive matched results immediately.

Billing: Usage is emitted per matched record only (unmatched records are free). The platform reserves a conservative ceiling and durably queues finalized usage for billing rather than debiting a local balance field. amount_charged is the conservative USD estimate accepted for provider delivery; it is not a finalized invoice amount.

Records array: one output record per input record — matched or not. Unmatched rows carry match_level/match_type/match_confidence: null and a best-effort iag_person_id derived from the row’s own identity signals (or null if none qualified) — only real matches are billed. Use match_count vs record_count to distinguish real matches from derived-only rows.

For datasets larger than 100 records, use POST /v1/match/file instead. Upload, analysis, and async matching are free until egress. The first successful delivery involving that file-match run emits its one aggregate match usage set together with normal delivery usage.

Retries: pass an Idempotency-Key header to make a retried call safe to repeat without a duplicate charge. The same key with an identical body returns the original response verbatim, at zero additional charge (honored for 24 hours); the same key with a different body is rejected with 409 IDEMPOTENCY_KEY_CONFLICT. Without this header, every call reserves and charges independently — recommended for any integration that may retry on timeout. Requires ‘purchase’ scope.

Idempotency-Key
string
>= 8 characters <= 160 characters /^[A-Za-z0-9][A-Za-z0-9._:-]{7,159}$/

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

Media typeapplication/json
object
records
required

Records to match (max 100). Each object should include at least one identity signal: email (or email_sha256), phone (or phone_sha256), full_name (or first_name+last_name), or address attributes (address_1, city, state, zip). All attributes are optional — include only what you have. Any extra attributes you include are echoed back unchanged.

Array<object>
>= 1 items <= 100 items
object
email

Primary email address.

string format: email
phone

Phone number in any standard format.

string
email_sha256

Lowercase-hex SHA-256 hash of a normalized email address, for clients whose own systems never expose raw email addresses (e.g. data co-op / clean-room partners using the same hashing convention). The platform passes this through without re-hashing. Do not submit an already-hashed value in email — it would be hashed a second time and never match.

string
phone_sha256

Lowercase-hex SHA-256 hash of a normalized phone number. Same pre-hashed semantics as email_sha256.

string
full_name

Optional convenience field. When provided (and first_name / last_name are absent), the engine parses this into first_name, middle_name, last_name, and name_suffix automatically. The parsed components are used for matching; the original full_name value is echoed back unchanged.

string
first_name
string
middle_name
string
last_name
string
name_suffix

Generational suffix (e.g. JR, SR, III).

string
emails

Additional raw email addresses beyond email, tried as extra match permutations.

Array<string>
emails_sha256

Pre-hashed counterpart to emails.

Array<string>
phones

Additional raw phone numbers beyond phone, tried as extra match permutations.

Array<string>
phones_sha256

Pre-hashed counterpart to phones.

Array<string>
addresses

Additional addresses beyond address_1/city/state/zip, tried as extra match permutations.

Array<object>
object
address_1
string
address_2
string
city
string
state
string
zip
string
address_1

Street address line 1.

string
address_2

Street address line 2 (apt, suite, etc.).

string
city
string
state

Two-letter US state code.

string
zip

5- or 9-digit ZIP code.

string
dob

Date of birth — any parseable date format (e.g. YYYY-MM-DD).

string
iag_person_id

A previously-issued platform id (format CLIENTCODE_TIER_HASH, e.g. returned by a prior call to this endpoint or a matched-segment delivery). Resolved server-side before matching. An id that doesn’t resolve (foreign, expired, or a derived/unmatched-tier id) is dropped and the row matches on its other identity signals, if any.

string
key
additional properties
any
field_list

Enrichment attribute names to append on match — every attribute must be a valid audience attribute (see GET /v1/catalog/fields). Mutually exclusive with template_id. If neither is provided, the Standard IAG attribute set (all attributes with product_usage containing audience) is used. Individual-level attributes (e.g. age, gender) come back null per row when that row’s match_level doesn’t qualify for individual-level data (see match_level below) — this is expected, not an error. Request only the attributes valid for the match_level(s) you accept if you want to avoid nulls.

Array<string>
template_id

Pre-built enrichment bundle ID. Only standard_iag is valid (see templates[] in GET /v1/catalog/fields). Mutually exclusive with field_list. If neither is provided, the Standard IAG attribute set is used.

string
match_level

Filter results to specific match levels. 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. Restricting this also restricts which attributes come back populated — see field_list above.

Array<string>
Allowed values: I H D S A

Matched records.

Media typeapplication/json
object
records

One output record per input record — matched or not. Matched rows carry a resolved iag_person_id, match_level/match_type/match_confidence, and (when requested) enrichment attributes. Unmatched rows carry match_level/match_type/match_confidence: null and a best-effort derived iag_person_id (see iag_person_id below) computed from the row’s own identity signals, or null if none qualified. Use match_count vs record_count to distinguish real matches from derived-only rows — only real matches are billed. Input attributes are echoed back unchanged; resolved enrichment attributes are added alongside them.

Array<object>
object
row_id

Correlates a matched output row back to its position in the submitted records array (1-indexed as a string when the input didn’t supply one).

string
email
string format: email
phone
string
email_sha256

Present when the request included email_sha256, echoed back unchanged.

string
phone_sha256

Present when the request included phone_sha256, echoed back unchanged.

string
full_name

Present when the request included full_name; the original submitted value, echoed back unchanged. Null when the request did not include one.

string | null
first_name
string
middle_name

Echoed back when present on input, or populated from full_name parsing when the request supplied full_name without first_name/last_name.

string
last_name
string
name_suffix

Generational suffix (e.g. JR, SR, III). Echoed back when present on input, or populated from full_name/last_name parsing.

string
address_1
string
address_2
string
city
string
state
string
zip
string
dob
string
emails

Additional raw emails from the request, echoed back unchanged.

Array<string>
emails_sha256

Additional pre-hashed emails from the request, echoed back unchanged.

Array<string>
phones

Additional raw phones from the request, echoed back unchanged.

Array<string>
phones_sha256

Additional pre-hashed phones from the request, echoed back unchanged.

Array<string>
addresses

Additional addresses from the request, echoed back unchanged.

Array<object>
object
key
additional properties
any
iag_person_id

Org-scoped, non-reversible identifier — never a raw internal id. Format: CLIENTCODE_TIER_HASH. TIER is 01 for a real graph match (see match_level/match_type/match_confidence) or 0205 for a best-effort id deterministically derived from the row’s own identity signals when it did NOT match (name+address, email, name+phone, or name+zip, in that priority order). null when the row is unmatched and no identity signal qualified for derivation. A tier-01 id may be resubmitted as input (see iag_person_id on the request schema above) to re-resolve the same match; derived (tier 02–05) ids cannot be.

string | null
match_level

Granularity of the match. I = individual, H = household, A = address-level, S = spatial (nearby-address proximity match), D = digital (email/phone only match). Present only on matched records (null, not a derived value, on unmatched rows).

string
Allowed values: I H A S D
match_type

Matching strategy that produced the result (e.g. graph_name_email_match, vector_name_address_match, spatial_match). Present only on matched records.

string
match_confidence

Confidence score for the match (0–1). Present only on matched records.

number
enrichment

Requested enrichment attributes keyed by column name (e.g. acs_housing_units, usda_median_hh_income_2023). Only present when field_list or template_id was provided and the record matched.

object
key
additional properties
any
key
additional properties
any
record_count

Total number of input records processed.

integer
match_count

Number of records that resolved to a known identity.

integer
match_rate

Match_count / record_count.

number
amount_charged

Conservative platform estimate in USD for usage accepted for delivery (e.g. 0.30 means $0.30 estimated). This legacy-named field is not a local credit debit or finalized invoice amount; unmatched records emit no usage.

number
run_id

Unique identifier for this match run. Pass to GET /v1/match/runs/{runId} to retrieve full details or audit this call later. Requires ‘discovery’ scope to read.

string
Example
{
"records": [
{
"match_level": "I"
}
]
}

Invalid request — malformed body, missing required attribute, or failed validation. See error and message for details.

Media typeapplication/json
object
error
required

Stable machine-readable error code (e.g. INVALID_STATUS_TRANSITION, BILLING_INSUFFICIENT_BALANCE). Always present.

string
message

Human-readable explanation of the error.

string
code

Alternate machine-readable code — present on some endpoints as an alias for error for backward compatibility.

string
request_id

Opaque support/debug identifier when available.

string
key
additional properties
any
Examples
Examplevalidation_error
{
"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).

Media typeapplication/json
object
error
required

Stable machine-readable error code (e.g. INVALID_STATUS_TRANSITION, BILLING_INSUFFICIENT_BALANCE). Always present.

string
message

Human-readable explanation of the error.

string
code

Alternate machine-readable code — present on some endpoints as an alias for error for backward compatibility.

string
request_id

Opaque support/debug identifier when available.

string
key
additional properties
any
Examples
{
"error": "Unauthorized: Missing or invalid Authorization header"
}

The request cannot proceed on billing grounds. BILLING_INSUFFICIENT_BALANCE applies only to prepay accounts and includes required, available, and shortfall in USD. BILLING_POSTPAY_CEILING_EXCEEDED applies to an account ceiling; BILLING_CONSUMER_POSTPAY_CEILING_EXCEEDED applies to an agency child’s routed ceiling. Both ceiling responses include projected accrued and configured ceiling in USD.

Media typeapplication/json
object
error
required

Stable machine-readable error code (e.g. INVALID_STATUS_TRANSITION, BILLING_INSUFFICIENT_BALANCE). Always present.

string
message

Human-readable explanation of the error.

string
code

Alternate machine-readable code — present on some endpoints as an alias for error for backward compatibility.

string
request_id

Opaque support/debug identifier when available.

string
code
string
Allowed values: BILLING_INSUFFICIENT_BALANCE BILLING_POSTPAY_CEILING_EXCEEDED BILLING_CONSUMER_POSTPAY_CEILING_EXCEEDED
shortfall
number
required
number
available
number
accrued
number
ceiling
number
Examples
{
"error": "Insufficient balance",
"code": "BILLING_INSUFFICIENT_BALANCE",
"message": "Insufficient effective balance",
"required": 1,
"available": 0.75,
"shortfall": 0.25
}

Token is valid but lacks the required scope for this endpoint. Check the endpoint description for the required scope (discovery, purchase, or account).

Media typeapplication/json
object
error
required

Stable machine-readable error code (e.g. INVALID_STATUS_TRANSITION, BILLING_INSUFFICIENT_BALANCE). Always present.

string
message

Human-readable explanation of the error.

string
code

Alternate machine-readable code — present on some endpoints as an alias for error for backward compatibility.

string
request_id

Opaque support/debug identifier when available.

string
key
additional properties
any
Examples
Examplemissing_scope
{
"error": "SCOPE_REQUIRED",
"message": "This endpoint requires the purchase scope."
}

BILLING_NOT_READY — the billing account/route isn’t active. 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.

Media typeapplication/json
object
error
required
string
code
required
string
Allowed values: BILLING_NOT_READY IDEMPOTENCY_KEY_CONFLICT IDEMPOTENCY_REQUEST_IN_PROGRESS
message
required
string
Example
{
"code": "BILLING_NOT_READY"
}

A required billing provider integration is temporarily unavailable.

Media typeapplication/json
object
error
required

Stable machine-readable error code (e.g. INVALID_STATUS_TRANSITION, BILLING_INSUFFICIENT_BALANCE). Always present.

string
message

Human-readable explanation of the error.

string
code

Alternate machine-readable code — present on some endpoints as an alias for error for backward compatibility.

string
request_id

Opaque support/debug identifier when available.

string
key
additional properties
any
Examplegenerated
{
"error": "example",
"message": "example",
"code": "example",
"request_id": "example"
}