Skip to main content
A disposition is a set of values you want Sempera to produce from every finished phone call of an agent: “did the caller book”, “which service”, “the callback number”. You define the values, price the definition, publish it, and test it against real calls on your own schedule. From then on every new completed phone call runs the published version, and the result arrives on the call.outcomes webhook event (Webhooks).

Conventions

These are /v2 compatibility routes (API overview) under /v2/agents/{agent_id}/dispositions, where {agent_id} is the Sempera agent id. An agent the credential cannot read answers 404 like one that never existed. Answers use the compatibility envelope {"data": ..., "errors": null}. A refusal these routes make is {"data": null, "errors": [{"error", "message"}]} with error one of BAD_REQUEST (400), NOT_FOUND (404), CONFLICT (409), TOO_MANY_REQUESTS (429) or SERVICE_UNAVAILABLE (503). A missing credential, scope or role gets the standard error envelope (Errors and limits). Every body field is checked; an unknown field is refused. GET /v1/dispositions/ is a placeholder that always answers 403; use the per-agent routes.

Routes

A disposition reads id, agentId, key, state (enabled or disabled), publishedVersionId, publishedVersionNumber, draftRevision, draftValueCount, hasUnpublishedChanges, name, description, createdAt, updatedAt and deletedAt. key is 1 to 64 lowercase letters, digits and underscores, starting with a letter, and unique among the agent’s live dispositions.

The definition

A value schema has a kind: boolean, string (optional format: "date-time"), number, enum (options: 1 to 24 of {"key", "label"}), array (items, optional minItems and maxItems up to 1000) or object (properties, up to 64, and required). Any schema may carry a description. At most 8 levels, 200 nodes and 64 KB. A value source says how the value is produced: A source may add "execution": {"reasoningEffort": "auto", "inputSourceIds": ["transcript"]}. Sempera reads the call transcript with one setting, so any other effort or input source is refused.

Estimate and publish

POST .../estimates answers a quote: id, draftRevision, perValue (each value’s executionPath, token volumes and usdPerCall), totalUsdPerCall (min, expected, max) and the assumptions behind it. The id is a digest of exactly what would run and how it is priced. Publish with that id and the draft revision you estimated; if anything changed since, publish answers 409 and you estimate again. acknowledgeEstimate: true is required when the expected cost per call is above zero. Publishing needs at least one value, freezes a copy of every pinned extractor version and judge wording into the version (a later edit never changes a published version), enables the disposition, and answers the version: id, versionNumber, definition, publishedAt.

On live calls

Every enabled disposition with a published version runs on every new completed phone call of the agent, after the call’s outcomes are captured. Previews, typed tests and simulations never run it, and a version published after a call ended never runs on that call. The call.outcomes event then carries dispositions: one entry per disposition with its status, values and the payload the transformation assembled. When no model is reachable a value is stored not_evaluated rather than guessed; Sempera reads it again when a model is back, within a day of the call, and sends the event again.

Test runs and corrections

A run body is {"target": "draft" | "published", "population": {...}, "executionSla": "realtime" | "queued"}; executionSla defaults to realtime for a disposition whose timing is immediate and queued for within_24h. population may carry environment, which can only be production, and is {"mode": "recent", "requestedSize": 1 to 250} (default 20 of the agent’s most recent finished calls with a transcript) or {"mode": "calls", "callIds": [...]} (1 to 250 ids). {"replayRunId"} instead replays a finished run over the same frozen definition and calls. At most 3 runs of one agent may be queued or running (429). A run’s status is queued, running, complete, partial or failed; with no model reachable it fails and says so. Paging numbers on runs and rows are pulled into range rather than refused. A correction is {"state": "produced", "value": ..., "explanation": "..."} or {"state": "no_value", "explanation": "..."}. The explanation is 40 to 4000 characters, the value must fit the value’s frozen schema, and the run must be finished (409 otherwise). Corrections are append-only revisions; the engine’s own result is never changed. Align takes an optional {"valueIds": [...], "instructions": "..."} (1 to 50 ids, up to 2000 characters) and answers proposals (each value’s changes: field, before, after, rationale), skipped with a reason, and truncatedCorrections. It needs a finished run with at least one correction (409 DISPOSITION_ALIGN_NOT_READY), a reachable model (503), and allows 30 requests per workspace per hour (429). You apply a proposal yourself, or not.

Extractors

An extractor is a reusable, versioned reader a structured_extraction value pins: a task prompt, an optional system prompt, the output schema and how it is read. It belongs to the workspace and is either workspace-wide or scoped to one agent; its key is unique in the workspace. promptMd is required and up to 8000 characters and 8000 UTF-8 bytes, so text with many multi-byte characters is refused sooner; systemPromptMd has the same cap, and the pair is at most 16000 bytes. outputSchema follows the value schema rules. inferenceConfig is {"contextSources": ["transcript"], "modelProfileKey": "balanced", "temperature": 0 to 2, "maxOutputTokens": 1 to 64000}; only contextSources is required, and any other source, profile or thinking setting is refused. An extractor always has one editable version; publishing freezes it as the active version (its state reads archived, meaning frozen) and opens the next number for editing. A disposition that pinned an earlier version keeps it.