Publish Agent For Runs

Beta
Publish an agent's current configuration for durable runs. The configuration a run executes is live as soon as it is written, so this promotes nothing. What a publish does is submit the configuration to the workspace's publish gates and record the decision against a fingerprint of that configuration. On a gated workspace a run will only start against a configuration that carries a passing (or overridden) decision, so this is the step that makes an agent runnable after it is created or edited. Any agent publishes here. The conversations it answers are versioned separately, by promoting a flow version via `/v1/agents/{agent_id}/flow/publish`. On an ungated workspace this succeeds and returns no `gate` object. This endpoint is in beta: the gate runs on workspaces granted `publish_eval_gate` **or** `red_team_publish_gate`, and the second is enabled automatically for every workspace granted `durable_runs_access` - so if you can start durable runs, you are gated and this call is a prerequisite, not an option. The runs a publish authorises need `durable_runs_access` too (the run endpoints answer `402 durable_runs_not_in_plan` without it).

Authentication

AuthorizationBearer

Enter your API key with the Bearer prefix, e.g. ‘Bearer sk_…’.

Path parameters

agent_idstringRequired
Prefixed agent id.

Headers

Speechify-VersionstringOptional
Idempotency-KeystringOptional<=255 characters
A client-generated key (an opaque string, max 255 chars) that makes a side-effect POST safe to retry: the server runs the operation exactly once and replays the first response (its status and body) for 24 hours. Reusing a key with a different request body, or while the first request is still in flight, returns `409 idempotency_conflict`. A replayed response carries the `Idempotent-Replayed: true` header.

Request

This endpoint expects an object.
gate_override_reasonstringOptional>=10 characters

On a gated workspace, a non-empty justification publishes past failing checks. The suite still runs and its verdict is recorded with this reason - an override bypasses blocking, not measurement. Must be at least 10 characters after trimming.

Response headers

Speechify-Request-IdstringOptional
Unique identifier for this request, present on every response (2xx and non-2xx alike). If the caller sends a `Speechify-Request-Id` request header the server echoes it back (sanitized and length-capped) so one logical request can be traced end-to-end; otherwise the server generates a fresh value. Log it on every response and quote it in support requests - it is the stable handle that ties your observation to Speechify's server-side logs, and it matches the `request_id` field in the error envelope. The legacy alias `X-Request-ID` carries the same value and is still accepted on requests, until 2027-07-24. Prefer the un-prefixed name (RFC 6648).

Response

The published configuration, with the gate outcome when gated.
agent_idstringformat: "^agent_[0-9a-hjkmnp-tv-z]{26}$"
The agent that was published.
config_fingerprintstring

Identifies the exact configuration this decision covers. A run is admitted only against a fingerprint carrying a passing (or overridden) decision, so any edit that changes the agent’s behavior produces a new fingerprint and requires publishing again.

published_atdatetime
When the configuration was published.
gateobjectOptional
The gate outcome. Absent when the workspace is not gated, in which case nothing was scored and runs are admitted without a gate check.

Errors

400
Bad Request Error
401
Unauthorized Error
403
Forbidden Error
404
Not Found Error
409
Conflict Error
422
Unprocessable Entity Error
500
Internal Server Error
503
Service Unavailable Error