ASK ME API — AGENT QUICKSTART https://ask-me.dev Ask Me lets a coding agent show rich choices in a browser and receive one structured human response. No account or login is required. THE REQUIRED FLOW 1. POST one complete interaction to /v1/interactions. 2. Show the returned form_url to the human. 3. Poll response_url with agent_token until status is no longer open. 4. Do not ask the human to return to chat. Their browser submission is the answer. 5. Continue only after the response reaches a terminal status. THE ONLY QUESTION PRIMITIVE Every field has type "question" and two independent parts: - items: zero or more things the human can inspect. Each item has a stable id, label, optional description/recommendation, and up to four content blocks. - response: how the human answers: single, multiple, binary, or text. Content block types currently supported: - text: {"type":"text","text":"..."} - image: {"type":"image","asset_id":"...","alt":"..."} - audio: {"type":"audio","asset_id":"...","description":"..."} - video: {"type":"video","asset_id":"...","description":"..."} HTML and Markdown renderers are not part of the current contract. CREATE A SESSION POST https://ask-me.dev/v1/interactions Content-Type: application/json Idempotency-Key: { "session": null, "expires_in_seconds": 86400, "form": { "title": "Choose an implementation", "description": "Which direction should I take?", "fields": [ { "id": "approach", "type": "question", "label": "Choose an approach", "items": [ { "id": "focused", "label": "Focused", "description": "Complete one workflow end to end", "recommended": true }, { "id": "broad", "label": "Broad", "description": "Cover more surface with less depth" } ], "response": { "mode": "single", "allow_none": false, "allow_other": true, "comment": { "enabled": true, "required": false, "label": "Why this direction?", "multiline": true } } } ] } } The response contains: { "session_id": "019f...", "revision": 1, "form_url": "https://ask-me.dev/s/arm_public_...", "agent_token": "arm_agent_...", "response_url": "https://ask-me.dev/v1/sessions/.../revisions/1/response", "ping_url": "https://ask-me.dev/v1/sessions/.../ping", "poll_after_seconds": 3, "expires_at": "..." } Show form_url to the human. Store agent_token privately; it is returned only once. WAIT FOR THE ANSWER Run this as one shell tool call. It remains quiet while the question is open. export RESPONSE_URL='' export AGENT_TOKEN='' while :; do response="$(curl -sS "$RESPONSE_URL" -H "Authorization: Bearer $AGENT_TOKEN")" case "$response" in *'"status":"open"'*) sleep 3 ;; *) printf '%s\n' "$response"; break ;; esac done Do not implement polling as repeated model turns. Keep the wait inside one shell invocation whenever the agent runtime permits long-running commands. Response states: - open: sleep for poll_after_seconds and request again. - answered: read response.answers and continue. - superseded: stop polling this revision; a newer question replaced it. - expired: stop; the revision can no longer be answered. RESPONSE MODES single - Requires at least two items. - Answer: {"field_id":"approach","type":"question","mode":"single","selected_item_ids":["focused"]} - allow_none permits an empty selected_item_ids array. - allow_other permits other_text instead of a selected item. multiple - Requires at least two items and accepts min/max bounds. - Answer: {"field_id":"features","type":"question","mode":"multiple","selected_item_ids":["search","export"]} binary - Presents zero or one item. - Has customizable positive_label and negative_label. - Answer: {"field_id":"keep","type":"question","mode":"binary","value":true} text - items may be empty or may contain material to inspect before writing. - Supports multiline and placeholder. There is no email, number, URL, or regex validation. - Answer: {"field_id":"context","type":"question","mode":"text","text":"Keep it reversible."} single, multiple, and binary may enable one optional or required comment object. MEDIA POST /v1/interactions accepts application/json for forms without files and multipart/form-data for local media. Declare every file once in form.assets: { "id": "quiet_room", "filename": "quiet-room.jpg", "media_type": "image/jpeg" } Reference it directly from an item content block: { "id": "quiet", "label": "Quiet room", "content": [ {"type":"image","asset_id":"quiet_room","alt":"A quiet room with soft light"} ] } Send the JSON envelope in the multipart field spec and each file in a part named asset.: curl -X POST https://ask-me.dev/v1/interactions \ -H 'Idempotency-Key: ' \ -F 'spec=","expected_revision":1}, "form": { ...the complete next form... } } The browser updates in place. Poll the new response_url. Each revision contains exactly one question. Answered revisions remain visible to the human in the History dropdown on the same page. PING THE OPEN PAGE POST /v1/sessions//ping Authorization: Bearer Content-Type: application/json {"kind":"attention","message":"I have another question for you.","sound":"default","dedupe_key":""} SECURITY AND LIMITS - The API has no login. Initial creation is rate-limited by IP. - form_url is an unguessable public capability for viewing and submitting only. - agent_token permits polling, replacement, pinging, and session deletion. - Never put agent_token in form_url or expose it to the human. - Never ask for passwords, API keys, tokens, or other secrets. - Exactly one question per revision, 50 items, 4 content blocks per item, 24 assets. - 10,000 characters per text response, alternative, or comment. - Session lifetime: 5 minutes to 7 days; up to 100 revisions.