Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: Upriver Audience API
description: A social insights API for ad generation platforms. It provides structured signals, like psychographics, behavioral insights, trends, and audience language, to help AI models generate relevant, higher-converting ads.
version: 1.0.0
servers:
- url: https://api.upriver.ai
description: Production API server
tags:
- name: Audience
paths:
/v3/audience_insights:
post:
tags:
- Audience
summary: Personas (v3)
description: 'Get detailed audience personas for a brand.
**Input:** Brand URL, optional query and effort level.
**Output:** Personas with purchase triggers, barriers, behaviors, language patterns, and optional real world citations.'
operationId: audience_insights_v3
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GroundedInsightsInput'
required: true
responses:
'200':
description: Audience personas
content:
application/json:
schema:
$ref: '#/components/schemas/AudienceInsightsResponseV3'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
security:
- APIKeyHeader: []
x-mint:
metadata:
tag: BETA
x-agent-description: Generate a list of audience personas for a brand, grounded in real online conversations. Provide brand_url. Each persona includes purchase triggers, barriers, behaviors, language patterns, and real-world citations. include_citations defaults to true (set false to omit); query is an optional focus hint; set effort=high for broader, deeper research (default auto). Generation can take roughly 15-25s.
x-agent-params:
- brand_url
- query
- include_citations
- effort
/v1/catalogs/{catalog_id}/match:
post:
tags:
- Audience
summary: Match Persona
description: 'Interpret a persona and rank this catalog''s entries for fit.
Returns fit scores from 0 to 1, the persona''s interpreted characteristics,
and supporting evidence for each qualifying advertiser. Scores measure
relevance, not purchase probability or verified buying intent. An absent
match is not a zero score.
See Score audience fit for
catalog setup, a complete request example, and guidance on comparing
candidate audiences.'
operationId: match_catalog
security:
- APIKeyHeader: []
parameters:
- name: catalog_id
in: path
required: true
schema:
type: string
format: uuid
title: Catalog Id
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/MatchInput'
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/MatchOutput'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
x-mint:
metadata:
tag: BETA
components:
schemas:
FacetKind:
type: string
enum:
- identity
- need
- trigger
- barrier
- interest
- situation
- intent
title: FacetKind
Completeness:
type: string
enum:
- complete
- truncated
- unavailable
title: Completeness
InterpretationMode:
type: string
enum:
- summary
- profile
- facets
title: InterpretationMode
Preset:
type: string
enum:
- balanced
- performance
- awareness
title: Preset
MatchOutput:
properties:
interpretation:
$ref: '#/components/schemas/MatchInterpretation'
matches:
items:
$ref: '#/components/schemas/CatalogMatch'
type: array
title: Matches
description: Ranked catalog entries that fit the persona.
settings_applied:
$ref: '#/components/schemas/MatchSettings'
description: The settings this match was computed under.
strategy_version:
type: string
title: Strategy Version
description: Version of the scoring strategy that produced this match.
completeness:
$ref: '#/components/schemas/Completeness'
description: Whether this response is complete.
brief_fingerprint:
type: string
title: Brief Fingerprint
description: Stable identifier for this persona-and-settings pairing.
relevance_status:
type: string
enum:
- disabled
- applied
- fallback
- skipped_sensitive
- skipped_settings
- no_candidates
title: Relevance Status
description: 'Full-context relevance assessment: applied, disabled, no_candidates, fallback after unavailability, skipped_sensitive to honor exclusions, or skipped_settings to preserve custom scoring preferences.'
default: disabled
judge_applied:
type: boolean
title: Judge Applied
description: 'Whether a borderline-match verification pass, selected server-side, was in effect for this response: either it ran and its answers were applied, or there was nothing borderline enough to need verifying. A match still returns normally, with this false, when no verification pass is configured, it only measures without changing results, or the selected backend is unavailable.'
default: false
additionalProperties: false
type: object
required:
- interpretation
- matches
- settings_applied
- strategy_version
- completeness
- brief_fingerprint
title: MatchOutput
description: Ranked catalog entries for one persona, with an explained score each.
PersonaFacetSummary:
properties:
kind:
$ref: '#/components/schemas/FacetKind'
description: What kind of statement this facet is.
text:
type: string
title: Text
description: The facet's text.
confidence:
type: number
maximum: 1.0
minimum: 0.0
title: Confidence
description: Confidence in this facet, from 0 to 1.
sensitive:
type: boolean
title: Sensitive
description: Whether this facet touches a sensitive topic.
source_span:
anyOf:
- type: string
maxLength: 300
- type: 'null'
title: Source Span
description: The phrase in the persona this facet came from, when known.
parent_index:
anyOf:
- type: integer
minimum: 0.0
- type: 'null'
title: Parent Index
description: Index of the stated facet this facet was inferred from, if any.
additionalProperties: false
type: object
required:
- kind
- text
- confidence
- sensitive
title: PersonaFacetSummary
description: One typed statement interpreted from a supplied persona.
MatchSettings:
properties:
preset:
$ref: '#/components/schemas/Preset'
description: 'Named weighting: balanced, performance (stated needs first) or awareness (interests and situations count more).'
default: balanced
priorities:
additionalProperties:
type: number
propertyNames:
$ref: '#/components/schemas/FacetKind'
type: object
title: Priorities
description: Optional multipliers from 0 to 2 per characteristic kind, applied on top of the preset.
exclusions:
$ref: '#/components/schemas/Exclusions'
description: What to leave out of the results.
inferred_needs:
$ref: '#/components/schemas/InferredNeeds'
description: 'Whether needs implied by stated interests and situations may contribute: off, capped (a bounded share of each score) or on.'
default: 'off'
min_evidence:
type: number
maximum: 1.0
minimum: 0.0
title: Min Evidence
description: Minimum score for an advertiser to be returned at all. A price-tier mismatch (see price_tier_affinity) can by itself lower a score below this threshold.
default: 0.35
price_tier_affinity:
type: boolean
title: Price Tier Affinity
description: 'Whether an entry''s price tier and the persona''s price sensitivity, when both are known, adjust that entry''s score: a small boost when they agree, a small penalty at the two extremes. Set false to leave scores unaffected by price tier.'
default: true
geo:
anyOf:
- type: string
maxLength: 2
minLength: 2
pattern: ^[A-Za-z]{2}$
- type: 'null'
title: Geo
description: Optional country filter, as a two-letter ISO 3166-1 country code.
language:
anyOf:
- type: string
maxLength: 16
- type: 'null'
title: Language
description: Optional language code filter.
limit:
type: integer
maximum: 50.0
minimum: 1.0
title: Limit
description: Maximum number of advertisers returned.
default: 10
additionalProperties: false
type: object
title: MatchSettings
description: Caller-controlled settings. Presets plus bounded multipliers, not free weights.
PersonaCitationV3:
properties:
title:
type: string
title: Title
description: Title
text:
type: string
title: Text
description: Relevant excerpt from the citation
url:
anyOf:
- type: string
- type: 'null'
title: Url
description: URL of the source if available
subreddit:
anyOf:
- type: string
- type: 'null'
title: Subreddit
description: Subreddit if from Reddit
type: object
required:
- title
- text
title: PersonaCitationV3
MatchInput:
properties:
persona:
$ref: '#/components/schemas/PersonaInputModel'
description: The persona to match against this catalog.
settings:
$ref: '#/components/schemas/MatchSettings'
description: Caller-controlled matching settings.
additionalProperties: false
type: object
required:
- persona
title: MatchInput
description: Request to match a persona against one catalog's entries.
Contribution:
properties:
edge:
$ref: '#/components/schemas/EdgeType'
description: The kind of relationship this edge represents.
user_facet:
$ref: '#/components/schemas/PersonaFacetSummary'
description: The persona facet on this edge.
product_facet:
$ref: '#/components/schemas/ProductFacetSummary'
description: The product facet on this edge.
similarity:
type: number
title: Similarity
description: Raw similarity between the two facets.
weight:
type: number
title: Weight
description: Weight applied to this edge under the caller's settings.
delta:
type: number
title: Delta
description: This edge's signed contribution to the raw score.
evidence:
items:
$ref: '#/components/schemas/EvidenceItem'
type: array
title: Evidence
description: Supporting evidence behind the product facet.
additionalProperties: false
type: object
required:
- edge
- user_facet
- product_facet
- similarity
- weight
- delta
title: Contribution
description: One persona-facet-to-product-facet edge that contributed to a score.
ResponseMetaV3:
properties:
generated_at:
type: string
title: Generated At
type: object
title: ResponseMetaV3
MatchedOffer:
properties:
name:
type: string
title: Name
description: Name of the selected product or service.
url:
anyOf:
- type: string
- type: 'null'
title: Url
description: Selected offer page, when known.
description:
type: string
title: Description
description: Available description of the selected offer.
evidence:
items:
$ref: '#/components/schemas/EvidenceItem'
type: array
title: Evidence
description: Source excerpts supporting this offer.
relevance_score:
type: number
maximum: 1.0
minimum: 0.0
title: Relevance Score
description: Assessed relevance from 0 to 1; not a purchase probability.
additionalProperties: false
type: object
required:
- name
- description
- relevance_score
title: MatchedOffer
description: Specific product or service supporting the advertiser recommendation.
EdgeType:
type: string
enum:
- direct
- affinity
- inferred
- barrier
title: EdgeType
HTTPValidationError:
properties:
detail:
items:
$ref: '#/components/schemas/ValidationError'
type: array
title: Detail
type: object
title: HTTPValidationError
PersonaFacetInput:
properties:
kind:
$ref: '#/components/schemas/FacetKind'
description: What kind of statement this facet is.
text:
type: string
maxLength: 300
minLength: 2
title: Text
description: The facet's text.
confidence:
type: number
maximum: 1.0
minimum: 0.0
title: Confidence
description: Confidence in this facet, from 0 to 1.
sensitive:
type: boolean
title: Sensitive
description: Whether this facet touches a sensitive topic.
default: false
source_span:
anyOf:
- type: string
maxLength: 300
- type: 'null'
title: Source Span
description: The phrase in the persona this facet came from, when known.
parent_index:
anyOf:
- type: integer
minimum: 0.0
- type: 'null'
title: Parent Index
description: Index of the stated facet this facet was inferred from. Must be null unless `inferred` is true.
inferred:
type: boolean
title: Inferred
description: Whether this facet was inferred by the caller rather than stated directly in the persona.
default: false
additionalProperties: false
type: object
required:
- kind
- text
- confidence
title: PersonaFacetInput
description: One caller-supplied statement describing the persona.
PersonalityTraitV3:
properties:
id:
type: string
title: Id
description: Taxonomy key, e.g. 'analytical', 'security_oriented'.
label:
type: string
title: Label
description: Human-readable label for the trait, e.g. 'Analytical', 'Stability-Seeking'.
type: object
required:
- id
- label
title: PersonalityTraitV3
CatalogMatch:
properties:
ref:
type: string
title: Ref
description: The matched entry's caller-defined identifier.
brand_url:
type: string
title: Brand Url
description: Brand website URL for the matched entry.
score:
type: number
maximum: 1.0
minimum: 0.0
title: Score
description: Fit from 0 to 1 under the reported scoring strategy.
evidence_grade:
$ref: '#/components/schemas/EvidenceGrade'
description: Strength of support behind this match.
matched_offer:
anyOf:
- $ref: '#/components/schemas/MatchedOffer'
- type: 'null'
description: Selected offer when full-context relevance was assessed.
contributions:
items:
$ref: '#/components/schemas/Contribution'
type: array
title: Contributions
description: Supporting facet relationships. With a selected offer, these explain candidate discovery rather than add up to its relevance score.
reasons:
items:
type: string
type: array
title: Reasons
description: Short, human-readable reasons for this match.
price_tier_fit:
anyOf:
- type: string
enum:
- match
- adjacent
- mismatch
- type: 'null'
title: Price Tier Fit
description: 'How this entry''s price tier compares with the persona''s price sensitivity: match, adjacent, or mismatch. Null when either the persona or the entry gives no price signal.'
additionalProperties: false
type: object
required:
- ref
- brand_url
- score
- evidence_grade
- contributions
- reasons
title: CatalogMatch
description: One catalog entry ranked for fit against a persona.
PersonaInputModel:
properties:
summary:
anyOf:
- type: string
maxLength: 8000
minLength: 1
- type: 'null'
title: Summary
description: Free-text persona description.
profile:
anyOf:
- $ref: '#/components/schemas/PersonaProfileInput'
- type: 'null'
description: Structured persona fields.
facets:
anyOf:
- items:
$ref: '#/components/schemas/PersonaFacetInput'
type: array
maxItems: 80
- type: 'null'
title: Facets
description: Caller-typed persona facets.
additionalProperties: false
type: object
title: PersonaInputModel
description: 'Persona to match against a catalog: exactly one of summary, profile or facets.'
example:
summary: Tech founders interested in developer tools and automation
Exclusions:
properties:
categories:
items:
type: string
type: array
maxItems: 50
title: Categories
description: Product categories to leave out of the results.
brands:
items:
type: string
type: array
maxItems: 200
title: Brands
description: Brand websites, as domains, to leave out of the results.
sensitive:
type: boolean
title: Sensitive
description: When true, statements about sensitive topics never contribute to a score.
default: true
additionalProperties: false
type: object
title: Exclusions
ValidationError:
properties:
loc:
items:
anyOf:
- type: string
- type: integer
type: array
title: Location
msg:
type: string
title: Message
type:
type: string
title: Error Type
type: object
required:
- loc
- msg
- type
title: ValidationError
InferredNeeds:
type: string
enum:
- 'off'
- capped
- 'on'
title: InferredNeeds
AudienceInsightsResponseV3:
properties:
rollup_summary:
anyOf:
- type: string
- type: 'null'
title: Rollup Summary
description: One-paragraph cross-persona summary (1-2 sentences).
personas:
items:
$ref: '#/components/schemas/PersonaV3'
type: array
title: Personas
description: Up to 8 distinct, evidence-supported audience personas. The response may contain fewer when the available evidence does not support more.
meta:
$ref: '#/components/schemas/ResponseMetaV3'
description: Generation metadata.
type: object
required:
- personas
title: AudienceInsightsResponseV3
ProductFacetSummary:
properties:
kind:
$ref: '#/components/schemas/FacetKind'
description: What kind of statement this facet is.
text:
type: string
title: Text
description: The facet's text.
confidence:
type: number
maximum: 1.0
minimum: 0.0
title: Confidence
description: Confidence in this facet, from 0 to 1.
evidence_grade:
$ref: '#/components/schemas/EvidenceGrade'
description: Strength of support behind this facet.
additionalProperties: false
type: object
required:
- kind
- text
- confidence
- evidence_grade
title: ProductFacetSummary
description: A minimal view of the product facet behind one score contribution.
EvidenceItem:
properties:
source:
type: string
title: Source
description: Community, platform or document the snippet came from.
url:
anyOf:
- type: string
- type: 'null'
title: Url
description: Link to the source when known.
snippet:
type: string
maxLength: 600
minLength: 1
title: Snippet
description: Short excerpt supporting the facet.
similarity:
anyOf:
- type: number
maximum: 1.0
minimum: 0.0
- type: 'null'
title: Similarity
description: How closely the excerpt supports the facet, 0 to 1 when known.
judge_probability:
anyOf:
- type: number
maximum: 1.0
minimum: 0.0
- type: 'null'
title: Judge Probability
description: Calibrated probability that this evidence supports the facet, when a judge scored it.
additionalProperties: false
type: object
required:
- source
- snippet
title: EvidenceItem
GroundedEffort:
type: string
enum:
- auto
- low
- mid
- high
title: GroundedEffort
PersonaProfileInput:
properties:
identity:
anyOf:
- type: string
maxLength: 300
minLength: 2
- type: 'null'
title: Identity
description: A short description of who this persona is.
interests:
items:
type: string
maxLength: 300
minLength: 2
type: array
maxItems: 40
title: Interests
description: Topics or activities this persona is interested in.
situations:
items:
type: string
maxLength: 300
minLength: 2
type: array
maxItems: 40
title: Situations
description: Situations or contexts relevant to this persona.
needs:
items:
type: string
maxLength: 300
minLength: 2
type: array
maxItems: 40
title: Needs
description: Needs this persona has.
intent:
anyOf:
- type: string
maxLength: 300
minLength: 2
- type: 'null'
title: Intent
description: This persona's stated intent, when known.
additionalProperties: false
type: object
title: PersonaProfileInput
description: Structured persona fields, mapped deterministically to facets.
PersonaV3:
properties:
label:
type: string
title: Label
description: Short descriptive label for this audience segment.
description:
type: string
title: Description
description: 1-sentence summary of what was observed about this group.
personality_traits:
items:
$ref: '#/components/schemas/PersonalityTraitV3'
type: array
title: Personality Traits
description: Deprecated. Previously contained personality taxonomy traits. Now always empty — use buying_mindset for behavioral insights.
deprecated: true
buying_mindset:
items:
type: string
type: array
title: Buying Mindset
description: 1-2 short observations about how this group makes buying decisions — what influences them, how they relate to brands.
purchase_motivations:
items:
type: string
type: array
title: Purchase Motivations
description: Why this group wants the product category — enduring desired outcomes, problems solved, and identity payoffs observed in real discussions. 2-5 items; fewer is preferable when evidence is sparse.
purchase_triggers:
items:
type: string
type: array
title: Purchase Triggers
description: What pushes them toward purchase now — specific moments, comparisons, and need states observed in real discussions. 2-5 items; fewer is preferable when evidence is sparse.
purchase_barriers:
items:
type: string
type: array
title: Purchase Barriers
description: What stops them from buying — specific fears, concerns, objections, and friction points observed in real discussions. 2-5 items; fewer is preferable when evidence is sparse.
behaviors:
items:
type: string
type: array
title: Behaviors
description: Deprecated. No longer populated — always returns an empty list. For behavioral insights use buying_mindset, purchase_triggers, and phrase_examples.
deprecated: true
phrase_examples:
items:
type: string
type: array
title: Phrase Examples
description: Distinctive slang, idioms, jargon, emojis, hashtags — 1-5 words each. 2-7 items; fewer is preferable to generic filler.
voice_and_tone:
items:
type: string
type: array
title: Voice And Tone
description: Deprecated. No longer populated — always returns an empty list. Use phrase_examples for how this audience communicates.
deprecated: true
communities:
anyOf:
- items:
type: string
type: array
- type: 'null'
title: Communities
description: Online communities supported by the segment's cited discussions. Omitted when the evidence does not establish a concentrated audience habitat.
citations:
items:
$ref: '#/components/schemas/PersonaCitationV3'
type: array
title: Citations
description: Supporting citations from real discussions that validate this segment's characteristics.
type: object
required:
- label
- description
- purchase_motivations
- purchase_triggers
- purchase_barriers
- phrase_examples
title: PersonaV3
EvidenceGrade:
type: string
enum:
- grounded
- sparse
- derived
title: EvidenceGrade
GroundedInsightsInput:
properties:
brand_url:
type: string
title: Brand Url
description: Brand website to research.
examples:
- https://nike.com
query:
anyOf:
- type: string
- type: 'null'
title: Query
description: Optional query to focus the audience research on a specific topic or angle. When provided, personas will be weighted toward conversations matching this query in addition to the brand itself. For example, 'running shoes for beginners' produces personas focused on entry-level runners, while 'streetwear fashion' emphasizes style-driven audiences. When omitted, the endpoint explores the brand broadly.
effort:
$ref: '#/components/schemas/GroundedEffort'
description: 'Effort level: low, mid, high. Default is mid.'
default: auto
include_citations:
type: boolean
title: Include Citations
description: When true, include real world citations for each persona.
default: true
type: object
required:
- brand_url
title: GroundedInsightsInput
MatchInterpretation:
properties:
mode:
$ref: '#/components/schemas/InterpretationMode'
description: How the persona was provided.
facets:
items:
$ref: '#/components/schemas/PersonaFacetSummary'
type: array
title: Facets
description: The typed facets read from the persona.
llm_calls:
type: integer
minimum: 0.0
title: Llm Calls
description: Number of model calls used to read this persona.
language:
anyOf:
- type: string
- type: 'null'
title: Language
description: This persona's dominant language, as a two-letter code, or `mixed` when the persona mixes multiple languages with no single dominant one. Null when it could not be determined.
price_sensitivity:
anyOf:
- type: string
enum:
- budget
- mid
- premium
- type: 'null'
title: Price Sensitivity
description: 'This persona''s price sensitivity, when stated: budget, mid or premium. Null when the persona said nothing about spend.'
additionalProperties: false
type: object
required:
- mode
- facets
- llm_calls
title: MatchInterpretation
description: What was read from the supplied persona.
securitySchemes:
APIKeyHeader:
type: apiKey
in: header
name: X-API-Key