Skip to main content
The feedback contract is a compact JSON object that Agent Feedback embeds in every eligible product response. It tells a capable agent exactly where to submit an outcome, how to authenticate, which values are accepted, and what privacy constraints apply — all without any out-of-band configuration. The SDK builds this object locally, signs a short-lived capability token, and injects it before the response leaves your server. Your product response never waits for any network call to Agent Feedback.

Embedding methods

The SDK chooses an embedding method based on the response’s content type and structure.

JSON field

For eligible 2xx JSON responses that contain a plain object at the top level, the SDK appends _agentFeedback directly to that object. No wrapping, no restructuring — existing fields are untouched.

HTML script tag

For HTML responses, the SDK injects a <script id="agent-feedback" type="application/json"> element before </head> (or </body> if no </head> is present). The contract is the same JSON object as the field variant.

Header fallback

For arrays, scalars, and other bodies that cannot be modified safely, the SDK uses Agent-Feedback: <base64url> for the encoded contract and a Link header to aid discovery.

Envelope shape

Every instrumented response carries an envelope with this structure:

Envelope fields

number
required
Protocol version. Always 1 for v1 envelopes.
string
required
Either "auto" or "ask". In auto mode, the instruction directs the agent to submit autonomously without prompting the human user. In ask mode, the instruction is conditional — the agent only submits if the outcome is already known.
boolean
required
true when mode is "auto", indicating an unconditional submission request. false when mode is "ask".
string
required
Always "best_effort_without_agent_adapter" for HTTP surfaces. This signals to feedback-aware runtimes that the contract is present but that non-instrumented agents may ignore it.
string
required
Always "after_outcome_known_before_final_response". This instructs the agent on the correct timing: submit the review after it has used the product response and determined the outcome, but before it writes its final response to the human.
string
required
A human-readable (and agent-readable) directive that explains exactly what to do. Between 1 and 1000 characters.
object
required
The submission descriptor. Contains everything an agent needs to POST an outcome without reading any external documentation.
string
required
The HTTPS outcomes endpoint. Always starts with https://.
string
required
Always "POST".
string
required
The Bearer afr2_... capability token. This is a short-lived, scoped credential — not your product key. See Capability Tokens for details.
string
required
Always "application/json".
object
required
Describes the allowed outcome fields.
array
required
The three permitted outcome values: "success", "partial", "failure".
string
required
Instructions for the note field. Up to 500 characters. Directs the agent not to include user data in its submitted note.
string
required
A machine-readable privacy directive reminding the agent not to include prompts, transcripts, credentials, personal data, or raw product content in the submission.
string (ISO 8601)
required
The UTC timestamp at which the capability token — and therefore the entire contract — expires. The window is at most two hours from the time the response was served.

Excluded responses

The SDK never instruments a response that falls into any of the following categories:
  • Error and redirect responses — any non-2xx status code
  • Health and metrics endpoints/health, /healthz, /metrics, and similar
  • Asset files/favicon.ico, /robots.txt, and static file paths
  • Streaming or binary bodies — responses where the body cannot be safely parsed or modified
  • Agent Feedback’s own endpoints/_agent-feedback/* and /api/v2/outcomes are never self-instrumented

Cache behaviour

Every instrumented response receives Cache-Control: private, no-store. This is required because each capability token is unique to a single interaction — caching an instrumented response would cause multiple agents to receive the same scoped token, which the backend would reject on the second use.

Existing fields are preserved

If your application already includes a field named _agentFeedback in a JSON response body, the SDK detects it and skips injection entirely. Your existing value is never overwritten.
If you are building a custom integration or validating envelope output, the canonical schema lives at protocol/v1/envelope.schema.json in the Agent Feedback repository and is the source of truth for all SDK implementations.