Skip to main content
Reconciliation is how Invoke resolves ambiguous tool call outcomes without retrying blindly. When a tool call times out, the response is dropped, or the network fails, Invoke checks live source-of-truth state before deciding whether to allow a retry.

Why reconciliation exists

When an API call returns an unknown outcome, the agent faces a dilemma:
  • Retry → risk a duplicate side effect if the first attempt already succeeded
  • Don’t retry → risk leaving the action incomplete if the first attempt failed
Neither is safe without knowing what actually happened. Reconciliation solves this by checking live state first.

How it works

1

Unknown outcome detected

A tool call returns an ambiguous result — a timeout, a dropped connection, or an HTTP 5xx with no confirmation.Invoke marks the execution as unknown and does not allow a retry yet.
2

Live state check

Invoke calls POST /outcomes/reconcile with the action context and a snapshot of current live state.For a Stripe charge, that means querying whether the charge already exists on the customer. For a CRM write, that means fetching the current record. For a Linear issue, that means checking whether the title already exists.
3

Decision returned

Invoke returns one of three decisions:
DecisionMeaning
do_not_retryLive state confirms the action already succeeded. Retry blocked.
retry_allowedLive state confirms the action did not succeed. Retry is safe.
replanLive state has drifted from assumed state. Agent should replan.

Example: Stripe charge timeout

const result = await invoke.call({
  tool: "stripe.charge_customer",
  params: { customer_id: "cust_123", amount: 2400 },
  agentId: "billing-agent",
  idempotencyKey: "charge:cust_123:2400"
})

// result.status === "reconciled"
// result.final_outcome === "already_succeeded"
// result.retry === "blocked"
The agent never needs to implement the reconciliation logic. Invoke handles it automatically for any tool classified as write-once-checkable.

Calling the reconcile endpoint directly

curl -X POST https://api.invokehq.run/outcomes/reconcile \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "action": {
      "intent": "charge_customer",
      "tool": "stripe.charge_customer",
      "params": { "customer_id": "cust_123", "amount": 2400 }
    },
    "outcome": "UNKNOWN",
    "current_state": { "charged": true, "customer_id": "cust_123", "amount": 2400 },
    "conditions": { "charged": true }
  }'

Next steps