More
Score audience fit
Match an audience persona to advertisers and inspect the score, audience characteristics, and supporting evidence.
Use audience matching to assess how well a supplied persona fits the advertisers in your catalog. Each match includes a fit score from 0 to 1, reasons, and the audience characteristics behind the match.
For campaign planning, you can prepare a catalog containing your brand, submit each candidate persona separately, and collect the returned scores to help prioritize audiences. For sponsorship selection, submit a persona against a catalog of advertisers to find relevant brands.
Before you start
You need an Upriver API key with access and quota for catalog intake and matching.
Use the same API user for catalog setup and matching: catalogs belong to the user
who creates them. The examples use curl and jq.
Set UPRIVER_API_KEY in your environment. If you already have a prepared catalog,
set CATALOG_ID to its ID and skip to Match a persona.
Prepare your advertiser catalog
1. Create a catalog
A catalog is the set of advertisers you want to match against. Save the returned
catalog_id for subsequent requests.
export CATALOG_ID="$(curl --fail-with-body --silent --show-error \ --request POST 'https://api.upriver.ai/v1/catalogs' \ --header "X-API-Key: $UPRIVER_API_KEY" \ --header 'Content-Type: application/json' \ --data '{"name":"Campaign audience research"}' | jq -er '.catalog_id')"2. Add advertisers
Choose a stable ref for each advertiser. The match response uses this identifier
to connect results back to your own records. You can submit up to 200 entries per
request; inspect each entry’s status in the response before continuing.
curl --fail-with-body --silent --show-error \ --request POST "https://api.upriver.ai/v1/catalogs/$CATALOG_ID/entries" \ --header "X-API-Key: $UPRIVER_API_KEY" \ --header 'Content-Type: application/json' \ --data '{"entries":[{"ref":"running-brand","brand":{"url":"https://www.nike.com"}}]}'3. Research the entries
Hydration researches the advertisers and prepares the characteristics used for matching. Adding an entry alone does not mean it is ready to match.
curl --fail-with-body --silent --show-error \ --request POST "https://api.upriver.ai/v1/catalogs/$CATALOG_ID/hydrate" \ --header "X-API-Key: $UPRIVER_API_KEY" \ --header 'Content-Type: application/json' \ --data '{"refs":["running-brand"]}'A 202 response means the request was accepted. Check selected and skipped;
mode indicates whether processing started immediately (inline) or was queued
(queued). Check progress periodically:
curl --fail-with-body --silent --show-error \ "https://api.upriver.ai/v1/catalogs/$CATALOG_ID/hydrate" \ --header "X-API-Key: $UPRIVER_API_KEY"Wait for succeeded before expecting the prepared entry to participate fully.
pending and running mean work is unfinished; partial means only some research
is available. For failed or stale, retry hydration for the affected ref.
To retry a partial entry, include its ref and "force": true in the hydration
request. Avoid repeatedly restarting entries that are still running.
Match a persona
Send a description of the audience’s stated needs, interests, and situation. Include relevant constraints and objections. Use information you actually have; do not invent individual preferences from a broad segment label.
curl --fail-with-body --silent --show-error \ --request POST "https://api.upriver.ai/v1/catalogs/$CATALOG_ID/match" \ --header "X-API-Key: $UPRIVER_API_KEY" \ --header 'Content-Type: application/json' \ --data '{ "persona": { "summary": "Recreational runners training for their first half marathon who want comfortable shoes for longer runs." }, "settings": {"limit": 10} }'Provide exactly one of persona.summary (free text), persona.profile
(structured fields), or persona.facets (characteristics you have already typed).
See the Match Persona reference for all request fields,
settings, and the complete response schema.
Read the score and audience breakdown
A facet is a short statement about a persona or an advertiser’s audience, such as a need, interest, or situation. The response separates the supplied persona’s interpretation from the matches it supports.
| Field | How to use it |
|---|---|
interpretation.facets |
Inspect the needs, interests, situations, identities, triggers, barriers, or intent read from your persona. Each has text and confidence. |
matches[].ref |
Join the result to your catalog entry. |
matches[].score |
Read fit from 0 to 1 under strategy_version; higher means stronger assessed fit. |
matches[].reasons |
Explain why the advertiser fits. |
matches[].matched_offer |
When present, inspect the selected product or service, its evidence, and relevance score. |
matches[].contributions |
Inspect the related persona and product facets and supporting evidence. When an offer is selected, these explain how it was found; they do not add up to its relevance score. |
settings_applied and strategy_version |
Keep these with your scores so you can identify changes in scoring conditions. |
completeness and relevance_status |
Check whether results are complete and whether relevance assessment ran or used a fallback. |
This illustrative excerpt shows the fields to use for a score column and its explanation. Values are examples, not measured results; other response fields are omitted.
{ "interpretation": { "facets": [ {"kind":"need","text":"Comfortable shoes for longer runs","confidence":0.9}, {"kind":"situation","text":"Training for a first half marathon","confidence":0.9} ] }, "matches": [ { "ref":"running-brand", "score":0.82, "reasons":["Offers running shoes relevant to the stated training needs."] } ]}Compare candidate audiences
Submit each persona against the same prepared catalog with the same settings. Store its description, advertiser ref, score, reasons, strategy, and response status together. In a spreadsheet or a workflow such as Clay, these can become columns you use to review and prioritize candidate segments. This requires your own integration; it is not a built-in Clay audience-list scoring operation.
Check status before comparing results. completeness can be complete, truncated,
or unavailable. A fallback or a different strategy_version can change what a
score means, so do not silently mix these results into one ranking.
The endpoint returns qualifying matches rather than a score for every catalog
entry. A missing advertiser or empty matches array is not a zero score:
check research readiness, response status, exclusions, and score thresholds.
Validate any filtering threshold on examples representative of your use case.
Get facets without running a match
To inspect an advertiser’s stored characteristics and evidence, request:
curl --fail-with-body --silent --show-error \ "https://api.upriver.ai/v1/catalogs/$CATALOG_ID/entries/running-brand/facets" \ --header "X-API-Key: $UPRIVER_API_KEY"This returns facets with kind, text, confidence, evidence_grade,
sensitive, brand/product scope, and supporting evidence. It reads existing
research; it does not create new research or score a persona. The default limit
is 200, with a maximum of 500. Check truncated to see whether more facets exist
than the response contains.
POST /v1/audience_dimensions serves a different starting point: a brand URL
becomes researched audience facts categorized as behaviors, motivations,
lifestyles, concerns, or interests. Matching facets can draw on that research,
but also on brand, product, and persona research. Use
Personas when you need to discover audience
personas before assessing their fit. There is no separate endpoint that only
interprets a supplied persona; its facets come back in the match response.
Limits and troubleshooting
Matching is limited to 60 requests per 60-second window per API user, in addition to account quota. The default result limit is 10; you can request 1–50 advertisers.
| Result | What to check |
|---|---|
200 with no matches |
Check hydration status, completeness, and relevance_status, then the persona, exclusions, and thresholds. Do not record an absent match as zero. |
400 |
Check the validation message and request identifiers. |
401 / 403 |
Check the API key and account access. |
404 |
Check the catalog ID and use credentials for its owning API user. |
422 |
Supply exactly one persona format and valid field values. Simplify an uninterpretable persona description. |
429 |
Back off before retrying and check account limits. |
500 / 503 / 504 |
Retry with backoff; contact support if failures persist. |
For example, an unknown or inaccessible catalog returns 404 with:
{"detail":"Catalog not found."}