Skip to Content
API referencePOST /v1/observe/actions

POST /v1/observe/actions

The Observe Mode relay. It is deliberately separate from POST /v1/actions and the rest of the governed pipeline: this endpoint runs only for trial agents on an ephemeral, unclaimed organisation, relays a call to a vetted platform using a credential you supply per call, and writes one metadata-only audit row. See Observe Mode for the concept.

This route applies no policy. It doesn’t check scopes and it can’t hold a call for approval: it either relays or fails closed on a precondition. If you need governance (scopes, approval, revocation), use /v1/actions on a real agent.

Request

POST /v1/observe/actions HTTP/1.1 Host: api.agentvalet.ai Authorization: Bearer <trial-agent-rs256-jwt> X-AV-Observe-Credential: <your-platform-api-key> Content-Type: application/json
{ "platform": "github", "endpoint": "/user", "method": "GET", "action": "github.user.read" }
FieldTypeRequiredNotes
platformstringyesPlatform id from the catalog (e.g. github, slack, stripe). Must have a vetted observe_base_url; not every platform is relayable
endpointstringyesPath relative to the platform’s vetted base URL. Absolute URLs, protocol-relative URLs, and .. path traversal are rejected
methodstringyesGET / POST / PUT / PATCH / DELETE
actionstringnoA label for the audit row. Defaults to observe.relay
bodyobjectnoRequest payload forwarded upstream (ignored for GET)
headersobjectnoExtra headers forwarded upstream

The credential itself never goes in the body. It goes on the X-AV-Observe-Credential header, is applied to the upstream Authorization header in memory, and is never written to the audit row, a log, or storage.

Success

The upstream response is relayed back with its original status code and body, unwrapped (there is no discovery envelope, unlike /v1/actions).

Error codes

StatuserrorCause
400Missing X-AV-Observe-Credential headerNo credential header on the request
400platform, endpoint, method are requiredBody missing a required field
400endpoint_blockedThe endpoint escapes the platform’s vetted base URL, or resolves to a private/link-local/metadata host
400unsupported_auth_typeThe platform’s catalog auth_type isn’t one Observe Mode knows how to apply (api_key, oauth, basic)
401Missing Bearer token / Invalid JWTNo or invalid agent JWT
403observe_mode_requiredThe agent isn’t in observe mode on an ephemeral org; this route refuses to run for any other agent
403platform_not_relayableThe platform has no vetted observe_base_url in the catalog
429Too many observe calls. Slow down or sign up.Per-trial rate limit (60 calls/minute)
502Upstream request failedThe platform returned an error or the call timed out
503Observe Mode is at capacity. Please sign up.The global cap across all trials is exceeded (OBSERVE_GLOBAL_CAP, default 1000/minute)

Every one of these outcomes, including the failures above, writes an audit row: denied for the precondition and validation failures, observed for a completed relay (any upstream status, including upstream errors).

Audit

Every call writes one row to audit_log with:

  • result = observed (relay completed, any upstream status) or denied (precondition/validation failure)
  • action = your action field, or observe.relay
  • scopes_used = null (Observe Mode does not use scopes)
  • metadata = platform, endpoint, method, action, status, latency_ms, request_size, response_size; no request or response body, and the credential value is redacted wherever it would otherwise appear

Response bodies are capped at 1 MB read from upstream and are not persisted regardless of size. Read Observe Mode for the full retention and containment story.

Next

  • Observe Mode: the concept, the containment invariants, and the try flow
  • POST /v1/actions: the governed action proxy this route intentionally does not touch
Last updated on