---
title: "Ask a human to fix what your agent could not"
method: POST
path: "/v1/interventions"
---

# Ask a human to fix what your agent could not

`POST /v1/interventions`

## Request

- Base URL: `https://api.doubleoh.ai`
- URL: `https://api.doubleoh.ai/v1/interventions`
- Auth: one of:
  - API key in header `x-api-key`
  - HTTP bearer

Opens an intervention and returns a fix link for a human to drive the stuck page. Three shapes come back: a fresh fix link (201); a deflection (200, `deflected: true`) when a learned skill already answers this wall — nobody is paged, retry with the skill; if it fails, report `{worked: false}` and the next ask reaches a human; or a duplicate (200, `duplicateOf`) when this exact wall is already waiting — `blockedRuns` says how many runs are stuck on it. With no page to take over, send `mode: "answer"` and a `packet` instead of `url`: a person answers in words or a corrected call, and the agent reads it back from `waitUrl`.

## Request body

- object
  - `url` string: The public http(s) page the agent is stuck on. Private and loopback addresses are refused. Leave it out for an answer wall.
  - `mode` 'screen' | 'answer': screen (default): a person takes over the page. answer: a person answers; implied when there is no url.
  - `packet` object: What the agent saw, shown to the person who answers: the call, what came back, its last steps, and the sentences it was held to.
    - `tool` string
    - `args` unknown
    - `error` string
    - `steps` string[]
    - `screenshot` string: Base64 JPEG, 1.5 MB at most.
    - `boundary` object
      - `may` string[]
      - `needsPerson` string[]
      - `never` string[]
    - `amountCents` integer: What you ask to spend, in minor units; needs currency. A yes covers this much at most, and a receipt opened with approvedBy on it may not exceed it.
    - `currency` string: ISO 4217, e.g. EUR.
  - `agent` string: Which of your agents is asking, e.g. "ops-bot". Shown to the person ("asked by ops-bot"); walls from different agents never merge.
  - `task` string, required: One sentence. Phrase it the same way each time — it is part of the skill's identity.

## Response `200`

Deflected (skill answers instead, nobody paged) or duplicate (already waiting).

- object
  - `intervention` object
    - `id` string, nullable
    - `fixUrl` string, nullable
    - `prepared` boolean
    - `deflected` boolean
    - `skill` object, nullable
      - `systemHint` string: The skill as one block of context for a model: boundary first, then the steps, then how to report. Paste it verbatim.
      - `authority` object, nullable
        - `requiresHuman` string[]
        - `never` string[]
      - `name` string
      - `description` string
      - `instructions` string: The steps, as prose. Put this in your agent's context.
      - `timesWorked` integer: Raw counts, not a rate: 5 for 5 is worth following, 1 for 1 is a guess that worked once.
      - `timesFailed` integer
    - `duplicateOf` string
    - `waitingSince` string, date-time
    - `blockedRuns` integer

## Other responses

- `201`: A human has been asked; `fixUrl` is the link to send your team.
- `400`: Bad input, a refused target URL, or `agent_mismatch`: this key belongs to another agent than the `agent` sent.
- `402`: Free plan cap reached, or only the reserve kept for approvals is left (the last 10%; `reservedForApprovals`). The meter is the organisation's: every agent's key counts toward one plan. Learned skills keep working.
- `429`: `rate_limited`: too many calls, or too many new walls from this agent (default 6 a minute, 60 an hour; approvals have their own budget); carries `retryAfterSeconds`, `limit`, and for walls `per` and `agent`. `agent_paused`: a person paused this agent; carries `agent` and `retryAfterSeconds`. `retry-after` says when to try again.

---

[API](https://skmtc.dev/doubleoh/apis/doubleoh-api.md) · [All operations](https://skmtc.dev/doubleoh/apis/doubleoh-api/llms.txt) · [OpenAPI document](https://skmtc.dev/doubleoh/apis/doubleoh-api/revisions/398fb6ef5068?raw)
