An HTTP 202 Accepted response means a server accepted a request for processing; it does not mean that processing finished, or even that the request will eventually be acted on. Before telling a customer that an agent completed a task, check the external fact that defines completion for that task. A request leaving your system, a provider accepting it, and the intended change appearing in the outside world are separate events.
Summary
- A tool call reports an interaction with a system. Interpret its response according to that system’s documented contract.
- HTTP
202 is explicit: work is accepted but incomplete, and it may never be carried out.
- A callback can report progress, but a callback is not automatically independent proof. When the provider offers a status endpoint or readback, use its documented semantics to reconcile uncertainty.
- A timeout means your client did not learn the outcome. It does not prove that the provider did nothing.
- Define a task-specific acceptance condition before execution. Show “complete” only when evidence meets it; show “in progress,” “failed,” or “checking” otherwise.
The request was accepted. What happened next?
Consider a synthetic example, not an Armalo incident or customer story. An AI assistant is asked to create a qualified opportunity in a customer relationship management system (CRM). It submits a request to create a record. The provider returns 202 Accepted and a job identifier. The integration then shows “Opportunity created.” Minutes later, the provider’s validation worker rejects the job because a required field is missing.
The tool call succeeded in one narrow sense: the provider received and accepted the request for processing. The business task did not succeed. The integration collapsed two different statements—“the provider accepted this work” and “the opportunity now exists”—into one green check.
HTTP itself makes this distinction clear. RFC 9110 says 202 Accepted indicates that a request was accepted for processing, but processing has not completed. The request might or might not eventually be acted upon; it could be disallowed when processing takes place. The response is intentionally noncommittal. A server should describe the request’s current status and point to a status monitor when it can. (RFC 9110, section 15.3.3)
That is a protocol fact about 202, not a rule that every successful tool response is incomplete. Other HTTP responses and other APIs have their own documented meaning. RFC 9110 §15.3 describes the 2xx class as successful receipt, understanding, and acceptance; the specific status code and endpoint contract still matter. (RFC 9110, section 15.3) The engineer’s job is to map that contract to the user’s requested outcome.
Define “done” outside the transport
An HTTP status is not a business requirement. “Create an opportunity” could mean any of the following:
- The client sent a request.
- The provider accepted a request for later processing.
- The provider says the operation completed.
- A record with the required fields exists in the intended account.
- A person has reviewed the record and accepted the next action.
Those statements are not interchangeable. The right completion condition depends on what the user asked for and what the integration is authorized to promise. If the task is to submit a job, provider acceptance might be the intended result. If the task is to create a usable CRM opportunity, acceptance alone is too early. If the task includes assigning an owner, seeing a record without the correct owner is only partial completion.
Write the condition as an observable fact. For example: “A record exists in account A, has the expected source and contact fields, and is assigned to owner B.” This does not guarantee that the opportunity will convert or that the data is true. It defines the boundary of this particular task.
The evidence must match that condition. A job receipt can show that a request was accepted. A terminal job status can show what the provider reports about processing. A readback can show the fields visible in the external system at the time of the read. Each answers a different question. A signature or well-formed event envelope can help establish who sent a message and whether it changed in transit, but it cannot by itself establish that the reported business fact is true.
The W3C PROV overview describes provenance as information about entities, activities, and people involved in producing data or an object. It says such information can support assessments of quality, reliability, or trustworthiness. That is useful vocabulary for recording what produced a result; it is not a guarantee that a claimed result is correct. (W3C PROV Overview, section 1)
Model the outcome, not just the call
For an asynchronous provider operation, keep the transport response and task state separate. A practical state model can be small:
- Pending: the provider accepted work, but no terminal result is known.
- Complete: evidence meets the task’s defined acceptance condition.
- Failed: evidence shows the operation did not meet that condition.
- Unknown: available evidence cannot distinguish completion from failure.
- Partial: some requested effects occurred, but at least one acceptance condition did not.
These are proposed application states, not HTTP status codes or a claim about every provider’s vocabulary. A provider may expose queued, running, succeeded, canceled, or other states. Map its documented states into your own vocabulary without erasing distinctions the user needs.
| Event or evidence | What it establishes | What it does not establish | User-facing state |
|---|
| Client sends request; connection ends before response | The client attempted a request | Whether the provider received or acted on it | Checking; do not claim failure or completion |
Provider returns 202 with a job reference | The request was accepted for processing | That processing finished or will finish | In progress |
| Provider callback reports rejection | The provider reported a failed job | Whether a prior side effect occurred, unless its contract answers that | Failed or needs review |
| Provider callback reports success | The provider reported a successful job | That the required record fields still match, unless the contract defines that as success | Checking, or complete if this is the accepted contract |
| Readback finds the expected record and fields | Those values were visible through that read path at that time | Future availability, user approval, or business value | Complete for the stated acceptance condition |
| Timeout, expired status link, or lost callback | The integration lacks a current result | That the operation failed | Unknown; reconcile before retrying |
The table is a synthetic design aid, not a report of observed Armalo or provider behavior. Change its rows to match the provider’s official contract and the actual task. In particular, decide whether the provider’s terminal “success” status is enough or whether the task requires an external readback.
Callbacks and readback answer different questions
A callback (often called a webhook) can reduce delay: the provider sends a message when a job changes state. But a callback path introduces its own operational conditions. The receiver might be down, the message might arrive later than expected, or the same notification might be delivered more than once. Those are failure cases to design for, not claims that every provider behaves this way.
Make callback handling safe to repeat. Store the provider event identifier when one exists, validate the sender according to provider documentation, and make state transitions idempotent. An old “processing” event must not move a task backward after a newer terminal state. Keep the event and the provider’s event time or sequence data when available, but do not treat event order as authoritative unless the provider documents it.
Readback is a separate query to the external system. If the provider offers a documented way to retrieve the job or resulting object, use that path to reconcile a missing callback or uncertain response. A readback is only as strong as its scope and timing: check the right tenant/account, object identifier, fields, and consistency guarantees. A stale replica or a partial response may not prove the intended change. If no reliable readback exists, keep the result unknown or ask for human review; do not manufacture certainty from a timeout.
Reconciliation should have an owner and a bounded schedule. For example, an integration may check a job after a short delay, repeat a limited number of status reads with increasing intervals, then surface “still checking” and route the case to a named operator. The interval and retry count are design choices to set from the provider’s rate limits, expected processing time, and business urgency. They are not universal constants.
A timeout is not permission to repeat blindly
Suppose the client sends a create request, the provider creates the record, and the response is lost before the client sees it. Retrying with a new request can create a duplicate. Conversely, refusing every retry can leave a task incomplete when the original request never arrived. The missing response leaves both possibilities open.
Use the provider’s documented idempotency mechanism when it supports the operation. Idempotency means that repeating a request under a defined key can avoid repeating the same effect within the mechanism’s rules. It is not a universal property of a tool call, and it does not mean “retry anything forever.”
Stripe’s API documentation is one provider-specific example. It says Stripe saves the first result for an idempotency key and returns that same status code and body on later requests with the key, including 500 responses. It also says keys can be pruned after they are at least 24 hours old; reusing a pruned key creates a new request. Stripe saves a result only after endpoint execution begins, so validation failures and concurrent conflicts that prevent execution are not saved in the same way. Those limits are Stripe’s documented behavior, not a promise about another provider. (Stripe, “Idempotent requests,” persistence and pruning sections)
Before retrying, ask in order:
- Does this provider support idempotency for this exact endpoint and method?
- Does the key identify this same intended action and exact parameters?
- Is the key still within the provider’s retention window?
- Can a status lookup or readback resolve the result without issuing another write?
- If the result remains unknown, who can decide whether another attempt is acceptable?
Do not reuse a key for a materially different action. Do not assume an idempotency key prevents duplicate effects across separate systems, endpoints, or expired retention windows. If the provider has no suitable mechanism, design a deduplication key or human recovery step where the provider’s data model allows it, and document the residual risk.
When the counterargument is right
Some APIs complete an operation synchronously and return a response whose documented semantics are sufficient for the requested task. RFC 9110, for example, defines 204 No Content as indicating that the server successfully fulfilled the request and has no additional response content. (RFC 9110, section 15.3.5) If an API’s contract says that this response means the exact requested record update is complete, and that is the task’s acceptance condition, an immediate success report can be reasonable.
This counterargument changes the recommendation: do not add a second read to every tool call by default. Extra polling adds latency, load, and more failure paths. First inspect the endpoint’s documented semantics. Use further evidence only when the task’s acceptance condition exceeds what the response contract guarantees, when the response is asynchronous, or when there is a material reason to verify the resulting state.
Even a synchronous response has boundaries. It might mean the provider accepted a command, stored a resource, or completed a change only within one subsystem. The response does not establish unrelated facts such as whether a human approved the result, whether a downstream process ran, or whether the change created business value. Ask the API contract the narrow question it can answer, then ask the business acceptance condition what remains.
What to tell the user
The wording should track the evidence, not the optimism of the agent:
- Pending: “The provider accepted the request. I’m waiting for its result.”
- Unknown: “I can’t confirm whether the provider completed it yet. I’m checking before retrying.”
- Failed: “The provider rejected the request because a required field was missing. Nothing is marked complete.” Use the final sentence only if the provider’s contract or readback supports it.
- Partial: “The record was created, but the owner assignment could not be confirmed.”
- Complete: “The opportunity is in the CRM with the requested fields and owner.” Use this only after evidence meets the defined condition.
These are wording patterns for the synthetic scenario. Adapt them to the actual provider result and avoid stating that nothing happened when the outcome is unknown. “Done” should be a claim a user can inspect, not a synonym for “the tool returned.”
A short implementation checklist
Before you connect an agent to a write-capable tool:
- Write the user’s requested result as an external, observable condition.
- Read the provider documentation for accepted, terminal, and error responses on the exact endpoint.
- Record which response or readback proves each part of the condition.
- Keep
pending, complete, failed, partial, and unknown distinct in storage and in the interface.
- Treat timeouts as unknown. Reconcile through a documented status or readback path before creating another write.
- Apply idempotency only under the provider’s stated key, parameter, endpoint, and retention rules.
- Make callback handling repeat-safe; preserve enough event context to explain later state changes.
- Set a retry and escalation owner. Stop automatic retries when evidence cannot safely distinguish “not done” from “done but not observed.”
- Review the words shown to customers against each state. Never display completion merely because a request was accepted.
A compact completion scorecard
Track these measures for each write-capable workflow. Set provider timing thresholds from the provider’s documented processing window, status retention, and rate limits. Set customer deadlines from the workflow’s business impact and support capacity. The triggers below are operating rules, not measured Armalo results.
| Measure | Threshold or trigger | Action | Owner |
|---|
| Completion claims without the stated acceptance evidence | Any task enters complete before its acceptance condition is evidenced | Block the completion transition; review the state mapping and customer wording before resuming | Integration owner |
Age of tasks in unknown | Reconciliation exceeds the provider’s documented status window or the workflow’s customer deadline, whichever arrives first | Stop automatic writes; notify the recovery owner and resolve through a documented read path or human review | Workflow operator |
| Required-field disagreement between provider terminal status and readback | Any required field differs or cannot be checked | Keep the task partial or unknown; investigate provider semantics and correct only with authorized action | CRM/workflow owner |
| Duplicate external effects linked to one task | Any duplicate object or repeated effect is confirmed | Disable the unsafe retry path, reconcile affected objects, and review idempotency scope and retention | Integration owner |
For lower-impact measures such as median reconciliation time or operator effort, collect a baseline before setting a target. Choose that target from the customer deadline and the value of resolving the task; do not copy a threshold from an unrelated workflow. A scorecard is useful only if each threshold leads to an owner and a concrete state change.
What may change as agent integrations expand
If more agent workflows add asynchronous writes to CRMs, ticket queues, or document stores, teams will need to define completion at the provider boundary rather than infer it from a tool response. The practical burden will depend on each provider’s contract: durable job identifiers, queryable terminal states, readable external records, and documented retry rules can make reconciliation clearer; absent those features, integrations must preserve uncertainty and assign a recovery owner. Better status APIs may reduce polling, but they do not change what a particular response proves. This is a conditional design forecast, not a claim about current adoption or a measured market trend.
FAQ
Does every 2xx response mean the task is finished?
No universal rule answers that. The 2xx class means a request was successfully received, understood, and accepted under HTTP semantics, while each status code and method has more specific meaning. 202 explicitly says processing has not completed. For other responses, read the endpoint contract and compare it with the business condition you need to establish.
Is a provider’s “succeeded” callback enough?
It can be enough if the provider documents what “succeeded” means and that meaning matches the user’s requested result. If the task requires specific fields, a particular account, or a downstream effect not covered by that status, check those facts separately. Keep the callback as evidence of the provider’s report, not an unbounded guarantee.
Should an integration always read the object back?
No. Readback is useful when it resolves a real evidence gap. It can add cost and delay, and it can return stale or incomplete information. Use it when the response contract is weaker than the task’s acceptance condition or when uncertainty has material consequences.
What should the interface show after a timeout?
Show “checking” or “outcome unknown” while a documented reconciliation step runs. A timeout describes what the client observed; it does not prove what the provider did. Retry only when the provider contract makes that retry safe or an accountable person accepts the risk.
How does this relate to the Armalo Layer?
Armalo Layer is a proposed responsibility model for connecting an agent’s authority, work, evidence, and consequences. This article applies one narrow part of that proposal: connect a claimed completion to evidence that matches the requested result. For the wider technical mapping, see Trust Infrastructure for AI Agent Platforms: A Technical Mapping of the Armalo Layer. Armalo Layer remains a proposal, not an established standard, and this article does not claim that Armalo already implements every mechanism described here.
The final check
Before an agent says “done,” ask one question: What final external fact did the system check, and does that fact satisfy the user’s request? If the answer is “the tool returned success,” inspect what that response means. If the answer is “we do not know yet,” report uncertainty and reconcile it. That small distinction keeps an accepted request from masquerading as completed work.
Sources
- Roy T. Fielding, Mark Nottingham, and Julian Reschke, RFC 9110: HTTP Semantics, June 2022. Sections 15.3.3 (
202 Accepted) and 15.3.5 (204 No Content).
- World Wide Web Consortium, PROV-Overview: An Overview of the PROV Family of Documents, Working Group Note, 30 April 2013. Section 1.
- Stripe, Idempotent requests, provider documentation, accessed 24 September 2026. “Idempotent requests,” result persistence, key pruning, and execution-start conditions.