API Reference · Query
Offer Query
Send intent, context, constraints, and pagination fields to discover offers for AI product or agent experiences.
Runtime projection
This route documents the public HTTP request and response surface. It is not the canonical AgentOffer Protocol: use Protocol v1.0 for normative Query and Offer semantics. Service access and credentials are configured separately in the Developer Portal.
Protocol v1.0 also defines optional alternative_offersalongside an empty main list and empty_reason, with a selection reason for each alternative. Service, SDK and Agent integration is pending; these fields are not a guarantee of the deployed HTTP response. See Query alternatives for the example, compatibility limits and rollout order. Existing requests, including force_offer, are unchanged.
Operations
/v1/offers/queryBearer requiredHeaders that should be present on this request.
AON-Protocol-VersionstringRequired exact current version selector. Send one value equal to `1.0`; every other value is unsupported.
Content-TypeheaderRequest body format for JSON endpoints.
example: application/jsonx-aon-user-pseudo-idstringOptional hosted-service extension carrying a pseudonymous viewer id. It is not part of the canonical v1.0 Query body, is never forwarded to Providers, and is never echoed in the response.
example: pseudo-viewer-xyzx-aon-consentstringOptional hosted-service extension carrying `personalization=granted|denied;jurisdiction=<code>;age=<value>`. It is outside the canonical v1.0 Query body and is never forwarded to Providers.
example: personalization=granted;jurisdiction=EU;age=verifiedJSON payload fields accepted by this endpoint.
objectBounded calling and session context for the current Query. It is not a raw conversation transcript or long-term profile.
4 nested fieldsobjectCalling platform or agent metadata used for diagnostics and integration context.
3 nested fieldsexample: { "name": "shopping-bot", "channel": "api" }namestringOptional non-empty name of the calling platform or agent.
example: shopping-botversionstringOptional caller-reported platform or agent version used for integration diagnostics.
example: 2.1.0channelstringOptional caller-reported interaction channel.
example: apiobjectBounded session continuity for the current conversation.
2 nested fieldsexample: { "previous_request_id": "019dd200-1234-7890-abcd-ef0123456788" }previous_request_idstringOptional Query response identifier used as the explicit comparison baseline for returned hooks.
example: 019dd200-1234-7890-abcd-ef0123456788format: uuidrecent_topicsstring[]Optional bounded list of up to ten recent topic labels. Topics may boost matching overlap but do not change recall or become a raw transcript.
example: ["Tokyo weekend trip", "boutique hotels"]session_idstringOptional session identifier for support correlation.
example: sess_123maxLength: 256conversation_idstring | numberOptional host conversation identifier.
example: conversation_123objectThe user's current intent for this Query, not the complete conversation history.
6 nested fieldsobjectExplicit opt-in Flight search constraints.
2 nested fieldsprofilestringRegistered Query profile identifier.
Allowed valuesflightobjectClosed hard constraints for a typed Flight search.
6 nested fieldsquery_kindstringExplicit reference search or traveler-specific full itinerary quote; no inferred default.
Allowed valuesreference_searchtraveler_quoteobject[]Nonempty itinerary legs in request order.
3 nested fieldsobjectRequested departure airport or city.
2 nested fieldskindstringWhether the requested code denotes an airport or city.
Allowed valuesairportcitycodestringThree-letter uppercase location code; spelling alone does not prove registry membership.
pattern: ^[A-Z]{3}$objectRequested arrival airport or city.
2 nested fieldskindstringWhether the requested code denotes an airport or city.
Allowed valuesairportcitycodestringThree-letter uppercase location code; spelling alone does not prove registry membership.
pattern: ^[A-Z]{3}$departure_datestringActual calendar date at the departure location in YYYY-MM-DD form.
format: datepattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}$object[]Traveler groups, required for a quote and forbidden for a reference search. Typed Flight quotes require matching traveler composition.
4 nested fieldstypestringTraveller type used to state the priced traveller composition.
Allowed valuesadultchildinfantcountintegerPositive number of travellers of this type included in the stated itinerary price.
minimum: 1agesinteger[]Completed years of age on the first local departure date, in traveler order. Supply one age per traveler.
infant_seat_requiredboolean[]Seat requirement for each infant at the same index as ages. Supply one seat flag per infant; forbidden for other traveler types.
cabin_classstringExact cabin required on every returned segment.
Allowed valueseconomypremium_economybusinessfirstmax_connectionsintegerMaximum segment changes within each leg.
minimum: 0nonstop_onlybooleanWhen true, each leg must contain one segment with explicitly empty stops.
object[]Exactly one current text or image input item.
3 nested fieldsexample: { "type": "input_text", "text": "noise cancelling headphones under $200" }typestringContent item kind. Most server integrations start with `input_text`.
example: input_textAllowed valuesinput_textinput_imagetextstringFree-text user intent when the item type is `input_text`.
example: noise cancelling headphones under $200minLength: 1maxLength: 200image_urlstringURI of the current image input for an input_image item.
example: https://example.com/current-product.jpgformat: uriprovenancestringWhether the current intent was directly expressed by the user or inferred from context.
example: user_expressedAllowed valuesuser_expressedinferred_contextconfidencenumberConfidence assigned to an inferred intent. It is required for inferred_context and forbidden for user_expressed intent.
example: 0.8minimum: 0maximum: 1object[]At most three unique references that led to a user-expressed intent. Inferred intent cannot carry origin entries.
2 nested fieldskindstringKind of source reference that led to the current intent.
Allowed valuesoffercategorytopicquery_helperidstringOpaque identifier of the referenced source within its declared kind.
minLength: 1maxLength: 256objectStructured signals for the current turn, such as purchase stage, timeframe, or a budget with an explicit currency.
3 nested fieldsobjectNumeric budget values require an explicit ISO 4217 currency; never infer the currency from language, region, or device.
3 nested fieldsexample: { "max": 200, "currency": "USD" }maxnumberRequired non-negative upper budget bound in the declared budget currency.
example: 200minimum: 0currencystringRequired uppercase three-letter currency code for every numeric budget declaration.
example: USDpattern: ^[A-Z]{3}$minnumberOptional non-negative lower budget bound in the declared budget currency.
example: 100minimum: 0purchase_stagestringOptional current stage in the user's purchase journey.
Allowed valuesexploringcomparingready_to_buytimeframestringOptional timeframe in which the user expects to act.
Allowed valuesnowthis_weekthis_monthlaterrequest_idstringOptional client request identifier for log correlation. UUIDv7 is recommended.
example: 019dd200-1234-7890-abcd-ef0123456789format: uuidtimestampstringOptional RFC 3339 timestamp for when the request was created.
example: 2026-04-28T03:30:00Zformat: date-timetest_modebooleanOptional test-execution marker that defaults to false. Deployments may apply stricter credential or environment controls.
example: falseplacement_idstringOptional top-level body field for platform-defined placement routing. Do not send it as a URL query parameter or under `constraints`.
example: plc_A1b2C3d4E5f6G7h8minLength: 1maxLength: 64pattern: ^\S+$objectExplicit public taxonomy constraints for the current Query.
2 nested fieldscategory_ids[]string[]AON Taxonomy v1 category ids used as public query constraints. Parent ids match descendant offer categories. Ids are case-sensitive; use lowercase registry ids from /protocol/category-taxonomy.
example: othersexcluded_category_ids[]string[]AON Taxonomy v1 category ids to exclude from the current query. Parent ids exclude descendant offer categories.
example: arts_entertainment.adult_entertainmentforce_offerbooleanRequest a fallback recommendation when normal matching returns no offer.
example: falseobjectOptional controls for the shape of the current Query response.
1 nested fieldthinking_modebooleanDefaults to true. Set false when the client does not want `match_reason` in returned offers.
example: trueCurrent v1.0 response envelope with canonical Query metadata and public Offers. Empty matches still return 200 and include the required `data.request_id`, `data.protocol_version`, `data.language`, and empty `data.offers` array.
codestringNo description provided by the current OpenAPI source.
messagestringNo description provided by the current OpenAPI source.
objectNo description provided by the current OpenAPI source.
7 nested fieldsrequest_idstringRequest identifier echoed from the accepted query. AON injects one when the client omits it.
example: 019dd200-1234-7890-abcd-ef0123456789format: uuidprotocol_versionstringTransport protocol line used to produce the response. This is always `1.0` for the current lane and is distinct from `offers[].version`.
example: 1.0Allowed values1.0languagestringLanguage selected for user-facing response content under the stable-v1.0 language-tag profile. It does not express eligibility or targeting.
example: enformat: bcp47object[]Ranked offers that matched the request. Empty array means no eligible offer.
12 nested fieldsoffer_idstringAON-issued, globally unique inventory identity for the logical Offer. It remains stable across returned instances and is distinct from Partner source and request identifiers.
example: 019fc211-c6cd-7e62-9c4d-699c243e6c96format: uuidoffer_instance_idstringAON-issued identity for this dispatch of the Offer. Propagate it unchanged through click and conversion attribution; a later dispatch of the same offer_id receives a different value.
example: 019dd208-27d2-7673-b16f-6897fa120303format: uuidversionstringOffer document-model lineage. It identifies the Offer payload model and does not select the transport protocol version.
example: 3.0Allowed values3.0objectUser-facing descriptive, category, commercial, and availability information for the Offer.
14 nested fieldsobjectRegistered Offer profile facts; optional on ordinary and non-real-time Query results, required for typed Flight results. Details do not imply a live lookup.
2 nested fieldsprofilestringRegistered Offer profile; validated independently of real-time query selection.
Allowed valuesflighthotel_rateobjectClosed facts for the selected registered Offer profile. Flight fields below describe one priced air itinerary.
4 nested fieldstrip_typestringDeclared itinerary topology; semantic validation binds it to the number of legs.
Allowed valuesone_wayround_tripmulti_cityobject[]Non-empty traveller counts grouped by traveller type. Each type may occur at most once under semantic validation. Typed Flight quotes require matching traveler composition.
4 nested fieldstypestringTraveller type used to state the priced traveller composition.
Allowed valuesadultchildinfantcountintegerPositive number of travellers of this type included in the stated itinerary price.
minimum: 1agesinteger[]Completed years of age on the first local departure date, in traveler order. Supply one age per traveler.
infant_seat_requiredboolean[]Seat requirement for each infant at the same index as ages. Supply one seat flag per infant; forbidden for other traveler types.
object[]Ordered itinerary legs. Each leg contains one or more ordered flight segments.
2 nested fieldsobject[]Ordered segments for this leg. Semantic validation requires adjacent arrival and departure continuity.
7 nested fieldsobjectScheduled departure airport and airport-local date-time for this segment.
2 nested fieldsairport_codestringThree-letter uppercase airport code; airport-registry membership is outside this profile.
pattern: ^[A-Z]{3}$local_atstringScheduled local date-time at this airport in YYYY-MM-DDTHH:mm:ss form, without a UTC offset or timezone. Producers normalize a source space separator to T and must not infer missing timezone data.
pattern: ^[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])T(?:[01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$objectScheduled arrival airport and airport-local date-time for this segment.
2 nested fieldsairport_codestringThree-letter uppercase airport code; airport-registry membership is outside this profile.
pattern: ^[A-Z]{3}$local_atstringScheduled local date-time at this airport in YYYY-MM-DDTHH:mm:ss form, without a UTC offset or timezone. Producers normalize a source space separator to T and must not infer missing timezone data.
pattern: ^[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])T(?:[01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$duration_minutesintegerPositive source-provided scheduled elapsed duration of this segment in minutes. It is authoritative for duration; producers must not infer a timezone to derive it from local_at values.
minimum: 1objectCarrier marketing this flight under the displayed flight number.
1 nested fieldcodestringTwo-character uppercase marketing carrier code; registry membership is not asserted by this profile.
pattern: ^[A-Z0-9]{2}$flight_numberstringCarrier-local flight number without the marketing-carrier prefix.
pattern: ^[0-9]{1,4}[A-Z]?$cabin_classstringPublic cabin class for this segment.
Allowed valueseconomypremium_economybusinessfirstobject[]Source-reported stops within this segment. Omission means unknown; an empty array explicitly means no stops.
3 nested fieldsnamestringSource-provided nonblank location label, which may identify a city rather than an airport.
minLength: 1pattern: \Sairport_codestringSource-provided uppercase airport code; do not infer it from a location name.
pattern: ^[A-Z]{3}$duration_minutesintegerPositive source-provided stop duration in minutes.
minimum: 1duration_minutesintegerSource-provided total leg duration including connection waiting, at least the sum of segment durations.
minimum: 1price_basisstringPrice nature: a reference amount without traveler composition or a complete itinerary total.
Allowed valuesreferenceitinerary_totaltitlestringShort user-facing name used to identify the Offer in a result or presentation.
example: QuietPro 500 HeadphonesdescriptionstringUser-facing explanation of what the Offer provides. It is Offer content, not an AON ranking explanation.
example: Premium truly wireless noise cancelling earbuds with adaptive sound.objectPrimary AON Taxonomy v1 classification for the Offer.
1 nested fieldidstringCanonical AON Taxonomy v1 identifier for the Offer's primary classification. Resolve ids from /protocol/category-taxonomy.
example: travel_tourism.accommodations.hotels_motels_resorts.hotelsobjectOptional user-visible rating summary supplied with the Offer. It is descriptive content and not an AON endorsement.
3 nested fieldsvaluenumberRating value on the declared five-point scale.
example: 4.6minimum: 0maximum: 5countintegerPositive number of observations represented by the rating when supplied.
example: 128minimum: 1sourcestringOptional name of the source that supplied the rating.
example: Verified customersobject[]Optional non-empty, bounded list of structured user-facing facts, such as duration, plan tier, or included features.
4 nested fieldstypestringStable machine-readable key for the displayed fact.
example: plan_tiervaluestring | number | booleanValue of the displayed fact.
example: prounitstringOptional non-empty unit that qualifies the displayed value.
example: monthdisplay_patternstringOptional presentation template for this fact. Only same-item tokens `${type}`, `${value}`, and `${unit}` are allowed.
example: ${value} per ${unit}objectPublic commercial presentation; required for typed Flight results and optional for Generic results. It excludes internal commission, settlement, and eligibility policy.
4 nested fieldsobjectObserved original-price context. It is only valid together with commercial.price and does not prove display_price or foreign-exchange freshness. May accompany registered profile facts on ordinary requests; profile-required observation and expiry rules apply.
2 nested fieldsobserved_atstringRFC 3339 instant at which the producer observed the original Offer price.
format: date-timevalid_untilstringOptional RFC 3339 instant through which the producer explicitly asserts the observed original price remains valid; semantic validation requires it to be after observed_at.
format: date-timeobjectOriginal price; required for typed Flight results and optional for Generic results. Flight traveler_quote requires an itinerary total including taxes and mandatory fees.
4 nested fieldstax_statusstringOriginal price tax and mandatory-fee status under the returned Offer profile; typed Flight traveler_quote requires included.
Allowed valuesincludedexcludedunknownamountstringCanonical decimal string for the displayed public Offer price, not Goal commission.
example: 189.99currencystringUppercase three-letter currency code for the displayed public Offer price.
example: USDpattern: ^[A-Z]{3}$unitstringOptional unit or billing period to which the displayed price applies. Typed Flight permits only one_time.
example: monthAllowed valuesone_timenightdayweekmonthyearobjectOptional AON-derived presentation amount and currency for this Query response. It overrides only price.amount and price.currency for display and is invalid without an original price.
2 nested fieldsamountstringCanonical non-negative decimal amount to present for this response, with at most twelve integer digits and six fractional digits.
example: 718.42pattern: ^(?:0|[1-9][0-9]{0,11})(?:\.[0-9]{1,6})?$currencystringUppercase three-letter target presentation currency syntax; registry membership is not asserted.
example: CNYpattern: ^[A-Z]{3}$fulfillment_notestringOptional short user-facing note about fulfillment or a material price condition.
short_descriptionstringOptional concise display summary for the Offer. It is limited to 500 code points and 50 word-like segments.
example: Premium noise cancelling earbuds with adaptive sound.maxLength: 500offer_typestringHigh-level class of what is offered. It supports presentation and product understanding; it is not the executable consumer action.
example: online_serviceAllowed valuesphysical_productdigital_goodscontentonline_serviceoffline_servicesecondary_category_idsstring[]Optional non-empty list of additional AON Taxonomy v1 classifications. Entries add descriptive coverage and must remain distinct from the primary category and one another under semantic validation.
example: ["finance.investing.crypto_and_digital_assets"]recommendation_reasonstringOptional static Partner- or provider-authored Offer copy. It is not the per-request AON match explanation and is unaffected by thinking_mode.
start_atstringOptional start of the user-visible Offer availability window.
format: date-timeexpire_atstringOptional end of the user-visible Offer availability window. When both bounds are supplied, it must not precede start_at.
format: date-timeobjectPublic identity of the party responsible for the Offer.
6 nested fieldsidstringStable identifier for the merchant, brand, provider, publisher, or other party responsible for the Offer. It is not an Offer identifier.
example: ent_audiomartnamestringUser-facing name of the entity responsible for the Offer.
example: AudioMarttypestringRole of the entity in relation to the Offer.
example: providerAllowed valuesmerchantbrandproviderpublisherotherdescriptionstringOptional non-empty user-facing description of the responsible entity.
example: Consumer electronics retailer.websitestringOptional public HTTPS website for the responsible entity. It is identity metadata, not the action destination, and must not contain URI userinfo.
example: https://www.audiomart.exampleformat: uripattern: ^[Hh][Tt][Tt][Pp][Ss]://logostringOptional public logo for the responsible entity. It is an absolute HTTPS resource URI and must not contain URI userinfo.
example: https://cdn.example.com/logos/audiomart.pngformat: uripattern: ^[Hh][Tt][Tt][Pp][Ss]://objectOptional provenance for the external platform or site where listing information was observed.
4 nested fieldskindstringClassification of the external place where user-facing listing information was observed.
Allowed valuesplatformmarketplacemerchant_siteofficial_siteothernamestringUser-facing name of the observed platform or site. It remains distinct from entity.name.
observed_atstringUTC timestamp for when the listing information was observed, not the Offer availability window.
format: date-timelogostringOptional explicit logo of the observed platform or site. It is an absolute HTTPS resource URI without userinfo and must not be inferred from other Offer fields.
format: uripattern: ^[Hh][Tt][Tt][Pp][Ss]://object[]Optional non-empty list of user-facing creative assets for presenting the Offer. It is distinct from entity.logo and listing_source.logo.
5 nested fieldsurlstringAbsolute HTTPS URI for retrieving the creative asset; URI userinfo is forbidden.
example: https://example.com/assets/quietpro-500-hero.jpgformat: uripattern: ^[Hh][Tt][Tt][Pp][Ss]://formatstringCreative asset format.
example: imageAllowed valuesimagevideohtml5tagstringOptional producer-supplied label for the creative asset. It must not be treated as targeting or eligibility data.
example: herodimensionsstringOptional producer-declared dimensions or aspect descriptor for rendering.
example: 1200x628alt_textstringOptional accessibility text describing the creative asset.
objectExecutable user-choice destination associated with the Offer.
6 nested fieldstypestringTechnical form of the executable action destination.
example: open_urlAllowed valuesopen_urldeep_linkopen_appcustomobjectExecutable action parameters. Stable v1.0 defines one safe absolute URI destination.
1 nested fieldurlstringSafe absolute URI invoked when the user chooses the action. javascript, data, vbscript, and file schemes are forbidden; open_url additionally requires HTTPS.
example: https://partner.example.com/products/quietpro-500format: uripattern: ^(?!(?:[Jj][Aa][Vv][Aa][Ss][Cc][Rr][Ii][Pp][Tt]|[Dd][Aa][Tt][Aa]|[Vv][Bb][Ss][Cc][Rr][Ii][Pp][Tt]|[Ff][Ii][Ll][Ee]):)[A-Za-z][A-Za-z0-9+.-]*:namestringOptional non-empty concise call-to-action label for the user.
example: Shop nowconsumer_actionstringUser-intent classification for the action. It describes what the user is invited to do and is distinct from a conversion Goal event.
example: buyAllowed valueslearn_morebuybooksubscribedownloadclaimsign_upopendescriptionstringOptional non-empty user-facing explanation of what invoking the action does.
example: Open the product page on the merchant site.destination_typesstring[]Optional non-empty declaration of destination surfaces supported by the action. It does not replace action.type or payload.url.
example: webAllowed valueswebappphoneemailobject[]Public conversion event declarations and their associated public pricing model.
3 nested fieldseventstringCanonical conversion event name for this Goal; events are unique within one Offer.
example: conversionpattern: ^[a-z][a-z0-9_]{0,63}$objectGross commission the Partner declares payable to AON for an approved, attributed occurrence of this Goal, before fees, developer share, refunds, holds, disputes, or adjustments.
4 nested fieldsmodelstringGross Partner-to-AON commission model for an approved, attributed occurrence of the Goal. It is not the user-visible Offer price or final settlement.
example: cpaAllowed valuescpacpsamountstringStrictly positive canonical decimal amount of gross Partner-to-AON commission for one approved Goal event.
example: 10pattern: ^(?:0|[1-9][0-9]{0,11})(?:\.[0-9]{1,6})?$excluded: 0, 0.0, 0.00, 0.000, 0.0000, 0.00000, 0.000000currencystringUppercase three-letter currency code for the CPA commission amount.
example: USDpattern: ^[A-Z]{3}$ratestringStrictly positive canonical percentage rate, greater than zero and no greater than 100, applied to the gross conversion amount in its reported currency.
example: 12.5pattern: ^(?:100(?:\.0{1,4})?|[1-9]?[0-9](?:\.[0-9]{1,4})?)$excluded: 0, 0.0, 0.00, 0.000, 0.0000descriptionstringOptional user-facing explanation of what outcome constitutes the Goal; it does not change attribution or payment terms.
object[]Optional non-empty, bounded list of source-provided statements about the Offer. They are not AON endorsements.
2 nested fieldskindstringClassification of the statement so consumers can present it with appropriate context.
Allowed valuesadvertiser_claimuser_benefitavailabilitytextstringUser-facing statement text. It remains source-provided content, not an AON endorsement.
content_languagestringLanguage tag for user-facing Offer text under the stable-v1.0 BCP-47 syntax profile. It does not express targeting eligibility or select the protocol version.
example: en-USformat: bcp47match_reasonstringAON-authored, per-request user-facing explanation of why this Offer matches the current intent. It is omitted when response_options.thinking_mode is false and must not expose private reasoning or ranking data.
objectOptional non-empty user-facing guidance for refining the current intent or exploring an adjacent topic. It does not change returned Offers.
2 nested fieldsobject[]Up to three non-empty suggestions that narrow or clarify the current Query intent.
3 nested fieldslabelstringShort user-facing label for the refinement.
minLength: 1maxLength: 160objectStructured and bounded instruction for deriving a subsequent Query without deleting current request fields.
2 nested fieldsobjectRequired non-empty partial update limited to intent.signals and category constraints. Omission preserves values, objects merge, arrays replace, and null is invalid.
2 nested fieldsobjectOptional intent portion of the next-Query update; when present it contains non-empty signals.
1 nested fieldobjectNon-empty intent signals proposed for the next Query. Omitted signal members remain unchanged.
3 nested fieldsobjectOptional budget update with an explicit upper bound and currency.
3 nested fieldsmaxnumberRequired non-negative replacement upper budget bound.
minimum: 0currencystringRequired uppercase three-letter currency code for the budget update.
pattern: ^[A-Z]{3}$minnumberOptional non-negative replacement lower budget bound.
minimum: 0purchase_stagestringOptional replacement purchase-journey stage.
Allowed valuesexploringcomparingready_to_buytimeframestringOptional replacement action timeframe.
Allowed valuesnowthis_weekthis_monthlaterobjectNon-empty category-constraint update. Supplied arrays replace prior arrays, including an empty array that clears a constraint.
2 nested fieldscategory_ids[]string[]Replacement list of included AON Taxonomy v1 category ids.
excluded_category_ids[]string[]Replacement list of excluded AON Taxonomy v1 category ids.
object[]Optional non-empty provenance references to copy into intent.origin if the user adopts this suggestion.
2 nested fieldskindstringKind of source reference for the suggested next Query.
Allowed valuesoffercategorytopicquery_helperidstringOpaque identifier of the suggested Query source within its declared kind.
minLength: 1maxLength: 256speakstringOptional longer phrasing suitable for voice or conversational presentation.
minLength: 1maxLength: 500object[]Up to two adjacent-topic suggestions ordered by descending confidence within this response.
4 nested fieldslabelstringShort user-facing label for the related topic.
minLength: 1maxLength: 160basisstringDeclared relationship between the follow-up topic and the current Query.
Allowed valuescategory_complementsequential_journeyproblem_to_productcomparison_alternativeuser_interestseasonalobjectStructured and bounded instruction for deriving a subsequent Query without deleting current request fields.
2 nested fieldsobjectRequired non-empty partial update limited to intent.signals and category constraints. Omission preserves values, objects merge, arrays replace, and null is invalid.
2 nested fieldsobjectOptional intent portion of the next-Query update; when present it contains non-empty signals.
1 nested fieldobjectNon-empty intent signals proposed for the next Query. Omitted signal members remain unchanged.
3 nested fieldsobjectOptional budget update with an explicit upper bound and currency.
3 nested fieldsmaxnumberRequired non-negative replacement upper budget bound.
minimum: 0currencystringRequired uppercase three-letter currency code for the budget update.
pattern: ^[A-Z]{3}$minnumberOptional non-negative replacement lower budget bound.
minimum: 0purchase_stagestringOptional replacement purchase-journey stage.
Allowed valuesexploringcomparingready_to_buytimeframestringOptional replacement action timeframe.
Allowed valuesnowthis_weekthis_monthlaterobjectNon-empty category-constraint update. Supplied arrays replace prior arrays, including an empty array that clears a constraint.
2 nested fieldscategory_ids[]string[]Replacement list of included AON Taxonomy v1 category ids.
excluded_category_ids[]string[]Replacement list of excluded AON Taxonomy v1 category ids.
object[]Optional non-empty provenance references to copy into intent.origin if the user adopts this suggestion.
2 nested fieldskindstringKind of source reference for the suggested next Query.
Allowed valuesoffercategorytopicquery_helperidstringOpaque identifier of the suggested Query source within its declared kind.
minLength: 1maxLength: 256confidencenumberProducer-normalized relevance estimate. It is comparable only among follow-up topics in this response, not across requests or producers.
minimum: 0maximum: 1object[]Optional change cues comparing a returned Offer with an explicit previous Query baseline. Hooks do not register watches or guarantee delivery.
6 nested fieldskindstringCategory of changed Offer information observed against the baseline.
Allowed valuesprice_changeavailability_changeeligibility_changecontent_changetitlestringShort user-facing title for the change cue.
minLength: 1maxLength: 160subject_offer_idstringoffer_id of the returned Offer whose current representation is being compared.
format: uuidbaseline_request_idstringPrior Query response id used as the comparison baseline. It must equal the current request context.session.previous_request_id.
format: uuidobjectStructured and bounded instruction for deriving a subsequent Query without deleting current request fields.
2 nested fieldsobjectRequired non-empty partial update limited to intent.signals and category constraints. Omission preserves values, objects merge, arrays replace, and null is invalid.
2 nested fieldsobjectOptional intent portion of the next-Query update; when present it contains non-empty signals.
1 nested fieldobjectNon-empty intent signals proposed for the next Query. Omitted signal members remain unchanged.
3 nested fieldsobjectOptional budget update with an explicit upper bound and currency.
3 nested fieldsmaxnumberRequired non-negative replacement upper budget bound.
minimum: 0currencystringRequired uppercase three-letter currency code for the budget update.
pattern: ^[A-Z]{3}$minnumberOptional non-negative replacement lower budget bound.
minimum: 0purchase_stagestringOptional replacement purchase-journey stage.
Allowed valuesexploringcomparingready_to_buytimeframestringOptional replacement action timeframe.
Allowed valuesnowthis_weekthis_monthlaterobjectNon-empty category-constraint update. Supplied arrays replace prior arrays, including an empty array that clears a constraint.
2 nested fieldscategory_ids[]string[]Replacement list of included AON Taxonomy v1 category ids.
excluded_category_ids[]string[]Replacement list of excluded AON Taxonomy v1 category ids.
object[]Optional non-empty provenance references to copy into intent.origin if the user adopts this suggestion.
2 nested fieldskindstringKind of source reference for the suggested next Query.
Allowed valuesoffercategorytopicquery_helperidstringOpaque identifier of the suggested Query source within its declared kind.
minLength: 1maxLength: 256descriptionstringOptional user-facing explanation of the observed change.
minLength: 1maxLength: 500empty_reasonstringPrimary explanation required exactly when offers is empty in a Generic Query response. Forbidden in typed Flight responses, including empty results. If several causes apply, canonical precedence selects one value.
Allowed valuesfrequency_cappedbelow_relevance_thresholdscene_suppressedno_materialconsent_missingextraobjectNo description provided by the current OpenAPI source.
AON-Protocol-VersionstringHTTP response header that echoes the exact selected current Query protocol version on successful v1.0 responses.
example: 1.0Allowed values1.0X-AON-TRACE-IDstringHTTP response header for AON support diagnostics. It is not part of the JSON response body.
example: trc_01HX6P8T4K2W9QX6Y7Z8A9BCDEMalformed request body, unsupported field value, or invalid request shape.
- Missing `intent.content[]` or unsupported content item type.
- `constraints.category_ids[]` contains a value outside AON Taxonomy v1.
- `intent.provenance` or another Protocol v1.0 required field is missing.
- Validate the request against the documented field table.
- Start from the minimal request example, then add `constraints.category_ids` only when the user intent maps to a taxonomy id.
Curated guidance, not contract schema
Missing, expired, revoked, or invalid bearer credential.
- `Authorization: Bearer <token>` is missing.
- The token belongs to the wrong account or environment.
- The credential has been rotated or revoked.
- Create or rotate an API key from the developer app flow.
- Confirm the request is sent to the matching staging or production base URL.
Curated guidance, not contract schema
The integration exceeded the accepted request rate for the current window.
- A worker retried immediately in a loop.
- Multiple sessions share the same key without backoff.
- Apply exponential backoff with jitter.
- Respect retry windows when returned and avoid duplicate immediate retries.
Curated guidance, not contract schema
Platform envelope error code for a malformed, empty, inactive, unauthorized, or unknown `placement_id`. It is returned as the service envelope `code`, not as a canonical AgentOffer Protocol response payload field.
- `placement_id` is empty, whitespace-only, malformed, inactive, missing, or belongs to another app.
- The placement exists but is not available to the credential used for this request.
- Confirm the placement id was copied from the app's placement configuration.
- Send placement as top-level JSON body field `placement_id`, not as `/v1/offers?placement_id=...` and not under `constraints`.
Curated guidance, not contract schema
Platform envelope error code for a catalog-backed placement whose configured catalog has no available offers. It is returned as the service envelope `code`, not as a canonical AgentOffer Protocol response payload field.
- The placement routes to an offerwall catalog data source.
- The selected catalog currently has no active eligible offers.
- Review the catalog configuration and offer lifecycle state.
- Retry only after inventory changes; immediate retries with the same placement should not change the result.
Curated guidance, not contract schema
Behavior, compatibility, and source notes
Current Offer Query contract for new integrations. Send exactly one `AON-Protocol-Version` header whose field value is exactly `1.0`. Missing, duplicate, historical, approximate, range, unknown, or any other non-exact selector returns HTTP 400 `UNSUPPORTED_PROTOCOL_VERSION`; no fallback is performed. Successful responses echo `1.0` in both the response header and `data.protocol_version`, send `Vary: AON-Protocol-Version`, and return `data.offers[]` following the canonical public Offer v1.0 schema. Optionally pass `placement_id` to route the query by a configured ad placement; invalid placement values return `INVALID_PLACEMENT` and an empty catalog placement returns `CATALOG_NO_AVAILABLE_OFFERS`. Unknown or inactive `constraints.category_ids` fail closed with HTTP 400 `INVALID_CATEGORY_ID` and an indexed `extra.field_path`; resolve category ids first rather than guessing. If the caller supplies `request_id`, this endpoint replays the first response for that (caller identity, request id) pair for 10 minutes without duplicating the five write-side effects: inbound journal, impressions/billing projection, outbound metrics, partner journal, and embedding journal. A retryable HTTP 503 `SERVICE_BUSY` may be retried with the same `request_id`; HTTP 409 `QUERY_REPLAY_UNAVAILABLE` means the durable query is finalized but its response body can no longer be replayed, so issue a new logical request with a new `request_id`.
- This is the main partner entry point for offer discovery. Start here once bearer auth is working.
- Persist `offers[].offer_instance_id` for downstream attribution and conversion reporting.
- Flight `reference_search` forbids travelers and returns price_basis reference; `traveler_quote` requires traveler groups and returns price_basis itinerary_total with tax_status included. Hard itinerary constraints must match; intent text does not override them.
- Typed Flight success returns usable Offers without source execution metadata. Empty offers means no usable results for this request; it does not claim market-wide coverage. Total source failure remains an error.
- Ordinary queries, including non-real-time requests, may return registered `offer_info.details` with profile-required price, tax and quote facts. Details alone do not imply a live lookup. Opt in to strict real-time Flight matching with `intent.details.profile: flight` and explicit `data.query_kind` and itinerary legs. Typed Flight results require complete matching Flight details and original price including tax_status. Public responses omit execution metadata; empty typed results mean no usable Offers for this request. Canonical protocol support does not by itself certify a deployed provider capability.
Quick Recipes
Minimal request
Use this shape to validate bearer auth and the required intent/context envelope.
- Send
intent.content[]with at least one user input item. - Include
intent.provenanceand send only bounded context for the current conversation. - Use the full request example in Endpoints when you need a copyable payload.
Production request
Add platform, bounded session context, structured signals, and public constraints once the minimal request works.
- Add
context.platformandcontext.sessionfor bounded continuity. - When your app has a placement context, send it as top-level body field
placement_id. - Use
constraints.category_idswhen the user intent maps to AON Taxonomy v1. - Set
response_options.thinking_modeto false when the client does not need match reasons.
Empty result
Treat an empty `offers` array as a valid response. Show an empty state or relax constraints.
code: SUCCESSwithdata.offers: []is not an integration failure.- Log
data.request_idbefore retrying or relaxing constraints. - Keep the complete empty-result payload in Endpoints as the response reference.
- Do not treat an empty match as HTTP 204; the JSON body is intentional so clients keep request correlation.
Error response
Handle malformed payloads, invalid credentials, placement errors, and rate limits explicitly.
- Use 400 to fix request shape or missing required fields.
INVALID_PLACEMENTandCATALOG_NO_AVAILABLE_OFFERSare platform envelopecodevalues for placement-scoped queries.- Use 401 to check bearer token presence, account scope, or credential rotation.
- Use 429 backoff with jitter and avoid immediate retry loops.
Common Questions
What is the difference between `intent` and `constraints`?
`intent` describes what the user wants in natural language or multimodal content. `constraints` is for low-ambiguity structured constraints. The first public version only exposes canonical category constraints.
Should `category_ids` use root ids or leaf ids?
Send AON Taxonomy v1 ids from /protocol/category-taxonomy. A root id such as `travel_tourism` matches descendants, a leaf id such as `computers_electronics.computers.software` is more precise, and `others` currently matches only stored id `others`. Historical v0.1 aliases may be tolerated in migration paths, but public integrations should store and send taxonomy ids.
How do we correlate conversions?
Persist the returned `offer_instance_id`. It is the dispatch-level identity for click, conversion, and settlement attribution; do not replace it with a legacy tracking URL.
What should we do when no offers are returned?
Render a normal empty state, log the `request_id`, and consider relaxing constraints before retrying. Do not treat `offers: []` as a failed request.
How should we debug 401 responses?
Check that `Authorization: Bearer YOUR_API_KEY` is present, the key belongs to the right account context, and the credential has not expired or been rotated.
How should we handle 429 responses?
Apply exponential backoff with jitter, honor retry windows when present, and avoid immediate retry loops from the same session or worker.
Where should we put `placement_id`?
Send `placement_id` as an optional top-level JSON body field on `POST /v1/offers/query`. Do not send it as `/v1/offers?placement_id=...` and do not nest it inside `constraints`.
Is `/v1/sdk/offers/query` still available?
No — `/v1/sdk/offers/query` was retired in SVC-PLATFORM-F260813162251. All REST integrations, including former SDK-facing callers, now use `POST /v1/offers/query`.
Implementation checklist · 3 items
- Get an API key from Quick Start or Developer Portal first.
- Send a structured `intent` payload, even for simple text-only queries.
- Persist returned tracking URLs or identifiers for downstream attribution.
Related links
Optionally resolve registry ids for location pickers, normalization, or Offer-side geographic targeting; Query v1.0 has no viewer-location input.
Browse the category ids accepted by constraints.category_ids.
Shared HTTP status, body envelope, and retry guidance.