API Reference · Attribution
Tracking
Resolve AON click redirects without losing attribution; Partners report and reverse conversions through the GET postback route.
Operations
/v1/track/click/{aon_id}PublicRoute identifiers embedded in the request path.
aon_idstringAON click tracking identifier.
example: trk_tokyo_001Redirect to the partner destination.
LocationstringRedirect target resolved for the tracked click.
example: https://partner.example.com/travel/tokyo-weekend?aon_id=trk_tokyo_001format: uriTracking identifier not found.
Behavior, compatibility, and source notes
Resolve a tracked click and redirect to the final destination while recording attribution.
- This route returns an HTTP redirect rather than a JSON body.
- Your integration should keep the AON tracking link intact so attribution can be recorded before redirecting to the advertiser destination.
/v1/postback/{partner_id}Partner network policyRoute identifiers embedded in the request path.
partner_idstringPartner identifier receiving the postback route.
example: 019f5f65-dbc1-7c3c-9ef9-9d6d2d8ae001format: uuidAll Provider fields travel in the query string. Send exactly one attribution anchor; `aon_click_id` is recommended.
aon_click_idstringThe AON click id passed to your landing page (typically `aci_…`), returned unchanged. A reversal must carry the same anchor kind and value as the conversion.
example: aci_0192f3a4b5c67d8e9f0a1b2c3d4e5f60event_namestringExact, case-sensitive Goal event declared on the attributed Offer. A reversal must name the Goal of the conversion being reversed.
example: purchaseorder_idstringBusiness identity, 1-256 UTF-8 bytes. `order_id`, `event_id`, and `partner_txn_id` are separate namespaces: a reversal must reuse the same field and value the conversion carried (`order_id=x` is not found by `event_id=x`).
example: ord_10001amountstringDecimal revenue string paired with `currency`. A reversal always reverses the whole conversion and must not carry an amount.
example: 179.99currencystringISO 4217 currency code paired with `amount`.
example: USDactionstringRequest kind, case-insensitive. Absent or `conversion` reports a conversion; `reversal` reverses one; `confirm` acknowledges one. Any other value returns 400 `invalid_action`.
default: conversionAllowed valuesconversionreversalconfirmreasonstringWhy the conversion is reversed, case-insensitive. Missing or unknown values return 400 `INVALID_REVERSAL_REASON`.
Allowed valuesrefundedchargebackmerchant_cancelledinvalid_orderfraudduplicateevent_idstringBusiness identity alias in its own namespace; see `order_id`.
partner_txn_idstringBusiness identity alias in its own namespace; see `order_id`.
aon_tracking_idstringAlternative attribution anchor. Send it instead of, never together with, `aon_click_id`.
offer_instance_idstringAlternative attribution anchor (UUID-shaped `offer_instance_id`, returned unchanged). Send it instead of, never together with, `aon_click_id`. It is a derived value in UUID shape: treat it as an opaque string and do not rely on its UUID version bits or on time ordering.
format: uuidConversion accepted or already recorded; reversal applied (`reversed`) or replayed (`already_reversed`); reversal turned into a dispute (`disputed` / `already_disputed`); confirm recorded (`acknowledged`) or replayed (`already_acknowledged`).
Malformed request: missing or invalid parameters, `invalid_action`, or `INVALID_REVERSAL_REASON`. Terminal.
Curated guidance, not contract schema
Partner route scope, enablement, or IP allowlist validation failed. Terminal.
Curated guidance, not contract schema
`REVERSAL_TARGET_NOT_FOUND` or `ACK_TARGET_NOT_FOUND`: no conversion matches the anchor, `event_name`, and business identity field and value. Terminal.
Curated guidance, not contract schema
Identity conflict, `REVERSAL_TARGET_AMBIGUOUS` (resend with the original business identity), `REVERSAL_ITEM_HELD`, `REVERSAL_INVOICE_PAID`, `REVERSAL_ALREADY_ADJUDICATED`, `REVERSAL_WINDOW_CLOSED` (settlement settled or paid out), or an `ACK_*` confirm rejection. Terminal.
Curated guidance, not contract schema
Attribution window expired, or `postback_json_lane_retired` when the request carries an `AON-Protocol-Version` header. Terminal.
Curated guidance, not contract schema
Well-formed request that does not match AON-side Goal or pricing state. Terminal.
Curated guidance, not contract schema
AON-side internal failure. Retry with backoff and the same business identity.
Curated guidance, not contract schema
Intake temporarily unavailable (`postback_intake_unavailable`). Retry with backoff.
Curated guidance, not contract schema
Behavior, compatibility, and source notes
The only Provider-to-AON postback binding: GET with every parameter in the query string, no body, and no protocol-version header. Send `aon_click_id` and `event_name` to report a Goal conversion; add `action=reversal&reason=...` to the same URL to reverse a previously reported conversion. Requests that carry an `AON-Protocol-Version` header are the retired JSON lane and receive 410 `postback_json_lane_retired`.
- Canonical contract: https://github.com/agentoffernetwork/protocol/blob/main/v1.0/specs/postback.md.
- GET with query parameters is the only Partner postback binding. Do not send a body, an `AON-Protocol-Version` header, or Partner AppKey/AppSecret, HMAC, timestamp, nonce, or signature headers.
- Validation is partner-specific route scope, enablement, and IP allowlisting; reversals use the same checks as conversions.
- Reversal: same URL plus `action=reversal&reason=...`. AON locates one conversion by the same anchor, the same `event_name`, and the same business identity field and value; identity is optional for dedup_strategy=first and required for dedup_strategy=all. Whole conversion only; once per conversion (a replay returns 200 `already_reversed`).
- Reversal stages: an unacknowledged, uninvoiced conversion is reversed (200 `reversed`). An acknowledged or invoiced conversion opens a dispute instead (200 `disputed` with `data.dispute_id`, or `already_disputed`). Refused with 409 only when the item is held (`REVERSAL_ITEM_HELD`), the statement invoice is paid (`REVERSAL_INVOICE_PAID`), a dispute was already upheld or adjusted (`REVERSAL_ALREADY_ADJUDICATED`), or the settlement is settled or paid out (`REVERSAL_WINDOW_CLOSED`); 422 `REVERSAL_DISPUTE_UNAVAILABLE` when the dispute cannot be opened.
- Confirm: same URL plus `action=confirm` (no `reason`, `amount`, or `currency`). Returns 200 `acknowledged` or `already_acknowledged` with `acknowledged_at` and `acknowledged_source`; rejections use `ACK_TARGET_NOT_FOUND` (404), `ACK_TARGET_AMBIGUOUS`, `ACK_SETTLEMENT_NOT_CONFIRMED`, `ACK_CONVERSION_REVERSED`, `ACK_ITEM_UNDER_REVIEW` (409), and `ACK_NOT_BILLABLE` (422). Confirming the monthly statement acknowledges the rest.
- Responses use the `{code, message, data, extra}` envelope; `data` carries `result`, `event_logged`, `reason`, `correlation_id`, and `retryable` on successes and rejections.
- 4xx is terminal; correct the request before sending again. 500 and 503 are retryable with backoff while preserving the same business identity.
Implementation checklist · 2 items
- Keep AON tracking URLs intact until the click redirect resolves.
- Have the Partner report conversions through GET /v1/postback/{partner_id} with the aon_click_id from the click flow, and reverse them on the same URL with action=reversal and a reason.