---
title: "Replace an agent's call variables, SMS templates and caller lookup"
method: PUT
path: "/v1/agents/{agent_id}/variables"
---

# Replace an agent's call variables, SMS templates and caller lookup

`PUT /v1/agents/{agent_id}/variables`

## Request

- Base URL: `https://api.skysay.ai`
- URL: `https://api.skysay.ai/v1/agents/{agent_id}/variables`
- Auth: none declared

A full replace. The config is checked by the publish lint and republished into the agent's language profiles in the same transaction, so the next call is admitted against it; calls already admitted keep what they were admitted with. For an agent with an active workflow the config carries only sms_mode, sms_templates and caller_lookup: its variables are the workflow's. Protected fields need a workflow agent and a confirmation method; live engines (GPT-Live, Gemini Live) cannot hold them.

## Path parameters

- `agent_id` string, required

## Request body

- AgentVariablesUpdate
  - `base_revision` integer: The revision this edit was based on. When sent and stale, the write is refused with 409 revision_conflict. Omit for last-write-wins.
  - `config` VariablesConfig, required: An agent's call variables, SMS templates and caller lookup. Exported from config_schema.py (the API's copy; tests pin the two equal) for the dashboard and the docs. tests/fixtures/call_variables/config_cases.json is the accept/reject contract.
    - `caller_lookup` object, nullable
      - `contact_list_id` string, required
    - `sms_mode` 'free_text' | 'templates_only'
    - `sms_templates` object
    - `variables` VariablesConfigVariables
      - `fields` object, required
      - `version` unknown, required

## Response `200`

The config as stored and published

- AgentVariables
  - `agent_id` string, required
  - `config` VariablesConfig, required: An agent's call variables, SMS templates and caller lookup. Exported from config_schema.py (the API's copy; tests pin the two equal) for the dashboard and the docs. tests/fixtures/call_variables/config_cases.json is the accept/reject contract.
    - `caller_lookup` object, nullable
      - `contact_list_id` string, required
    - `sms_mode` 'free_text' | 'templates_only'
    - `sms_templates` object
    - `variables` VariablesConfigVariables
      - `fields` object, required
      - `version` unknown, required
  - `published_at` string, required: When the current publication was made; empty before the first.
  - `revision` integer, required: The agent's latest published language-profile version; send it back as base_revision. Any publish of the agent moves it. 0 before the agent is first published.
  - `schema_hash` string, required: sha256 of the variable schema a call admitted now would carry; empty when the publication declares none a call could be admitted with.

## Other responses

- `400`: {error: 'variables_config_invalid', message, issues: [issue]}: the config fails the publish lint.
- `404`: Agent not found
- `409`: {error: 'revision_conflict', message, revision}: base_revision is stale. Or {error: 'workflow_revalidation_failed', message, issues}: the change would let the agent's active workflow say a protected value before the caller is confirmed.

---

[API](https://skmtc.dev/skysay/apis/skysay-api.md) · [All operations](https://skmtc.dev/skysay/apis/skysay-api/llms.txt) · [OpenAPI document](https://skmtc.dev/skysay/apis/skysay-api/revisions/95b8c66f99aa?raw)
