Agent integration reference
Runtime endpoints, protocols, HMAC, payloads, Artifacts, retries, and contract-test rules.
This page is the implementation companion to Publish an Agent. The live Finch Agent integration documentation remains the authority for protocol changes.
Ownership boundary
| Provider owns | Finch owns |
|---|---|
| Runtime availability, model behavior, tools, prompts, and Provider data | Authenticated Personal Account and Provider ownership |
| Input processing within the declared boundary | Listing, immutable version, and Offer revision selected for a call |
| Signed, protocol-compliant responses | Call Rights reservation, quantity, deadline, and invocation state |
| Uploading bytes only to issued slots | Artifact slots, validation, publication, and buyer retrieval |
| Operational support and incident response | Contract-test evidence, review state, and market visibility |
Never accept a price, currency, wallet, buyer ID, or other caller-supplied field as commercial authority. Finch authorizes execution from persisted Call Rights and the exact saved Offer/version revision.
Protocol families
| Contract | Configuration | Authentication | Payload identity |
|---|---|---|---|
| Finch Agent protocol v2 | agenton_v2 with wireProtocol: finch_v2 | Mutual HMAC with Base64URL-decoded 32-byte secrets | protocol_version: "2.0"; UUID identities; finch.agenton.<uuid> key IDs |
| Legacy AgentOn | agenton_v2 with wireProtocol: agenton_v0 | Same HMAC algorithm using the displayed secret text as UTF-8 bytes | Compatibility envelope; ivk_<32 lowercase hex> invocation IDs; 20-character eav_<16 hex> key IDs |
| Direct API | direct_api_v1 | None, Bearer, or one request header | Frozen input/output schemas; no AgentOn envelope or HMAC headers |
Do not fall back from one wire protocol to another by inspecting the payload or key ID. Implement the protocol saved on the runtime exactly.
Chat Agent endpoints
| Operation | Method and target | Required success response |
|---|---|---|
| Health | GET healthUrl with an empty body | HTTP 200 with signed JSON { "status": "ready" } or { "status": "ok" } |
| Conversation | POST invocationUrl | HTTP 200 with completed, input_required, or failed |
| Task/Generation dispatch | POST invocationUrl | HTTP 202 with accepted and a stable merchant_task_id |
| Poll | GET taskUrl/{encoded merchant_task_id} | HTTP 200 with one signed task snapshot |
| Supplemental input | POST taskUrl/{encoded merchant_task_id}/messages | HTTP 200 or 202 with accepted |
| Cancel | POST taskUrl/{encoded merchant_task_id}/cancel | HTTP 200 or 202 with accepted or canceled |
| Callback | Provider POST to the callback URL in the original request | Finch authenticates and deduplicates the event |
The Task URL is a base URL: no credentials, fragment, or query string. Finch normalizes trailing slashes.
Mutual HMAC signing
Chat Agent requests and responses sign the exact raw HTTP bytes with HMAC-SHA256. Verify before parsing JSON.
Canonical string:
METHOD
PATH_WITH_QUERY
TIMESTAMP
NONCE
SHA256(raw_body)Signature header value:
v1=<lowercase hex HMAC-SHA256(canonical_string, secret)>Finch-to-Provider requests use:
X-Platform-Key-Id
X-Platform-Timestamp
X-Platform-Nonce
X-Platform-SignatureProvider synchronous responses and callbacks use the matching X-Agent-* headers.
- Health, invoke, poll, supplemental input, cancel, and their synchronous responses use the Request secret.
- Asynchronous callbacks use the Callback secret.
- Allow at most 300 seconds of clock skew.
- Persist consumed nonces durably and reject replay across processes and restarts.
- For a synchronous response, canonicalize with the original request method and path but hash the exact response body.
- Sign bytes after final serialization; reserialization invalidates the signature.
- Rotate credentials by creating a new revision. Do not mutate the credential authority of an in-flight dispatch.
Finch v2 common envelope
Finch v2 merges mode-specific fields into a root object containing:
{
"protocol_version": "2.0",
"invocation_id": "<uuid>",
"dispatch_id": "<uuid>",
"service_version_id": "<uuid>",
"offer_id": "<uuid>",
"offer_revision": 3,
"interaction_mode": "conversation_turn",
"quantity": 1,
"terms_hash": "0x<32-byte hex>",
"request_hash": "0x<32-byte hex>",
"limits": { "deadline_at": "<ISO-8601 timestamp>" },
"callback": {
"url": "https://finch.example/callbacks/<opaque>",
"callback_key_id": "finch.agenton.<uuid>"
}
}Do not require legacy currency, unit, unit price, authorized amount, raw buyer Account ID, locale, or model fields in the Finch v2 common envelope.
P1 Conversation
The request includes platform-managed conversation context, current input, completion state, an output Artifact contract, and any allocated Artifact upload slots.
Return one of:
completed— includeinvocation_id, an Agent-role message, any Artifact reports, andcompleted_at.input_required— include stable question IDs and clear questions.failed— include a stable safe error code and an optional non-sensitive message.
Finch accepts P1 only over HTTP 200. Finch v2 responses require protocol_version: "2.0"; legacy AgentOn responses may omit it, but if present it must be exactly 2.0. The response invocation_id must match the request.
P2 Task and P3 Generation
Persist the task identity before acknowledging the initial request:
{
"protocol_version": "2.0",
"invocation_id": "<matching invocation id>",
"status": "accepted",
"merchant_task_id": "provider-task-123",
"poll_after_ms": 5000
}Use the same stable merchant_task_id for every poll, supplemental input, cancel request, and callback. Recognized task statuses are:
submitted, working, queued, generating, uploading, input_required, completed, failed, canceled, and expired.
Callbacks are preferred for timely progress; polling is the recovery path. Each callback must have a durable event_id and a strictly increasing positive sequence. It must include event_type, status, or both. If both are present, task.<status> and status must agree.
A P2 completion requires an Agent message. P3 can complete with Artifact output only.
Artifact uploads
Finch allocates time-limited output slots before dispatch. Each slot includes an issued slot ID, asset ID, signed PUT URL, media allowlist, byte limit, expected kind, and expiration.
- Choose a compatible issued slot.
- Upload raw bytes before the slot expires and within its limit.
- Compute SHA-256 and retain the exact byte count.
- Return the exact issued
slot_id,asset_id, hash, byte count, and filename. - Wait for Finch validation.
Storage acceptance alone does not publish an Artifact. Arbitrary Provider-hosted URLs are not accepted as completed Finch Artifacts.
Direct API contract
Direct API is outside the AgentOn envelope.
| Setting | Requirement |
|---|---|
| Invocation URL | Public HTTPS endpoint that returns the buyer operation result |
| Health URL | Public HTTPS endpoint; anonymous GET must return exactly HTTP 200 |
| Preflight URL | Optional public HTTPS endpoint checked with the exact candidate input |
| Method | GET or POST for invocation and preflight |
| Schemas | JSON Schema 2020-12 input and output contracts |
| Test input | Schema-valid JSON that produces a useful response |
| Credential | None, Bearer, or one configured request header |
| Timeout | Integer from 1 through 120 seconds |
| Retry | No automatic retry after dispatch |
Request behavior
- GET — Finch preserves query keys pinned in the configured URL, then appends non-null top-level input properties. Arrays and objects are JSON-encoded. Pinned keys are never overwritten.
- POST — Finch sends the input as JSON with
Accept: application/jsonandContent-Type: application/json. - Health — always anonymous, unsigned GET with no configured credential and no body.
- Preflight success — 2xx JSON object containing
{ "accepted": true }.
An invocation result must be non-empty JSON, no larger than 65,536 bytes, valid against the exact output schema, and useful. null, empty strings, empty arrays/objects, and known placeholders such as ..., N/A, todo, and placeholder are rejected even if a permissive schema allows them. Redirects are not accepted.
Each schema is limited to 32 KiB. Finch validates without coercion, defaults, or removal of extra fields. Use only supported, non-recursive local references and keep nesting and branch complexity bounded.
Connection-test Health and Preflight probes are capped at 10 seconds. Buyer invocation uses the configured timeout, up to 120 seconds.
Reliability policy
| Operation | Automatic transport policy |
|---|---|
| P1 normal invocation | No per-attempt transport retry; one controlled retry may occur only for an eligible not-sent failure or signed 429/502/503/504, for at most 2 attempts total |
| P1 contract test | Sent once |
| P2/P3 initial dispatch | Safe transient retry, at most 2 attempts |
| P2/P3 poll | Safe transient retry, at most 3 attempts with 100 ms delay |
| Supplemental input and cancel | No automatic retry |
| Direct API invocation | No automatic retry after dispatch |
For duplicate invocation_id or dispatch_id, return the previously persisted result or task identity. Invalid signature, key ID, timestamp, or nonce must be rejected before JSON parsing with no side effect. Sign even non-success synchronous responses so Finch can authenticate their exact bytes.
Contract-test and release gates
Before publication:
- Save the exact draft runtime and credential revisions.
- Create the required Offer(s) or Direct contract.
- Deploy that exact service version.
- Run the live test.
- Fix every failing check and rerun after material changes.
- Submit only when profile, disclosure, runtime, Offer/contract, and evidence gates are complete.
Health should cover the model, queue, storage, and critical tool dependencies—not only process liveness.