POST /v1/selection — report which suggestion was chosen
Tell AutoSugges which suggestion a user picked, so future ranking for that list can improve. Entirely optional and fire-and-forget.
What this endpoint does
A correct raw HTTP call to POST /v1/selection that reports a real selection without ever blocking or being required for the autocomplete itself to work.
Before you call it
- An AutoSugges list that has been published at least once — an unpublished list returns
list_not_published. - The publishable key issued for the application that will call this endpoint.
- The runtime base URL for the environment you are targeting — the AutoSugges dashboard's integration panel shows it.
Parameters
| Parameter | Placeholder | Where it comes from |
|---|---|---|
| baseUrlRequired · public by design | YOUR_RUNTIME_BASE_URL | The AutoSugges dashboard's integration panel, for the environment you are deploying to. The origin of the AutoSugges runtime Worker — scheme and host, no trailing slash and no path. The SDK appends /v1/... itself. |
| publishableKeyRequired · public by design | YOUR_PUBLISHABLE_KEY | The AutoSugges dashboard, under the application that will make the queries. Identifies the consumer, the application, the subscription, the canonical list and the query policy in a single server-side lookup. The client never supplies a list id, tenant id or version hash — if a generated integration is passing one of those, it is wrong. |
| accessTokenOptional · never in client code | YOUR_SERVER_MINTED_ACCESS_TOKEN | Your own backend, which mints it from your AutoSugges credentials. Only for a list whose policy requires a token. Short-lived, sent as authorization: Bearer <token>, and never minted, stored or hardcoded in client code. |
| selectionIdRequired · public by design | REPLACE_WITH_A_UUID_YOU_GENERATE | Generated by the caller. Also doubles as the idempotency key for this report. A duplicate selectionId is ignored rather than double-counted. |
| queryRequestIdRequired · public by design | REQUEST_ID_FROM_THE_/v1/query_RESPONSE | The requestId field of the /v1/query response this selection answers. Ties the selection back to the query that produced it. |
| listIdRequired · public by design | LIST_ID_FROM_THE_/v1/query_RESPONSE | The list.id field of the /v1/query response. The canonical list the chosen item belongs to. |
| itemIdRequired · public by design | ITEM_ID_THE_USER_CHOSE | One of the query response's items[].itemId values. The suggestion the user actually selected. |
| positionRequired · public by design | 1 | The chosen item's 1-based position in the returned ranking. A positive integer. Zero and negative values are rejected. |
How to call it
- Fire it after a real selection. Call this only when a user actually chooses a suggestion — never speculatively, and never per keystroke.
- Send it fire-and-forget. Do not block the UI on this call's response. It is telemetry; the response is only { selectionId } and nothing renders from it.
- Reuse the key placement. key travels inside the JSON body, alongside the other fields — not as a query parameter and not as a header, unlike /v1/query and /v1/bootstrap.
- Handle a rate limit gracefully. This route is rate-limited separately from query quota (DEC-RANK-002). On rate_limited, simply drop the report — never retry in a loop and never surface it to the user.
Example
curl -sS \
-X POST 'YOUR_RUNTIME_BASE_URL/v1/selection' \
-H 'content-type: application/json' \
-d '{
"key": "YOUR_PUBLISHABLE_KEY",
"selectionId": "REPLACE_WITH_A_UUID_YOU_GENERATE",
"queryRequestId": "REQUEST_ID_FROM_THE_/v1/query_RESPONSE",
"listId": "LIST_ID_FROM_THE_/v1/query_RESPONSE",
"itemId": "ITEM_ID_THE_USER_CHOSE",
"query": "par",
"position": 1
}'Security
- This endpoint accepts no Authorization header for the key: the key is a JSON body field here, unlike /v1/query and /v1/bootstrap.
- Never fabricate a selection report for an item the user did not choose — it feeds future ranking for every caller of that list (DEC-RANK-001).
Check that it works
- Select a suggestion in the UI and confirm exactly one POST fires, with the response body { "selectionId": "<the one you sent>" }.
- Send the same selectionId twice and confirm the second call is accepted but not double-counted.
- Confirm the UI never waits on this call — remove network access to this route entirely and confirm suggestions and selection still work end-to-end.
- Omit position or send position: 0 and confirm HTTP 400 with code "invalid_request".
A 200 response of exactly { "selectionId": "<yours>" }. Ranking quality improves over time for future queries against this list; nothing about the current session changes.
Errors this endpoint is likely to return
invalid_keyorigin_not_allowedinvalid_requestrate_limited
Notes
- Skipping this call costs nothing but ranking quality over time — it is never required for autocomplete to function (PRD-FEEDBACK-003).
- There is no ancestors field in this response; the hierarchy chain rides on the suggestion from /v1/query, not on the selection report.