BrightshoalDocsOpen console
MenuAssistants

API reference

Assistants

An assistant is one agent: its instructions, model, voice, tools and channels. Every call and chat runs on an assistant, and every update creates a new version.

Create an assistant

POST/api/assistants

Creates an assistant at version 1. config needs agent.instructions and session.llm, session.stt and session.tts, each with a provider and model from the registry; everything else has a default. An org-wide key must name project_id. Validation checks the shape, not that the provider account works: place a test call or chat to be sure.

Secret API key, not read-only. How it works

Request body

  • project_idstring

    Required for an org-wide key; ignored (must match) for a project-scoped key.

  • namestringrequirednot empty

  • configAssistantConfigrequired

    The runtime profile minus per-call fields. agent.instructions and either session.realtime or the complete session.{llm,stt,tts} pipeline are required. Realtime requires provider; its model may use the runtime default. A pipeline LLM may omit provider for a LiveKit-hosted model id. Credentials are write-only: integrations.google_analytics.api_secret, channels.web_chat.analytics.ga4.api_secret and recording.s3.{access_key,secret,session_token} come back as <key>_set: boolean, and a write that omits one keeps the stored value. Chat (web or WhatsApp) answers with channels.web_chat.llm, defaulting independently to openai/gpt-6.1-sol with medium reasoning; creating or enabling web chat, or changing that model while web chat or WhatsApp routing is live, is refused with 400 when chat has no adapter for its provider.

    5 attributes
    • agentobjectrequired

      1 attribute
      • instructionsstringrequired

    • toolsAssistantTools

      Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

      1 attribute
      • definitionsarray of AssistantToolDefinition

        7 attributes
        • namestringrequired

        • descriptionstring

        • parametersobject

          JSON Schema for the arguments, as exposed to the model.

        • enabledboolean

          False keeps the tool saved, with its request, but offers it on no channel.

          Default true

        • channelsarray of string

          Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

        • read_onlyboolean

          True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

          Default false

        • requestobjectwrite-only, never returned

          Server-side HTTP execution spec, never returned on reads. A write that omits it keeps the stored spec for the same tool name; removing or renaming the tool drops it.

          4 attributes
          • urlstringrequireduri

          • methodstring

            One of GET POST PUT PATCH DELETE

          • headersobject

          • timeout_msinteger1 to 120000

    • sessionanyrequired

      5 attributes
      • llmobject

        2 attributes
        • providerstringnot empty

        • modelstringrequirednot empty

      • realtimeobject

        2 attributes
        • providerstringrequirednot empty

        • modelstringnot empty

      • sttProviderModel

        2 attributes
        • providerstringrequirednot empty

        • modelstringrequirednot empty

      • ttsProviderModel

        2 attributes
        • providerstringrequirednot empty

        • modelstringrequirednot empty

      • toolsAssistantTools

        Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

        1 attribute
        • definitionsarray of AssistantToolDefinition

          7 attributes
          • namestringrequired

          • descriptionstring

          • parametersobject

            JSON Schema for the arguments, as exposed to the model.

          • enabledboolean

            False keeps the tool saved, with its request, but offers it on no channel.

            Default true

          • channelsarray of string

            Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

          • read_onlyboolean

            True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

            Default false

          • requestobjectwrite-only, never returned

            Server-side HTTP execution spec, never returned on reads. A write that omits it keeps the stored spec for the same tool name; removing or renaming the tool drops it.

            4 attributes
            • urlstringrequireduri

            • methodstring

              One of GET POST PUT PATCH DELETE

            • headersobject

            • timeout_msinteger1 to 120000

    • variablesarray of AssistantVariableDefup to 50 items

      Authoring-time schema for {{key}} placeholders in agent.instructions, agent.context, agent.first_message, and agent.first_message_instructions; never delivered to the runtime.

      4 attributes
      • keystringrequiredup to 64 characters

      • labelstringup to 120 characters

      • descriptionstringup to 500 characters

      • defaultstringup to 2000 characters

    • knowledgeobject

      The knowledge bases the assistant answers from, by knowledge base id (kb_...). Unlike the rest of the config, leaving it out of a write keeps the stored selection; send {} to detach every base. An entry with both chat and voice false counts as detached. Changing it needs an org-wide key and editor access to each base: 403 organization_knowledge_access_required for a project key or knowledge_forbidden without editor access, 400 knowledge_base_not_found for an unknown id, 409 knowledge_voice_requires_pipeline_assistant for voice on a realtime session. Each refusal names the base in knowledge_base_id.

      3 attributes
      • chatbooleanrequired

        Search it in web chat and WhatsApp.

      • voicebooleanrequired

        Search it on calls. Needs a pipeline session, not realtime.

      • priorityintegerrequired0 to 100

        Each search reaches up to four of the attached bases that have a live publication, highest priority first (then by id), and searches them in parallel.

Returns

201 OK

Response attributes
  • dataAssistantrequired

    10 attributes
    • idstringrequired

    • org_idstringrequired

    • project_idstringrequired

    • namestringrequired

    • configAssistantConfigrequired

      The runtime profile minus per-call fields. agent.instructions and either session.realtime or the complete session.{llm,stt,tts} pipeline are required. Realtime requires provider; its model may use the runtime default. A pipeline LLM may omit provider for a LiveKit-hosted model id. Credentials are write-only: integrations.google_analytics.api_secret, channels.web_chat.analytics.ga4.api_secret and recording.s3.{access_key,secret,session_token} come back as <key>_set: boolean, and a write that omits one keeps the stored value. Chat (web or WhatsApp) answers with channels.web_chat.llm, defaulting independently to openai/gpt-6.1-sol with medium reasoning; creating or enabling web chat, or changing that model while web chat or WhatsApp routing is live, is refused with 400 when chat has no adapter for its provider.

      5 attributes
      • agentobjectrequired

        1 attribute
        • instructionsstringrequired

      • toolsAssistantTools

        Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

        1 attribute
        • definitionsarray of AssistantToolDefinition

          6 attributes
          • namestringrequired

          • descriptionstring

          • parametersobject

            JSON Schema for the arguments, as exposed to the model.

          • enabledboolean

            False keeps the tool saved, with its request, but offers it on no channel.

            Default true

          • channelsarray of string

            Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

          • read_onlyboolean

            True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

            Default false

      • sessionanyrequired

        5 attributes
        • llmobject

          2 attributes
          • providerstringnot empty

          • modelstringrequirednot empty

        • realtimeobject

          2 attributes
          • providerstringrequirednot empty

          • modelstringnot empty

        • sttProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • ttsProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • toolsAssistantTools

          Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

          1 attribute
          • definitionsarray of AssistantToolDefinition

            6 attributes
            • namestringrequired

            • descriptionstring

            • parametersobject

              JSON Schema for the arguments, as exposed to the model.

            • enabledboolean

              False keeps the tool saved, with its request, but offers it on no channel.

              Default true

            • channelsarray of string

              Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

            • read_onlyboolean

              True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

              Default false

      • variablesarray of AssistantVariableDefup to 50 items

        Authoring-time schema for {{key}} placeholders in agent.instructions, agent.context, agent.first_message, and agent.first_message_instructions; never delivered to the runtime.

        4 attributes
        • keystringrequiredup to 64 characters

        • labelstringup to 120 characters

        • descriptionstringup to 500 characters

        • defaultstringup to 2000 characters

      • knowledgeobject

        The knowledge bases the assistant answers from, by knowledge base id (kb_...). Unlike the rest of the config, leaving it out of a write keeps the stored selection; send {} to detach every base. An entry with both chat and voice false counts as detached. Changing it needs an org-wide key and editor access to each base: 403 organization_knowledge_access_required for a project key or knowledge_forbidden without editor access, 400 knowledge_base_not_found for an unknown id, 409 knowledge_voice_requires_pipeline_assistant for voice on a realtime session. Each refusal names the base in knowledge_base_id.

        3 attributes
        • chatbooleanrequired

          Search it in web chat and WhatsApp.

        • voicebooleanrequired

          Search it on calls. Needs a pipeline session, not realtime.

        • priorityintegerrequired0 to 100

          Each search reaches up to four of the attached bases that have a live publication, highest priority first (then by id), and searches them in parallel.

    • versionintegerrequired

    • draft_revisioninteger

      The revision a draft save names as expected_draft_revision; 0 before the first draft.

    • draftobject | null

      Whether a draft exists, without its config (GET /assistants/{id}/draft has it).

      3 attributes
      • revisioninteger

      • base_versioninteger

      • updated_atstringISO 8601 timestamp

    • created_atstringISO 8601 timestamp

    • updated_atstringISO 8601 timestamp

  • 400 Validation error: usually invalid_request, with the failing fields in issues when there are any
  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 403 Refused, for example a read-only key on a write (read_only_key), a role too low for the route (insufficient_role), or a route that needs a console session
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
POST /api/assistants
curl -X POST "https://api.myleadsfactory.tech/api/assistants" \
  -H "Authorization: Bearer $MLF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Front desk",
  "project_id": "proj_2f9c41d0a8b34e6f9d1c7a5b3e8f0a12",
  "config": {
    "agent": {
      "instructions": "You answer enquiries for Acme Travel. Be brief and friendly."
    },
    "session": {
      "llm": {
        "provider": "openai",
        "model": "gpt-4o-mini"
      },
      "stt": {
        "provider": "deepgram",
        "model": "nova-3"
      },
      "tts": {
        "provider": "elevenlabs",
        "model": "eleven_flash_v2_5"
      }
    },
    "channels": {
      "web_chat": {
        "enabled": true,
        "allowed_origins": [
          "https://www.acmetravel.com"
        ]
      }
    }
  }
}'
Response 201
{
  "data": {
    "id": "asst_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "org_id": "org_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "project_id": "proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "name": "Front desk",
    "config": {
      "agent": {
        "instructions": "You answer enquiries for Acme Travel."
      },
      "tools": {
        "definitions": [
          {
            "name": {},
            "description": {},
            "parameters": {},
            "enabled": {},
            "channels": {},
            "read_only": {}
          }
        ]
      },
      "session": null,
      "variables": [
        {
          "key": "string",
          "label": "string",
          "description": "string",
          "default": "string"
        }
      ],
      "knowledge": {
        "key": {
          "chat": true,
          "voice": true,
          "priority": 1
        }
      }
    },
    "version": 1,
    "draft_revision": 1,
    "draft": {
      "revision": 1,
      "base_version": 1,
      "updated_at": "2026-10-28T09:30:00.000Z"
    },
    "created_at": "2026-10-28T09:30:00.000Z",
    "updated_at": "2026-10-28T09:30:00.000Z"
  }
}

List assistants

GET/api/assistants

Every assistant in scope with its full current configuration. Secrets in the config come back as <key>_set flags.

Secret API key. How it works

Query parameters

  • project_idstring

    Only this project's assistants.

Returns

200 OK

Response attributes
  • dataarray of Assistantrequired

    10 attributes
    • idstringrequired

    • org_idstringrequired

    • project_idstringrequired

    • namestringrequired

    • configAssistantConfigrequired

      The runtime profile minus per-call fields. agent.instructions and either session.realtime or the complete session.{llm,stt,tts} pipeline are required. Realtime requires provider; its model may use the runtime default. A pipeline LLM may omit provider for a LiveKit-hosted model id. Credentials are write-only: integrations.google_analytics.api_secret, channels.web_chat.analytics.ga4.api_secret and recording.s3.{access_key,secret,session_token} come back as <key>_set: boolean, and a write that omits one keeps the stored value. Chat (web or WhatsApp) answers with channels.web_chat.llm, defaulting independently to openai/gpt-6.1-sol with medium reasoning; creating or enabling web chat, or changing that model while web chat or WhatsApp routing is live, is refused with 400 when chat has no adapter for its provider.

      5 attributes
      • agentobjectrequired

        1 attribute
        • instructionsstringrequired

      • toolsAssistantTools

        Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

        1 attribute
        • definitionsarray of AssistantToolDefinition

          6 attributes
          • namestringrequired

          • descriptionstring

          • parametersobject

            JSON Schema for the arguments, as exposed to the model.

          • enabledboolean

            False keeps the tool saved, with its request, but offers it on no channel.

            Default true

          • channelsarray of string

            Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

          • read_onlyboolean

            True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

            Default false

      • sessionanyrequired

        5 attributes
        • llmobject

          2 attributes
          • providerstringnot empty

          • modelstringrequirednot empty

        • realtimeobject

          2 attributes
          • providerstringrequirednot empty

          • modelstringnot empty

        • sttProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • ttsProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • toolsAssistantTools

          Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

          1 attribute
          • definitionsarray of AssistantToolDefinition

            6 attributes
            • namestringrequired

            • descriptionstring

            • parametersobject

              JSON Schema for the arguments, as exposed to the model.

            • enabledboolean

              False keeps the tool saved, with its request, but offers it on no channel.

              Default true

            • channelsarray of string

              Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

            • read_onlyboolean

              True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

              Default false

      • variablesarray of AssistantVariableDefup to 50 items

        Authoring-time schema for {{key}} placeholders in agent.instructions, agent.context, agent.first_message, and agent.first_message_instructions; never delivered to the runtime.

        4 attributes
        • keystringrequiredup to 64 characters

        • labelstringup to 120 characters

        • descriptionstringup to 500 characters

        • defaultstringup to 2000 characters

      • knowledgeobject

        The knowledge bases the assistant answers from, by knowledge base id (kb_...). Unlike the rest of the config, leaving it out of a write keeps the stored selection; send {} to detach every base. An entry with both chat and voice false counts as detached. Changing it needs an org-wide key and editor access to each base: 403 organization_knowledge_access_required for a project key or knowledge_forbidden without editor access, 400 knowledge_base_not_found for an unknown id, 409 knowledge_voice_requires_pipeline_assistant for voice on a realtime session. Each refusal names the base in knowledge_base_id.

        3 attributes
        • chatbooleanrequired

          Search it in web chat and WhatsApp.

        • voicebooleanrequired

          Search it on calls. Needs a pipeline session, not realtime.

        • priorityintegerrequired0 to 100

          Each search reaches up to four of the attached bases that have a live publication, highest priority first (then by id), and searches them in parallel.

    • versionintegerrequired

    • draft_revisioninteger

      The revision a draft save names as expected_draft_revision; 0 before the first draft.

    • draftobject | null

      Whether a draft exists, without its config (GET /assistants/{id}/draft has it).

      3 attributes
      • revisioninteger

      • base_versioninteger

      • updated_atstringISO 8601 timestamp

    • created_atstringISO 8601 timestamp

    • updated_atstringISO 8601 timestamp

  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
GET /api/assistants
curl "https://api.myleadsfactory.tech/api/assistants" \
  -H "Authorization: Bearer $MLF_API_KEY"
Response 200
{
  "data": [
    {
      "id": "asst_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "org_id": "org_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "project_id": "proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "name": "Front desk",
      "config": {
        "agent": {
          "instructions": "You answer enquiries for Acme Travel."
        },
        "tools": {
          "definitions": [
            {}
          ]
        },
        "session": null,
        "variables": [
          {
            "key": {},
            "label": {},
            "description": {},
            "default": {}
          }
        ],
        "knowledge": {
          "key": {
            "chat": {},
            "voice": {},
            "priority": {}
          }
        }
      },
      "version": 1,
      "draft_revision": 1,
      "draft": {
        "revision": 1,
        "base_version": 1,
        "updated_at": "2026-10-28T09:30:00.000Z"
      },
      "created_at": "2026-10-28T09:30:00.000Z",
      "updated_at": "2026-10-28T09:30:00.000Z"
    }
  ]
}

Get an assistant

GET/api/assistants/{id}

One assistant with its current configuration and version.

Secret API key. How it works

Path parameters

  • idstringrequired

    Assistant id, asst_....

Returns

200 OK

Response attributes
  • dataAssistantrequired

    10 attributes
    • idstringrequired

    • org_idstringrequired

    • project_idstringrequired

    • namestringrequired

    • configAssistantConfigrequired

      The runtime profile minus per-call fields. agent.instructions and either session.realtime or the complete session.{llm,stt,tts} pipeline are required. Realtime requires provider; its model may use the runtime default. A pipeline LLM may omit provider for a LiveKit-hosted model id. Credentials are write-only: integrations.google_analytics.api_secret, channels.web_chat.analytics.ga4.api_secret and recording.s3.{access_key,secret,session_token} come back as <key>_set: boolean, and a write that omits one keeps the stored value. Chat (web or WhatsApp) answers with channels.web_chat.llm, defaulting independently to openai/gpt-6.1-sol with medium reasoning; creating or enabling web chat, or changing that model while web chat or WhatsApp routing is live, is refused with 400 when chat has no adapter for its provider.

      5 attributes
      • agentobjectrequired

        1 attribute
        • instructionsstringrequired

      • toolsAssistantTools

        Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

        1 attribute
        • definitionsarray of AssistantToolDefinition

          6 attributes
          • namestringrequired

          • descriptionstring

          • parametersobject

            JSON Schema for the arguments, as exposed to the model.

          • enabledboolean

            False keeps the tool saved, with its request, but offers it on no channel.

            Default true

          • channelsarray of string

            Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

          • read_onlyboolean

            True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

            Default false

      • sessionanyrequired

        5 attributes
        • llmobject

          2 attributes
          • providerstringnot empty

          • modelstringrequirednot empty

        • realtimeobject

          2 attributes
          • providerstringrequirednot empty

          • modelstringnot empty

        • sttProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • ttsProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • toolsAssistantTools

          Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

          1 attribute
          • definitionsarray of AssistantToolDefinition

            6 attributes
            • namestringrequired

            • descriptionstring

            • parametersobject

              JSON Schema for the arguments, as exposed to the model.

            • enabledboolean

              False keeps the tool saved, with its request, but offers it on no channel.

              Default true

            • channelsarray of string

              Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

            • read_onlyboolean

              True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

              Default false

      • variablesarray of AssistantVariableDefup to 50 items

        Authoring-time schema for {{key}} placeholders in agent.instructions, agent.context, agent.first_message, and agent.first_message_instructions; never delivered to the runtime.

        4 attributes
        • keystringrequiredup to 64 characters

        • labelstringup to 120 characters

        • descriptionstringup to 500 characters

        • defaultstringup to 2000 characters

      • knowledgeobject

        The knowledge bases the assistant answers from, by knowledge base id (kb_...). Unlike the rest of the config, leaving it out of a write keeps the stored selection; send {} to detach every base. An entry with both chat and voice false counts as detached. Changing it needs an org-wide key and editor access to each base: 403 organization_knowledge_access_required for a project key or knowledge_forbidden without editor access, 400 knowledge_base_not_found for an unknown id, 409 knowledge_voice_requires_pipeline_assistant for voice on a realtime session. Each refusal names the base in knowledge_base_id.

        3 attributes
        • chatbooleanrequired

          Search it in web chat and WhatsApp.

        • voicebooleanrequired

          Search it on calls. Needs a pipeline session, not realtime.

        • priorityintegerrequired0 to 100

          Each search reaches up to four of the attached bases that have a live publication, highest priority first (then by id), and searches them in parallel.

    • versionintegerrequired

    • draft_revisioninteger

      The revision a draft save names as expected_draft_revision; 0 before the first draft.

    • draftobject | null

      Whether a draft exists, without its config (GET /assistants/{id}/draft has it).

      3 attributes
      • revisioninteger

      • base_versioninteger

      • updated_atstringISO 8601 timestamp

    • created_atstringISO 8601 timestamp

    • updated_atstringISO 8601 timestamp

  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 404 Not found, or outside what the key can see
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
GET /api/assistants/{id}
curl "https://api.myleadsfactory.tech/api/assistants/ASSISTANT_ID" \
  -H "Authorization: Bearer $MLF_API_KEY"
Response 200
{
  "data": {
    "id": "asst_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "org_id": "org_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "project_id": "proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "name": "Front desk",
    "config": {
      "agent": {
        "instructions": "You answer enquiries for Acme Travel."
      },
      "tools": {
        "definitions": [
          {
            "name": {},
            "description": {},
            "parameters": {},
            "enabled": {},
            "channels": {},
            "read_only": {}
          }
        ]
      },
      "session": null,
      "variables": [
        {
          "key": "string",
          "label": "string",
          "description": "string",
          "default": "string"
        }
      ],
      "knowledge": {
        "key": {
          "chat": true,
          "voice": true,
          "priority": 1
        }
      }
    },
    "version": 1,
    "draft_revision": 1,
    "draft": {
      "revision": 1,
      "base_version": 1,
      "updated_at": "2026-10-28T09:30:00.000Z"
    },
    "created_at": "2026-10-28T09:30:00.000Z",
    "updated_at": "2026-10-28T09:30:00.000Z"
  }
}

Update an assistant

PATCH/api/assistants/{id}

Send name, config or both. A config replaces the whole stored configuration (it is not merged), except that omitted secrets and tool request specs are kept: read the assistant, change what you need and send the full config back. Each update bumps version.

Secret API key, not read-only. How it works

Path parameters

  • idstringrequired

    Assistant id, asst_....

Request body

  • namestringnot empty

  • configAssistantConfig

    The runtime profile minus per-call fields. agent.instructions and either session.realtime or the complete session.{llm,stt,tts} pipeline are required. Realtime requires provider; its model may use the runtime default. A pipeline LLM may omit provider for a LiveKit-hosted model id. Credentials are write-only: integrations.google_analytics.api_secret, channels.web_chat.analytics.ga4.api_secret and recording.s3.{access_key,secret,session_token} come back as <key>_set: boolean, and a write that omits one keeps the stored value. Chat (web or WhatsApp) answers with channels.web_chat.llm, defaulting independently to openai/gpt-6.1-sol with medium reasoning; creating or enabling web chat, or changing that model while web chat or WhatsApp routing is live, is refused with 400 when chat has no adapter for its provider.

    5 attributes
    • agentobjectrequired

      1 attribute
      • instructionsstringrequired

    • toolsAssistantTools

      Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

      1 attribute
      • definitionsarray of AssistantToolDefinition

        7 attributes
        • namestringrequired

        • descriptionstring

        • parametersobject

          JSON Schema for the arguments, as exposed to the model.

        • enabledboolean

          False keeps the tool saved, with its request, but offers it on no channel.

          Default true

        • channelsarray of string

          Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

        • read_onlyboolean

          True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

          Default false

        • requestobjectwrite-only, never returned

          Server-side HTTP execution spec, never returned on reads. A write that omits it keeps the stored spec for the same tool name; removing or renaming the tool drops it.

          4 attributes
          • urlstringrequireduri

          • methodstring

            One of GET POST PUT PATCH DELETE

          • headersobject

          • timeout_msinteger1 to 120000

    • sessionanyrequired

      5 attributes
      • llmobject

        2 attributes
        • providerstringnot empty

        • modelstringrequirednot empty

      • realtimeobject

        2 attributes
        • providerstringrequirednot empty

        • modelstringnot empty

      • sttProviderModel

        2 attributes
        • providerstringrequirednot empty

        • modelstringrequirednot empty

      • ttsProviderModel

        2 attributes
        • providerstringrequirednot empty

        • modelstringrequirednot empty

      • toolsAssistantTools

        Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

        1 attribute
        • definitionsarray of AssistantToolDefinition

          7 attributes
          • namestringrequired

          • descriptionstring

          • parametersobject

            JSON Schema for the arguments, as exposed to the model.

          • enabledboolean

            False keeps the tool saved, with its request, but offers it on no channel.

            Default true

          • channelsarray of string

            Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

          • read_onlyboolean

            True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

            Default false

          • requestobjectwrite-only, never returned

            Server-side HTTP execution spec, never returned on reads. A write that omits it keeps the stored spec for the same tool name; removing or renaming the tool drops it.

            4 attributes
            • urlstringrequireduri

            • methodstring

              One of GET POST PUT PATCH DELETE

            • headersobject

            • timeout_msinteger1 to 120000

    • variablesarray of AssistantVariableDefup to 50 items

      Authoring-time schema for {{key}} placeholders in agent.instructions, agent.context, agent.first_message, and agent.first_message_instructions; never delivered to the runtime.

      4 attributes
      • keystringrequiredup to 64 characters

      • labelstringup to 120 characters

      • descriptionstringup to 500 characters

      • defaultstringup to 2000 characters

    • knowledgeobject

      The knowledge bases the assistant answers from, by knowledge base id (kb_...). Unlike the rest of the config, leaving it out of a write keeps the stored selection; send {} to detach every base. An entry with both chat and voice false counts as detached. Changing it needs an org-wide key and editor access to each base: 403 organization_knowledge_access_required for a project key or knowledge_forbidden without editor access, 400 knowledge_base_not_found for an unknown id, 409 knowledge_voice_requires_pipeline_assistant for voice on a realtime session. Each refusal names the base in knowledge_base_id.

      3 attributes
      • chatbooleanrequired

        Search it in web chat and WhatsApp.

      • voicebooleanrequired

        Search it on calls. Needs a pipeline session, not realtime.

      • priorityintegerrequired0 to 100

        Each search reaches up to four of the attached bases that have a live publication, highest priority first (then by id), and searches them in parallel.

  • expected_versionintegermin 1

    The version the caller read. A save over a newer version is refused with 409 version_conflict and the current_version.

Returns

200 OK

Response attributes
  • dataAssistantrequired

    10 attributes
    • idstringrequired

    • org_idstringrequired

    • project_idstringrequired

    • namestringrequired

    • configAssistantConfigrequired

      The runtime profile minus per-call fields. agent.instructions and either session.realtime or the complete session.{llm,stt,tts} pipeline are required. Realtime requires provider; its model may use the runtime default. A pipeline LLM may omit provider for a LiveKit-hosted model id. Credentials are write-only: integrations.google_analytics.api_secret, channels.web_chat.analytics.ga4.api_secret and recording.s3.{access_key,secret,session_token} come back as <key>_set: boolean, and a write that omits one keeps the stored value. Chat (web or WhatsApp) answers with channels.web_chat.llm, defaulting independently to openai/gpt-6.1-sol with medium reasoning; creating or enabling web chat, or changing that model while web chat or WhatsApp routing is live, is refused with 400 when chat has no adapter for its provider.

      5 attributes
      • agentobjectrequired

        1 attribute
        • instructionsstringrequired

      • toolsAssistantTools

        Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

        1 attribute
        • definitionsarray of AssistantToolDefinition

          6 attributes
          • namestringrequired

          • descriptionstring

          • parametersobject

            JSON Schema for the arguments, as exposed to the model.

          • enabledboolean

            False keeps the tool saved, with its request, but offers it on no channel.

            Default true

          • channelsarray of string

            Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

          • read_onlyboolean

            True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

            Default false

      • sessionanyrequired

        5 attributes
        • llmobject

          2 attributes
          • providerstringnot empty

          • modelstringrequirednot empty

        • realtimeobject

          2 attributes
          • providerstringrequirednot empty

          • modelstringnot empty

        • sttProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • ttsProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • toolsAssistantTools

          Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

          1 attribute
          • definitionsarray of AssistantToolDefinition

            6 attributes
            • namestringrequired

            • descriptionstring

            • parametersobject

              JSON Schema for the arguments, as exposed to the model.

            • enabledboolean

              False keeps the tool saved, with its request, but offers it on no channel.

              Default true

            • channelsarray of string

              Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

            • read_onlyboolean

              True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

              Default false

      • variablesarray of AssistantVariableDefup to 50 items

        Authoring-time schema for {{key}} placeholders in agent.instructions, agent.context, agent.first_message, and agent.first_message_instructions; never delivered to the runtime.

        4 attributes
        • keystringrequiredup to 64 characters

        • labelstringup to 120 characters

        • descriptionstringup to 500 characters

        • defaultstringup to 2000 characters

      • knowledgeobject

        The knowledge bases the assistant answers from, by knowledge base id (kb_...). Unlike the rest of the config, leaving it out of a write keeps the stored selection; send {} to detach every base. An entry with both chat and voice false counts as detached. Changing it needs an org-wide key and editor access to each base: 403 organization_knowledge_access_required for a project key or knowledge_forbidden without editor access, 400 knowledge_base_not_found for an unknown id, 409 knowledge_voice_requires_pipeline_assistant for voice on a realtime session. Each refusal names the base in knowledge_base_id.

        3 attributes
        • chatbooleanrequired

          Search it in web chat and WhatsApp.

        • voicebooleanrequired

          Search it on calls. Needs a pipeline session, not realtime.

        • priorityintegerrequired0 to 100

          Each search reaches up to four of the attached bases that have a live publication, highest priority first (then by id), and searches them in parallel.

    • versionintegerrequired

    • draft_revisioninteger

      The revision a draft save names as expected_draft_revision; 0 before the first draft.

    • draftobject | null

      Whether a draft exists, without its config (GET /assistants/{id}/draft has it).

      3 attributes
      • revisioninteger

      • base_versioninteger

      • updated_atstringISO 8601 timestamp

    • created_atstringISO 8601 timestamp

    • updated_atstringISO 8601 timestamp

  • 400 Validation error: usually invalid_request, with the failing fields in issues when there are any
  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 403 Refused, for example a read-only key on a write (read_only_key), a role too low for the route (insufficient_role), or a route that needs a console session
  • 404 Not found, or outside what the key can see
  • 409 Conflict
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
PATCH /api/assistants/{id}
curl -X PATCH "https://api.myleadsfactory.tech/api/assistants/ASSISTANT_ID" \
  -H "Authorization: Bearer $MLF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Front desk (UK)"
}'
Response 200
{
  "data": {
    "id": "asst_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "org_id": "org_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "project_id": "proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "name": "Front desk",
    "config": {
      "agent": {
        "instructions": "You answer enquiries for Acme Travel."
      },
      "tools": {
        "definitions": [
          {
            "name": {},
            "description": {},
            "parameters": {},
            "enabled": {},
            "channels": {},
            "read_only": {}
          }
        ]
      },
      "session": null,
      "variables": [
        {
          "key": "string",
          "label": "string",
          "description": "string",
          "default": "string"
        }
      ],
      "knowledge": {
        "key": {
          "chat": true,
          "voice": true,
          "priority": 1
        }
      }
    },
    "version": 1,
    "draft_revision": 1,
    "draft": {
      "revision": 1,
      "base_version": 1,
      "updated_at": "2026-10-28T09:30:00.000Z"
    },
    "created_at": "2026-10-28T09:30:00.000Z",
    "updated_at": "2026-10-28T09:30:00.000Z"
  }
}

Delete an assistant

DELETE/api/assistants/{id}

Deletes the assistant. Its past calls, conversations and leads stay readable.

Secret API key, not read-only. How it works

Path parameters

  • idstringrequired

    Assistant id, asst_....

Returns

200 OK

Response attributes
  • dataDeleteResultrequired

    2 attributes
    • idstringrequired

    • deletedbooleanrequired

  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 403 Refused, for example a read-only key on a write (read_only_key), a role too low for the route (insufficient_role), or a route that needs a console session
  • 404 Not found, or outside what the key can see
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
DELETE /api/assistants/{id}
curl -X DELETE "https://api.myleadsfactory.tech/api/assistants/ASSISTANT_ID" \
  -H "Authorization: Bearer $MLF_API_KEY"
Response 200
{
  "data": {
    "id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "deleted": true
  }
}

Upload an assistant avatar

POST/api/assistant-avatars

Stores a PNG, JPEG or WebP (at most 512 KB and 4096 pixels a side) as a public org asset and returns its URL, for channels.web_chat.appearance.avatar_url. The same picture always gets the same URL.

Secret API key, not read-only. How it works

Request body

  • content_typestringrequired

    One of image/png image/jpeg image/webp

  • base64stringrequired

    The file's bytes, base64-encoded.

Returns

201 OK

Response attributes
  • dataAssistantAvatarrequired

    1 attribute
    • urlstringrequireduri

  • 400 invalid_request for a malformed body, or avatar_empty, avatar_too_large, avatar_type_mismatch (the bytes are not the declared image type) or avatar_dimensions, in error.
  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 403 Refused, for example a read-only key on a write (read_only_key), a role too low for the route (insufficient_role), or a route that needs a console session
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
  • 503 asset_storage_not_configured: this deployment has no storage for uploaded images.
POST /api/assistant-avatars
curl -X POST "https://api.myleadsfactory.tech/api/assistant-avatars" \
  -H "Authorization: Bearer $MLF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "content_type": "image/png",
  "base64": "string"
}'
Response 201
{
  "data": {
    "url": "https://example.com/hook"
  }
}

Start a test chat conversation

POST/api/assistants/{id}/chat-test-conversation

Starts a one-hour conversation with an assistant whose web chat is on, without a publishable key or an origin check, for trying a prompt from your own tooling. Use the returned token with the public chat routes. Test conversations carry metadata.test and are left out of lists and analytics unless asked for.

Secret API key, not read-only. How it works

Path parameters

  • idstringrequired

    Assistant id, asst_....

Returns

201 Test conversation created

Response attributes
  • dataobjectrequired

    2 attributes
    • conversation_idstringrequired

    • tokenstringrequired

  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 403 Refused, for example a read-only key on a write (read_only_key), a role too low for the route (insufficient_role), or a route that needs a console session
  • 404 Not found, or outside what the key can see
  • 409 web_chat_disabled: turn on the assistant's channels.web_chat.enabled first
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
POST /api/assistants/{id}/chat-test-conversation
curl -X POST "https://api.myleadsfactory.tech/api/assistants/ASSISTANT_ID/chat-test-conversation" \
  -H "Authorization: Bearer $MLF_API_KEY"
Response 201
{
  "data": {
    "conversation_id": "conv_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "token": "string"
  }
}

Get the assistant's draft

GET/api/assistants/{id}/draft

The config being worked on in test mode, or null when there is none. Test chats (test keys and the console's test chat) run it; visitors never do until it is published.

Secret API key. How it works

Path parameters

  • idstringrequired

Returns

200 OK

Response attributes
  • dataAssistantDraft | nullrequired

    8 attributes
    • assistant_idstring

    • configAssistantConfig

      The runtime profile minus per-call fields. agent.instructions and either session.realtime or the complete session.{llm,stt,tts} pipeline are required. Realtime requires provider; its model may use the runtime default. A pipeline LLM may omit provider for a LiveKit-hosted model id. Credentials are write-only: integrations.google_analytics.api_secret, channels.web_chat.analytics.ga4.api_secret and recording.s3.{access_key,secret,session_token} come back as <key>_set: boolean, and a write that omits one keeps the stored value. Chat (web or WhatsApp) answers with channels.web_chat.llm, defaulting independently to openai/gpt-6.1-sol with medium reasoning; creating or enabling web chat, or changing that model while web chat or WhatsApp routing is live, is refused with 400 when chat has no adapter for its provider.

      5 attributes
      • agentobjectrequired

        1 attribute
        • instructionsstringrequired

      • toolsAssistantTools

        Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

        1 attribute
        • definitionsarray of AssistantToolDefinition

          6 attributes
          • namestringrequired

          • descriptionstring

          • parametersobject

            JSON Schema for the arguments, as exposed to the model.

          • enabledboolean

            False keeps the tool saved, with its request, but offers it on no channel.

            Default true

          • channelsarray of string

            Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

          • read_onlyboolean

            True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

            Default false

      • sessionanyrequired

        5 attributes
        • llmobject

          2 attributes
          • providerstringnot empty

          • modelstringrequirednot empty

        • realtimeobject

          2 attributes
          • providerstringrequirednot empty

          • modelstringnot empty

        • sttProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • ttsProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • toolsAssistantTools

          Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

          1 attribute
          • definitionsarray of AssistantToolDefinition

            6 attributes
            • namestringrequired

            • descriptionstring

            • parametersobject

              JSON Schema for the arguments, as exposed to the model.

            • enabledboolean

              False keeps the tool saved, with its request, but offers it on no channel.

              Default true

            • channelsarray of string

              Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

            • read_onlyboolean

              True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

              Default false

      • variablesarray of AssistantVariableDefup to 50 items

        Authoring-time schema for {{key}} placeholders in agent.instructions, agent.context, agent.first_message, and agent.first_message_instructions; never delivered to the runtime.

        4 attributes
        • keystringrequiredup to 64 characters

        • labelstringup to 120 characters

        • descriptionstringup to 500 characters

        • defaultstringup to 2000 characters

      • knowledgeobject

        The knowledge bases the assistant answers from, by knowledge base id (kb_...). Unlike the rest of the config, leaving it out of a write keeps the stored selection; send {} to detach every base. An entry with both chat and voice false counts as detached. Changing it needs an org-wide key and editor access to each base: 403 organization_knowledge_access_required for a project key or knowledge_forbidden without editor access, 400 knowledge_base_not_found for an unknown id, 409 knowledge_voice_requires_pipeline_assistant for voice on a realtime session. Each refusal names the base in knowledge_base_id.

        3 attributes
        • chatbooleanrequired

          Search it in web chat and WhatsApp.

        • voicebooleanrequired

          Search it on calls. Needs a pipeline session, not realtime.

        • priorityintegerrequired0 to 100

          Each search reaches up to four of the attached bases that have a live publication, highest priority first (then by id), and searches them in parallel.

    • hidden_changesarray of string

      Paths that differ from live but read back the same: credentials and tool request specs. Values are never returned.

    • revisioninteger

    • base_versioninteger

      The live version the draft started from.

    • live_versioninteger

    • staleboolean

      Live was edited after the draft started; publishing is refused.

    • updated_atstringISO 8601 timestamp

  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 404 Not found, or outside what the key can see
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
GET /api/assistants/{id}/draft
curl "https://api.myleadsfactory.tech/api/assistants/ASSISTANT_ID/draft" \
  -H "Authorization: Bearer $MLF_API_KEY"
Response 200
{
  "data": {
    "assistant_id": "asst_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "config": {
      "agent": {
        "instructions": "You answer enquiries for Acme Travel."
      },
      "tools": {
        "definitions": [
          {
            "name": {},
            "description": {},
            "parameters": {},
            "enabled": {},
            "channels": {},
            "read_only": {}
          }
        ]
      },
      "session": null,
      "variables": [
        {
          "key": "string",
          "label": "string",
          "description": "string",
          "default": "string"
        }
      ],
      "knowledge": {
        "key": {
          "chat": true,
          "voice": true,
          "priority": 1
        }
      }
    },
    "hidden_changes": [
      "string"
    ],
    "revision": 1,
    "base_version": 1,
    "live_version": 1,
    "stale": true,
    "updated_at": "2026-10-28T09:30:00.000Z"
  }
}

Save the assistant's draft

PUT/api/assistants/{id}/draft

Starts a draft from the live config, or replaces the current one. Credentials and tool request specs left out are kept from the stored draft (or from live for a new draft).

Secret API key, not read-only. How it works

Path parameters

  • idstringrequired

Request body

  • configAssistantConfigrequired

    The runtime profile minus per-call fields. agent.instructions and either session.realtime or the complete session.{llm,stt,tts} pipeline are required. Realtime requires provider; its model may use the runtime default. A pipeline LLM may omit provider for a LiveKit-hosted model id. Credentials are write-only: integrations.google_analytics.api_secret, channels.web_chat.analytics.ga4.api_secret and recording.s3.{access_key,secret,session_token} come back as <key>_set: boolean, and a write that omits one keeps the stored value. Chat (web or WhatsApp) answers with channels.web_chat.llm, defaulting independently to openai/gpt-6.1-sol with medium reasoning; creating or enabling web chat, or changing that model while web chat or WhatsApp routing is live, is refused with 400 when chat has no adapter for its provider.

    5 attributes
    • agentobjectrequired

      1 attribute
      • instructionsstringrequired

    • toolsAssistantTools

      Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

      1 attribute
      • definitionsarray of AssistantToolDefinition

        7 attributes
        • namestringrequired

        • descriptionstring

        • parametersobject

          JSON Schema for the arguments, as exposed to the model.

        • enabledboolean

          False keeps the tool saved, with its request, but offers it on no channel.

          Default true

        • channelsarray of string

          Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

        • read_onlyboolean

          True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

          Default false

        • requestobjectwrite-only, never returned

          Server-side HTTP execution spec, never returned on reads. A write that omits it keeps the stored spec for the same tool name; removing or renaming the tool drops it.

          4 attributes
          • urlstringrequireduri

          • methodstring

            One of GET POST PUT PATCH DELETE

          • headersobject

          • timeout_msinteger1 to 120000

    • sessionanyrequired

      5 attributes
      • llmobject

        2 attributes
        • providerstringnot empty

        • modelstringrequirednot empty

      • realtimeobject

        2 attributes
        • providerstringrequirednot empty

        • modelstringnot empty

      • sttProviderModel

        2 attributes
        • providerstringrequirednot empty

        • modelstringrequirednot empty

      • ttsProviderModel

        2 attributes
        • providerstringrequirednot empty

        • modelstringrequirednot empty

      • toolsAssistantTools

        Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

        1 attribute
        • definitionsarray of AssistantToolDefinition

          7 attributes
          • namestringrequired

          • descriptionstring

          • parametersobject

            JSON Schema for the arguments, as exposed to the model.

          • enabledboolean

            False keeps the tool saved, with its request, but offers it on no channel.

            Default true

          • channelsarray of string

            Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

          • read_onlyboolean

            True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

            Default false

          • requestobjectwrite-only, never returned

            Server-side HTTP execution spec, never returned on reads. A write that omits it keeps the stored spec for the same tool name; removing or renaming the tool drops it.

            4 attributes
            • urlstringrequireduri

            • methodstring

              One of GET POST PUT PATCH DELETE

            • headersobject

            • timeout_msinteger1 to 120000

    • variablesarray of AssistantVariableDefup to 50 items

      Authoring-time schema for {{key}} placeholders in agent.instructions, agent.context, agent.first_message, and agent.first_message_instructions; never delivered to the runtime.

      4 attributes
      • keystringrequiredup to 64 characters

      • labelstringup to 120 characters

      • descriptionstringup to 500 characters

      • defaultstringup to 2000 characters

    • knowledgeobject

      The knowledge bases the assistant answers from, by knowledge base id (kb_...). Unlike the rest of the config, leaving it out of a write keeps the stored selection; send {} to detach every base. An entry with both chat and voice false counts as detached. Changing it needs an org-wide key and editor access to each base: 403 organization_knowledge_access_required for a project key or knowledge_forbidden without editor access, 400 knowledge_base_not_found for an unknown id, 409 knowledge_voice_requires_pipeline_assistant for voice on a realtime session. Each refusal names the base in knowledge_base_id.

      3 attributes
      • chatbooleanrequired

        Search it in web chat and WhatsApp.

      • voicebooleanrequired

        Search it on calls. Needs a pipeline session, not realtime.

      • priorityintegerrequired0 to 100

        Each search reaches up to four of the attached bases that have a live publication, highest priority first (then by id), and searches them in parallel.

  • expected_draft_revisionintegermin 0

    The draft_revision the caller read. A save over a newer draft is refused with 409 draft_conflict.

  • expected_versionintegermin 1

    The live version the caller edited from. A save that starts a new draft is refused with 409 live_changed when live has moved on since.

Returns

200 OK

Response attributes
  • dataAssistantDraft | nullrequired

    8 attributes
    • assistant_idstring

    • configAssistantConfig

      The runtime profile minus per-call fields. agent.instructions and either session.realtime or the complete session.{llm,stt,tts} pipeline are required. Realtime requires provider; its model may use the runtime default. A pipeline LLM may omit provider for a LiveKit-hosted model id. Credentials are write-only: integrations.google_analytics.api_secret, channels.web_chat.analytics.ga4.api_secret and recording.s3.{access_key,secret,session_token} come back as <key>_set: boolean, and a write that omits one keeps the stored value. Chat (web or WhatsApp) answers with channels.web_chat.llm, defaulting independently to openai/gpt-6.1-sol with medium reasoning; creating or enabling web chat, or changing that model while web chat or WhatsApp routing is live, is refused with 400 when chat has no adapter for its provider.

      5 attributes
      • agentobjectrequired

        1 attribute
        • instructionsstringrequired

      • toolsAssistantTools

        Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

        1 attribute
        • definitionsarray of AssistantToolDefinition

          6 attributes
          • namestringrequired

          • descriptionstring

          • parametersobject

            JSON Schema for the arguments, as exposed to the model.

          • enabledboolean

            False keeps the tool saved, with its request, but offers it on no channel.

            Default true

          • channelsarray of string

            Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

          • read_onlyboolean

            True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

            Default false

      • sessionanyrequired

        5 attributes
        • llmobject

          2 attributes
          • providerstringnot empty

          • modelstringrequirednot empty

        • realtimeobject

          2 attributes
          • providerstringrequirednot empty

          • modelstringnot empty

        • sttProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • ttsProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • toolsAssistantTools

          Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

          1 attribute
          • definitionsarray of AssistantToolDefinition

            6 attributes
            • namestringrequired

            • descriptionstring

            • parametersobject

              JSON Schema for the arguments, as exposed to the model.

            • enabledboolean

              False keeps the tool saved, with its request, but offers it on no channel.

              Default true

            • channelsarray of string

              Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

            • read_onlyboolean

              True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

              Default false

      • variablesarray of AssistantVariableDefup to 50 items

        Authoring-time schema for {{key}} placeholders in agent.instructions, agent.context, agent.first_message, and agent.first_message_instructions; never delivered to the runtime.

        4 attributes
        • keystringrequiredup to 64 characters

        • labelstringup to 120 characters

        • descriptionstringup to 500 characters

        • defaultstringup to 2000 characters

      • knowledgeobject

        The knowledge bases the assistant answers from, by knowledge base id (kb_...). Unlike the rest of the config, leaving it out of a write keeps the stored selection; send {} to detach every base. An entry with both chat and voice false counts as detached. Changing it needs an org-wide key and editor access to each base: 403 organization_knowledge_access_required for a project key or knowledge_forbidden without editor access, 400 knowledge_base_not_found for an unknown id, 409 knowledge_voice_requires_pipeline_assistant for voice on a realtime session. Each refusal names the base in knowledge_base_id.

        3 attributes
        • chatbooleanrequired

          Search it in web chat and WhatsApp.

        • voicebooleanrequired

          Search it on calls. Needs a pipeline session, not realtime.

        • priorityintegerrequired0 to 100

          Each search reaches up to four of the attached bases that have a live publication, highest priority first (then by id), and searches them in parallel.

    • hidden_changesarray of string

      Paths that differ from live but read back the same: credentials and tool request specs. Values are never returned.

    • revisioninteger

    • base_versioninteger

      The live version the draft started from.

    • live_versioninteger

    • staleboolean

      Live was edited after the draft started; publishing is refused.

    • updated_atstringISO 8601 timestamp

  • 400 Validation error: usually invalid_request, with the failing fields in issues when there are any
  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 403 Refused, for example a read-only key on a write (read_only_key), a role too low for the route (insufficient_role), or a route that needs a console session
  • 404 Not found, or outside what the key can see
  • 409 Conflict
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
PUT /api/assistants/{id}/draft
curl -X PUT "https://api.myleadsfactory.tech/api/assistants/ASSISTANT_ID/draft" \
  -H "Authorization: Bearer $MLF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "config": {
    "agent": {
      "instructions": "You answer enquiries for Acme Travel."
    },
    "session": null
  }
}'
Response 200
{
  "data": {
    "assistant_id": "asst_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "config": {
      "agent": {
        "instructions": "You answer enquiries for Acme Travel."
      },
      "tools": {
        "definitions": [
          {
            "name": {},
            "description": {},
            "parameters": {},
            "enabled": {},
            "channels": {},
            "read_only": {}
          }
        ]
      },
      "session": null,
      "variables": [
        {
          "key": "string",
          "label": "string",
          "description": "string",
          "default": "string"
        }
      ],
      "knowledge": {
        "key": {
          "chat": true,
          "voice": true,
          "priority": 1
        }
      }
    },
    "hidden_changes": [
      "string"
    ],
    "revision": 1,
    "base_version": 1,
    "live_version": 1,
    "stale": true,
    "updated_at": "2026-10-28T09:30:00.000Z"
  }
}

Discard the assistant's draft

DELETE/api/assistants/{id}/draft

Throws the draft away and returns the assistant; the live config is unchanged. Succeeds when there is no draft too.

Secret API key, not read-only. How it works

Path parameters

  • idstringrequired

Query parameters

  • expected_draft_revisioninteger

    The draft_revision the caller looked at; a newer draft is not discarded (409 draft_conflict).

Returns

200 OK

Response attributes
  • dataAssistantrequired

    10 attributes
    • idstringrequired

    • org_idstringrequired

    • project_idstringrequired

    • namestringrequired

    • configAssistantConfigrequired

      The runtime profile minus per-call fields. agent.instructions and either session.realtime or the complete session.{llm,stt,tts} pipeline are required. Realtime requires provider; its model may use the runtime default. A pipeline LLM may omit provider for a LiveKit-hosted model id. Credentials are write-only: integrations.google_analytics.api_secret, channels.web_chat.analytics.ga4.api_secret and recording.s3.{access_key,secret,session_token} come back as <key>_set: boolean, and a write that omits one keeps the stored value. Chat (web or WhatsApp) answers with channels.web_chat.llm, defaulting independently to openai/gpt-6.1-sol with medium reasoning; creating or enabling web chat, or changing that model while web chat or WhatsApp routing is live, is refused with 400 when chat has no adapter for its provider.

      5 attributes
      • agentobjectrequired

        1 attribute
        • instructionsstringrequired

      • toolsAssistantTools

        Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

        1 attribute
        • definitionsarray of AssistantToolDefinition

          6 attributes
          • namestringrequired

          • descriptionstring

          • parametersobject

            JSON Schema for the arguments, as exposed to the model.

          • enabledboolean

            False keeps the tool saved, with its request, but offers it on no channel.

            Default true

          • channelsarray of string

            Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

          • read_onlyboolean

            True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

            Default false

      • sessionanyrequired

        5 attributes
        • llmobject

          2 attributes
          • providerstringnot empty

          • modelstringrequirednot empty

        • realtimeobject

          2 attributes
          • providerstringrequirednot empty

          • modelstringnot empty

        • sttProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • ttsProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • toolsAssistantTools

          Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

          1 attribute
          • definitionsarray of AssistantToolDefinition

            6 attributes
            • namestringrequired

            • descriptionstring

            • parametersobject

              JSON Schema for the arguments, as exposed to the model.

            • enabledboolean

              False keeps the tool saved, with its request, but offers it on no channel.

              Default true

            • channelsarray of string

              Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

            • read_onlyboolean

              True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

              Default false

      • variablesarray of AssistantVariableDefup to 50 items

        Authoring-time schema for {{key}} placeholders in agent.instructions, agent.context, agent.first_message, and agent.first_message_instructions; never delivered to the runtime.

        4 attributes
        • keystringrequiredup to 64 characters

        • labelstringup to 120 characters

        • descriptionstringup to 500 characters

        • defaultstringup to 2000 characters

      • knowledgeobject

        The knowledge bases the assistant answers from, by knowledge base id (kb_...). Unlike the rest of the config, leaving it out of a write keeps the stored selection; send {} to detach every base. An entry with both chat and voice false counts as detached. Changing it needs an org-wide key and editor access to each base: 403 organization_knowledge_access_required for a project key or knowledge_forbidden without editor access, 400 knowledge_base_not_found for an unknown id, 409 knowledge_voice_requires_pipeline_assistant for voice on a realtime session. Each refusal names the base in knowledge_base_id.

        3 attributes
        • chatbooleanrequired

          Search it in web chat and WhatsApp.

        • voicebooleanrequired

          Search it on calls. Needs a pipeline session, not realtime.

        • priorityintegerrequired0 to 100

          Each search reaches up to four of the attached bases that have a live publication, highest priority first (then by id), and searches them in parallel.

    • versionintegerrequired

    • draft_revisioninteger

      The revision a draft save names as expected_draft_revision; 0 before the first draft.

    • draftobject | null

      Whether a draft exists, without its config (GET /assistants/{id}/draft has it).

      3 attributes
      • revisioninteger

      • base_versioninteger

      • updated_atstringISO 8601 timestamp

    • created_atstringISO 8601 timestamp

    • updated_atstringISO 8601 timestamp

  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 403 Refused, for example a read-only key on a write (read_only_key), a role too low for the route (insufficient_role), or a route that needs a console session
  • 404 Not found, or outside what the key can see
  • 409 Conflict
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
DELETE /api/assistants/{id}/draft
curl -X DELETE "https://api.myleadsfactory.tech/api/assistants/ASSISTANT_ID/draft" \
  -H "Authorization: Bearer $MLF_API_KEY"
Response 200
{
  "data": {
    "id": "asst_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "org_id": "org_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "project_id": "proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "name": "Front desk",
    "config": {
      "agent": {
        "instructions": "You answer enquiries for Acme Travel."
      },
      "tools": {
        "definitions": [
          {
            "name": {},
            "description": {},
            "parameters": {},
            "enabled": {},
            "channels": {},
            "read_only": {}
          }
        ]
      },
      "session": null,
      "variables": [
        {
          "key": "string",
          "label": "string",
          "description": "string",
          "default": "string"
        }
      ],
      "knowledge": {
        "key": {
          "chat": true,
          "voice": true,
          "priority": 1
        }
      }
    },
    "version": 1,
    "draft_revision": 1,
    "draft": {
      "revision": 1,
      "base_version": 1,
      "updated_at": "2026-10-28T09:30:00.000Z"
    },
    "created_at": "2026-10-28T09:30:00.000Z",
    "updated_at": "2026-10-28T09:30:00.000Z"
  }
}

Update the draft from live

POST/api/assistants/{id}/draft/rebase

After live changed under a draft (a stale draft), lays what the draft changed since its base version over today's live config, so it can be published without undoing live's change. Settings both changed differently are refused with 409 rebase_conflict and their paths, unless keep_draft keeps the draft's values; those paths are returned as kept_draft. Also 409 no_draft, draft_conflict, rebase_unavailable when the base version is not in history, or rebase_invalid (with issues) when the merged config would not be valid; the draft is then left as it was.

Secret API key, not read-only. How it works

Path parameters

  • idstringrequired

Request body

  • expected_draft_revisionintegermin 0

  • keep_draftboolean

    Keep the draft's value where live changed the same setting differently.

Returns

200 The updated draft, and the settings where the draft's value was kept over live's.

Response attributes
  • dataAssistantDraft | nullrequired

    8 attributes
    • assistant_idstring

    • configAssistantConfig

      The runtime profile minus per-call fields. agent.instructions and either session.realtime or the complete session.{llm,stt,tts} pipeline are required. Realtime requires provider; its model may use the runtime default. A pipeline LLM may omit provider for a LiveKit-hosted model id. Credentials are write-only: integrations.google_analytics.api_secret, channels.web_chat.analytics.ga4.api_secret and recording.s3.{access_key,secret,session_token} come back as <key>_set: boolean, and a write that omits one keeps the stored value. Chat (web or WhatsApp) answers with channels.web_chat.llm, defaulting independently to openai/gpt-6.1-sol with medium reasoning; creating or enabling web chat, or changing that model while web chat or WhatsApp routing is live, is refused with 400 when chat has no adapter for its provider.

      5 attributes
      • agentobjectrequired

        1 attribute
        • instructionsstringrequired

      • toolsAssistantTools

        Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

        1 attribute
        • definitionsarray of AssistantToolDefinition

          6 attributes
          • namestringrequired

          • descriptionstring

          • parametersobject

            JSON Schema for the arguments, as exposed to the model.

          • enabledboolean

            False keeps the tool saved, with its request, but offers it on no channel.

            Default true

          • channelsarray of string

            Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

          • read_onlyboolean

            True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

            Default false

      • sessionanyrequired

        5 attributes
        • llmobject

          2 attributes
          • providerstringnot empty

          • modelstringrequirednot empty

        • realtimeobject

          2 attributes
          • providerstringrequirednot empty

          • modelstringnot empty

        • sttProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • ttsProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • toolsAssistantTools

          Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

          1 attribute
          • definitionsarray of AssistantToolDefinition

            6 attributes
            • namestringrequired

            • descriptionstring

            • parametersobject

              JSON Schema for the arguments, as exposed to the model.

            • enabledboolean

              False keeps the tool saved, with its request, but offers it on no channel.

              Default true

            • channelsarray of string

              Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

            • read_onlyboolean

              True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

              Default false

      • variablesarray of AssistantVariableDefup to 50 items

        Authoring-time schema for {{key}} placeholders in agent.instructions, agent.context, agent.first_message, and agent.first_message_instructions; never delivered to the runtime.

        4 attributes
        • keystringrequiredup to 64 characters

        • labelstringup to 120 characters

        • descriptionstringup to 500 characters

        • defaultstringup to 2000 characters

      • knowledgeobject

        The knowledge bases the assistant answers from, by knowledge base id (kb_...). Unlike the rest of the config, leaving it out of a write keeps the stored selection; send {} to detach every base. An entry with both chat and voice false counts as detached. Changing it needs an org-wide key and editor access to each base: 403 organization_knowledge_access_required for a project key or knowledge_forbidden without editor access, 400 knowledge_base_not_found for an unknown id, 409 knowledge_voice_requires_pipeline_assistant for voice on a realtime session. Each refusal names the base in knowledge_base_id.

        3 attributes
        • chatbooleanrequired

          Search it in web chat and WhatsApp.

        • voicebooleanrequired

          Search it on calls. Needs a pipeline session, not realtime.

        • priorityintegerrequired0 to 100

          Each search reaches up to four of the attached bases that have a live publication, highest priority first (then by id), and searches them in parallel.

    • hidden_changesarray of string

      Paths that differ from live but read back the same: credentials and tool request specs. Values are never returned.

    • revisioninteger

    • base_versioninteger

      The live version the draft started from.

    • live_versioninteger

    • staleboolean

      Live was edited after the draft started; publishing is refused.

    • updated_atstringISO 8601 timestamp

  • kept_draftarray of stringrequired

  • 400 Validation error: usually invalid_request, with the failing fields in issues when there are any
  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 403 Refused, for example a read-only key on a write (read_only_key), a role too low for the route (insufficient_role), or a route that needs a console session
  • 404 Not found, or outside what the key can see
  • 409 Conflict
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
POST /api/assistants/{id}/draft/rebase
curl -X POST "https://api.myleadsfactory.tech/api/assistants/ASSISTANT_ID/draft/rebase" \
  -H "Authorization: Bearer $MLF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "expected_draft_revision": 1,
  "keep_draft": true
}'
Response 200
{
  "data": {
    "assistant_id": "asst_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "config": {
      "agent": {
        "instructions": "You answer enquiries for Acme Travel."
      },
      "tools": {
        "definitions": [
          {
            "name": {},
            "description": {},
            "parameters": {},
            "enabled": {},
            "channels": {},
            "read_only": {}
          }
        ]
      },
      "session": null,
      "variables": [
        {
          "key": "string",
          "label": "string",
          "description": "string",
          "default": "string"
        }
      ],
      "knowledge": {
        "key": {
          "chat": true,
          "voice": true,
          "priority": 1
        }
      }
    },
    "hidden_changes": [
      "string"
    ],
    "revision": 1,
    "base_version": 1,
    "live_version": 1,
    "stale": true,
    "updated_at": "2026-10-28T09:30:00.000Z"
  },
  "kept_draft": [
    "string"
  ]
}

Publish the draft

POST/api/assistants/{id}/publish

Makes the draft the live config and records the new version. Refused with 409 no_draft, version_conflict, draft_conflict, or live_changed when live was edited after the draft started.

Secret API key, not read-only. How it works

Path parameters

  • idstringrequired

Request body

  • expected_versionintegermin 1

  • expected_draft_revisionintegermin 0

  • notestringup to 500 characters

Returns

200 OK

Response attributes
  • dataAssistantrequired

    10 attributes
    • idstringrequired

    • org_idstringrequired

    • project_idstringrequired

    • namestringrequired

    • configAssistantConfigrequired

      The runtime profile minus per-call fields. agent.instructions and either session.realtime or the complete session.{llm,stt,tts} pipeline are required. Realtime requires provider; its model may use the runtime default. A pipeline LLM may omit provider for a LiveKit-hosted model id. Credentials are write-only: integrations.google_analytics.api_secret, channels.web_chat.analytics.ga4.api_secret and recording.s3.{access_key,secret,session_token} come back as <key>_set: boolean, and a write that omits one keeps the stored value. Chat (web or WhatsApp) answers with channels.web_chat.llm, defaulting independently to openai/gpt-6.1-sol with medium reasoning; creating or enabling web chat, or changing that model while web chat or WhatsApp routing is live, is refused with 400 when chat has no adapter for its provider.

      5 attributes
      • agentobjectrequired

        1 attribute
        • instructionsstringrequired

      • toolsAssistantTools

        Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

        1 attribute
        • definitionsarray of AssistantToolDefinition

          6 attributes
          • namestringrequired

          • descriptionstring

          • parametersobject

            JSON Schema for the arguments, as exposed to the model.

          • enabledboolean

            False keeps the tool saved, with its request, but offers it on no channel.

            Default true

          • channelsarray of string

            Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

          • read_onlyboolean

            True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

            Default false

      • sessionanyrequired

        5 attributes
        • llmobject

          2 attributes
          • providerstringnot empty

          • modelstringrequirednot empty

        • realtimeobject

          2 attributes
          • providerstringrequirednot empty

          • modelstringnot empty

        • sttProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • ttsProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • toolsAssistantTools

          Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

          1 attribute
          • definitionsarray of AssistantToolDefinition

            6 attributes
            • namestringrequired

            • descriptionstring

            • parametersobject

              JSON Schema for the arguments, as exposed to the model.

            • enabledboolean

              False keeps the tool saved, with its request, but offers it on no channel.

              Default true

            • channelsarray of string

              Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

            • read_onlyboolean

              True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

              Default false

      • variablesarray of AssistantVariableDefup to 50 items

        Authoring-time schema for {{key}} placeholders in agent.instructions, agent.context, agent.first_message, and agent.first_message_instructions; never delivered to the runtime.

        4 attributes
        • keystringrequiredup to 64 characters

        • labelstringup to 120 characters

        • descriptionstringup to 500 characters

        • defaultstringup to 2000 characters

      • knowledgeobject

        The knowledge bases the assistant answers from, by knowledge base id (kb_...). Unlike the rest of the config, leaving it out of a write keeps the stored selection; send {} to detach every base. An entry with both chat and voice false counts as detached. Changing it needs an org-wide key and editor access to each base: 403 organization_knowledge_access_required for a project key or knowledge_forbidden without editor access, 400 knowledge_base_not_found for an unknown id, 409 knowledge_voice_requires_pipeline_assistant for voice on a realtime session. Each refusal names the base in knowledge_base_id.

        3 attributes
        • chatbooleanrequired

          Search it in web chat and WhatsApp.

        • voicebooleanrequired

          Search it on calls. Needs a pipeline session, not realtime.

        • priorityintegerrequired0 to 100

          Each search reaches up to four of the attached bases that have a live publication, highest priority first (then by id), and searches them in parallel.

    • versionintegerrequired

    • draft_revisioninteger

      The revision a draft save names as expected_draft_revision; 0 before the first draft.

    • draftobject | null

      Whether a draft exists, without its config (GET /assistants/{id}/draft has it).

      3 attributes
      • revisioninteger

      • base_versioninteger

      • updated_atstringISO 8601 timestamp

    • created_atstringISO 8601 timestamp

    • updated_atstringISO 8601 timestamp

  • 400 Validation error: usually invalid_request, with the failing fields in issues when there are any
  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 403 Refused, for example a read-only key on a write (read_only_key), a role too low for the route (insufficient_role), or a route that needs a console session
  • 404 Not found, or outside what the key can see
  • 409 Conflict
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
POST /api/assistants/{id}/publish
curl -X POST "https://api.myleadsfactory.tech/api/assistants/ASSISTANT_ID/publish" \
  -H "Authorization: Bearer $MLF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "expected_version": 1,
  "expected_draft_revision": 1
}'
Response 200
{
  "data": {
    "id": "asst_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "org_id": "org_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "project_id": "proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "name": "Front desk",
    "config": {
      "agent": {
        "instructions": "You answer enquiries for Acme Travel."
      },
      "tools": {
        "definitions": [
          {
            "name": {},
            "description": {},
            "parameters": {},
            "enabled": {},
            "channels": {},
            "read_only": {}
          }
        ]
      },
      "session": null,
      "variables": [
        {
          "key": "string",
          "label": "string",
          "description": "string",
          "default": "string"
        }
      ],
      "knowledge": {
        "key": {
          "chat": true,
          "voice": true,
          "priority": 1
        }
      }
    },
    "version": 1,
    "draft_revision": 1,
    "draft": {
      "revision": 1,
      "base_version": 1,
      "updated_at": "2026-10-28T09:30:00.000Z"
    },
    "created_at": "2026-10-28T09:30:00.000Z",
    "updated_at": "2026-10-28T09:30:00.000Z"
  }
}

List the assistant's config history

GET/api/assistants/{id}/versions

Every live config the assistant has had, newest first (the latest 100).

Secret API key. How it works

Path parameters

  • idstringrequired

Returns

200 OK

Response attributes
  • dataarray of AssistantVersionrequired

    8 attributes
    • assistant_idstringrequired

    • versionintegerrequired

    • namestring

    • sourcestringrequired

      One of create api_edit publish restore bulk_update seed

    • created_bystring | null

    • notestring | null

    • created_atstringISO 8601 timestamp

    • configAssistantConfig

      The runtime profile minus per-call fields. agent.instructions and either session.realtime or the complete session.{llm,stt,tts} pipeline are required. Realtime requires provider; its model may use the runtime default. A pipeline LLM may omit provider for a LiveKit-hosted model id. Credentials are write-only: integrations.google_analytics.api_secret, channels.web_chat.analytics.ga4.api_secret and recording.s3.{access_key,secret,session_token} come back as <key>_set: boolean, and a write that omits one keeps the stored value. Chat (web or WhatsApp) answers with channels.web_chat.llm, defaulting independently to openai/gpt-6.1-sol with medium reasoning; creating or enabling web chat, or changing that model while web chat or WhatsApp routing is live, is refused with 400 when chat has no adapter for its provider.

      5 attributes
      • agentobjectrequired

        1 attribute
        • instructionsstringrequired

      • toolsAssistantTools

        Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

        1 attribute
        • definitionsarray of AssistantToolDefinition

          6 attributes
          • namestringrequired

          • descriptionstring

          • parametersobject

            JSON Schema for the arguments, as exposed to the model.

          • enabledboolean

            False keeps the tool saved, with its request, but offers it on no channel.

            Default true

          • channelsarray of string

            Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

          • read_onlyboolean

            True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

            Default false

      • sessionanyrequired

        5 attributes
        • llmobject

          2 attributes
          • providerstringnot empty

          • modelstringrequirednot empty

        • realtimeobject

          2 attributes
          • providerstringrequirednot empty

          • modelstringnot empty

        • sttProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • ttsProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • toolsAssistantTools

          Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

          1 attribute
          • definitionsarray of AssistantToolDefinition

            6 attributes
            • namestringrequired

            • descriptionstring

            • parametersobject

              JSON Schema for the arguments, as exposed to the model.

            • enabledboolean

              False keeps the tool saved, with its request, but offers it on no channel.

              Default true

            • channelsarray of string

              Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

            • read_onlyboolean

              True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

              Default false

      • variablesarray of AssistantVariableDefup to 50 items

        Authoring-time schema for {{key}} placeholders in agent.instructions, agent.context, agent.first_message, and agent.first_message_instructions; never delivered to the runtime.

        4 attributes
        • keystringrequiredup to 64 characters

        • labelstringup to 120 characters

        • descriptionstringup to 500 characters

        • defaultstringup to 2000 characters

      • knowledgeobject

        The knowledge bases the assistant answers from, by knowledge base id (kb_...). Unlike the rest of the config, leaving it out of a write keeps the stored selection; send {} to detach every base. An entry with both chat and voice false counts as detached. Changing it needs an org-wide key and editor access to each base: 403 organization_knowledge_access_required for a project key or knowledge_forbidden without editor access, 400 knowledge_base_not_found for an unknown id, 409 knowledge_voice_requires_pipeline_assistant for voice on a realtime session. Each refusal names the base in knowledge_base_id.

        3 attributes
        • chatbooleanrequired

          Search it in web chat and WhatsApp.

        • voicebooleanrequired

          Search it on calls. Needs a pipeline session, not realtime.

        • priorityintegerrequired0 to 100

          Each search reaches up to four of the attached bases that have a live publication, highest priority first (then by id), and searches them in parallel.

  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
GET /api/assistants/{id}/versions
curl "https://api.myleadsfactory.tech/api/assistants/ASSISTANT_ID/versions" \
  -H "Authorization: Bearer $MLF_API_KEY"
Response 200
{
  "data": [
    {
      "assistant_id": "asst_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "version": 1,
      "name": "Front desk",
      "source": "create",
      "created_by": "string",
      "note": "string",
      "created_at": "2026-10-28T09:30:00.000Z",
      "config": {
        "agent": {
          "instructions": "You answer enquiries for Acme Travel."
        },
        "tools": {
          "definitions": [
            {}
          ]
        },
        "session": null,
        "variables": [
          {
            "key": {},
            "label": {},
            "description": {},
            "default": {}
          }
        ],
        "knowledge": {
          "key": {
            "chat": {},
            "voice": {},
            "priority": {}
          }
        }
      }
    }
  ]
}

Get one version of the assistant's config

GET/api/assistants/{id}/versions/{version}

The live config the assistant had at that version, as the history list returns it. 404 for a version not in its history.

Secret API key. How it works

Path parameters

  • idstringrequired

  • versionintegerrequired

Returns

200 OK

Response attributes
  • dataAssistantVersionrequired

    8 attributes
    • assistant_idstringrequired

    • versionintegerrequired

    • namestring

    • sourcestringrequired

      One of create api_edit publish restore bulk_update seed

    • created_bystring | null

    • notestring | null

    • created_atstringISO 8601 timestamp

    • configAssistantConfig

      The runtime profile minus per-call fields. agent.instructions and either session.realtime or the complete session.{llm,stt,tts} pipeline are required. Realtime requires provider; its model may use the runtime default. A pipeline LLM may omit provider for a LiveKit-hosted model id. Credentials are write-only: integrations.google_analytics.api_secret, channels.web_chat.analytics.ga4.api_secret and recording.s3.{access_key,secret,session_token} come back as <key>_set: boolean, and a write that omits one keeps the stored value. Chat (web or WhatsApp) answers with channels.web_chat.llm, defaulting independently to openai/gpt-6.1-sol with medium reasoning; creating or enabling web chat, or changing that model while web chat or WhatsApp routing is live, is refused with 400 when chat has no adapter for its provider.

      5 attributes
      • agentobjectrequired

        1 attribute
        • instructionsstringrequired

      • toolsAssistantTools

        Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

        1 attribute
        • definitionsarray of AssistantToolDefinition

          6 attributes
          • namestringrequired

          • descriptionstring

          • parametersobject

            JSON Schema for the arguments, as exposed to the model.

          • enabledboolean

            False keeps the tool saved, with its request, but offers it on no channel.

            Default true

          • channelsarray of string

            Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

          • read_onlyboolean

            True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

            Default false

      • sessionanyrequired

        5 attributes
        • llmobject

          2 attributes
          • providerstringnot empty

          • modelstringrequirednot empty

        • realtimeobject

          2 attributes
          • providerstringrequirednot empty

          • modelstringnot empty

        • sttProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • ttsProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • toolsAssistantTools

          Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

          1 attribute
          • definitionsarray of AssistantToolDefinition

            6 attributes
            • namestringrequired

            • descriptionstring

            • parametersobject

              JSON Schema for the arguments, as exposed to the model.

            • enabledboolean

              False keeps the tool saved, with its request, but offers it on no channel.

              Default true

            • channelsarray of string

              Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

            • read_onlyboolean

              True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

              Default false

      • variablesarray of AssistantVariableDefup to 50 items

        Authoring-time schema for {{key}} placeholders in agent.instructions, agent.context, agent.first_message, and agent.first_message_instructions; never delivered to the runtime.

        4 attributes
        • keystringrequiredup to 64 characters

        • labelstringup to 120 characters

        • descriptionstringup to 500 characters

        • defaultstringup to 2000 characters

      • knowledgeobject

        The knowledge bases the assistant answers from, by knowledge base id (kb_...). Unlike the rest of the config, leaving it out of a write keeps the stored selection; send {} to detach every base. An entry with both chat and voice false counts as detached. Changing it needs an org-wide key and editor access to each base: 403 organization_knowledge_access_required for a project key or knowledge_forbidden without editor access, 400 knowledge_base_not_found for an unknown id, 409 knowledge_voice_requires_pipeline_assistant for voice on a realtime session. Each refusal names the base in knowledge_base_id.

        3 attributes
        • chatbooleanrequired

          Search it in web chat and WhatsApp.

        • voicebooleanrequired

          Search it on calls. Needs a pipeline session, not realtime.

        • priorityintegerrequired0 to 100

          Each search reaches up to four of the attached bases that have a live publication, highest priority first (then by id), and searches them in parallel.

  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 404 Not found, or outside what the key can see
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
GET /api/assistants/{id}/versions/{version}
curl "https://api.myleadsfactory.tech/api/assistants/ASSISTANT_ID/versions/VERSION" \
  -H "Authorization: Bearer $MLF_API_KEY"
Response 200
{
  "data": {
    "assistant_id": "asst_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "version": 1,
    "name": "Front desk",
    "source": "create",
    "created_by": "string",
    "note": "string",
    "created_at": "2026-10-28T09:30:00.000Z",
    "config": {
      "agent": {
        "instructions": "You answer enquiries for Acme Travel."
      },
      "tools": {
        "definitions": [
          {
            "name": {},
            "description": {},
            "parameters": {},
            "enabled": {},
            "channels": {},
            "read_only": {}
          }
        ]
      },
      "session": null,
      "variables": [
        {
          "key": "string",
          "label": "string",
          "description": "string",
          "default": "string"
        }
      ],
      "knowledge": {
        "key": {
          "chat": true,
          "voice": true,
          "priority": 1
        }
      }
    }
  }
}

Restore a version

POST/api/assistants/{id}/versions/{version}/restore

Brings an old config back with today's credentials and tool auth: into the draft by default, or straight to live with target live.

Secret API key, not read-only. How it works

Path parameters

  • idstringrequired

  • versionintegerrequired

Request body

  • targetstring

    One of draft live

    Default "draft"

  • expected_versionintegermin 1

  • expected_draft_revisionintegermin 0

Returns

200 The draft it was restored into, or the assistant with target live.

Response attributes
  • dataAssistantDraft | null | Assistantrequired

    One of 2 shapes

    AssistantDraft

    • assistant_idstring

    • configAssistantConfig

      The runtime profile minus per-call fields. agent.instructions and either session.realtime or the complete session.{llm,stt,tts} pipeline are required. Realtime requires provider; its model may use the runtime default. A pipeline LLM may omit provider for a LiveKit-hosted model id. Credentials are write-only: integrations.google_analytics.api_secret, channels.web_chat.analytics.ga4.api_secret and recording.s3.{access_key,secret,session_token} come back as <key>_set: boolean, and a write that omits one keeps the stored value. Chat (web or WhatsApp) answers with channels.web_chat.llm, defaulting independently to openai/gpt-6.1-sol with medium reasoning; creating or enabling web chat, or changing that model while web chat or WhatsApp routing is live, is refused with 400 when chat has no adapter for its provider.

      5 attributes
      • agentobjectrequired

        1 attribute
        • instructionsstringrequired

      • toolsAssistantTools

        Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

        1 attribute
        • definitionsarray of AssistantToolDefinition

          6 attributes
          • namestringrequired

          • descriptionstring

          • parametersobject

            JSON Schema for the arguments, as exposed to the model.

          • enabledboolean

            False keeps the tool saved, with its request, but offers it on no channel.

            Default true

          • channelsarray of string

            Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

          • read_onlyboolean

            True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

            Default false

      • sessionanyrequired

        5 attributes
        • llmobject

          2 attributes
          • providerstringnot empty

          • modelstringrequirednot empty

        • realtimeobject

          2 attributes
          • providerstringrequirednot empty

          • modelstringnot empty

        • sttProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • ttsProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • toolsAssistantTools

          Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

          1 attribute
          • definitionsarray of AssistantToolDefinition

            6 attributes
            • namestringrequired

            • descriptionstring

            • parametersobject

              JSON Schema for the arguments, as exposed to the model.

            • enabledboolean

              False keeps the tool saved, with its request, but offers it on no channel.

              Default true

            • channelsarray of string

              Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

            • read_onlyboolean

              True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

              Default false

      • variablesarray of AssistantVariableDefup to 50 items

        Authoring-time schema for {{key}} placeholders in agent.instructions, agent.context, agent.first_message, and agent.first_message_instructions; never delivered to the runtime.

        4 attributes
        • keystringrequiredup to 64 characters

        • labelstringup to 120 characters

        • descriptionstringup to 500 characters

        • defaultstringup to 2000 characters

      • knowledgeobject

        The knowledge bases the assistant answers from, by knowledge base id (kb_...). Unlike the rest of the config, leaving it out of a write keeps the stored selection; send {} to detach every base. An entry with both chat and voice false counts as detached. Changing it needs an org-wide key and editor access to each base: 403 organization_knowledge_access_required for a project key or knowledge_forbidden without editor access, 400 knowledge_base_not_found for an unknown id, 409 knowledge_voice_requires_pipeline_assistant for voice on a realtime session. Each refusal names the base in knowledge_base_id.

        3 attributes
        • chatbooleanrequired

          Search it in web chat and WhatsApp.

        • voicebooleanrequired

          Search it on calls. Needs a pipeline session, not realtime.

        • priorityintegerrequired0 to 100

          Each search reaches up to four of the attached bases that have a live publication, highest priority first (then by id), and searches them in parallel.

    • hidden_changesarray of string

      Paths that differ from live but read back the same: credentials and tool request specs. Values are never returned.

    • revisioninteger

    • base_versioninteger

      The live version the draft started from.

    • live_versioninteger

    • staleboolean

      Live was edited after the draft started; publishing is refused.

    • updated_atstringISO 8601 timestamp

    Assistant

    • idstringrequired

    • org_idstringrequired

    • project_idstringrequired

    • namestringrequired

    • configAssistantConfigrequired

      The runtime profile minus per-call fields. agent.instructions and either session.realtime or the complete session.{llm,stt,tts} pipeline are required. Realtime requires provider; its model may use the runtime default. A pipeline LLM may omit provider for a LiveKit-hosted model id. Credentials are write-only: integrations.google_analytics.api_secret, channels.web_chat.analytics.ga4.api_secret and recording.s3.{access_key,secret,session_token} come back as <key>_set: boolean, and a write that omits one keeps the stored value. Chat (web or WhatsApp) answers with channels.web_chat.llm, defaulting independently to openai/gpt-6.1-sol with medium reasoning; creating or enabling web chat, or changing that model while web chat or WhatsApp routing is live, is refused with 400 when chat has no adapter for its provider.

      5 attributes
      • agentobjectrequired

        1 attribute
        • instructionsstringrequired

      • toolsAssistantTools

        Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

        1 attribute
        • definitionsarray of AssistantToolDefinition

          6 attributes
          • namestringrequired

          • descriptionstring

          • parametersobject

            JSON Schema for the arguments, as exposed to the model.

          • enabledboolean

            False keeps the tool saved, with its request, but offers it on no channel.

            Default true

          • channelsarray of string

            Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

          • read_onlyboolean

            True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

            Default false

      • sessionanyrequired

        5 attributes
        • llmobject

          2 attributes
          • providerstringnot empty

          • modelstringrequirednot empty

        • realtimeobject

          2 attributes
          • providerstringrequirednot empty

          • modelstringnot empty

        • sttProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • ttsProviderModel

          2 attributes
          • providerstringrequirednot empty

          • modelstringrequirednot empty

        • toolsAssistantTools

          Custom tools. config.tools is the canonical home; the legacy session.tools is read only when config.tools is absent.

          1 attribute
          • definitionsarray of AssistantToolDefinition

            6 attributes
            • namestringrequired

            • descriptionstring

            • parametersobject

              JSON Schema for the arguments, as exposed to the model.

            • enabledboolean

              False keeps the tool saved, with its request, but offers it on no channel.

              Default true

            • channelsarray of string

              Where the tool is offered: text is web chat and WhatsApp, voice is every call including browser test calls. Absent means both.

            • read_onlyboolean

              True when the tool only looks things up. Test and preview chats call only read-only tools; any other tool answers that requests are off in a test chat.

              Default false

      • variablesarray of AssistantVariableDefup to 50 items

        Authoring-time schema for {{key}} placeholders in agent.instructions, agent.context, agent.first_message, and agent.first_message_instructions; never delivered to the runtime.

        4 attributes
        • keystringrequiredup to 64 characters

        • labelstringup to 120 characters

        • descriptionstringup to 500 characters

        • defaultstringup to 2000 characters

      • knowledgeobject

        The knowledge bases the assistant answers from, by knowledge base id (kb_...). Unlike the rest of the config, leaving it out of a write keeps the stored selection; send {} to detach every base. An entry with both chat and voice false counts as detached. Changing it needs an org-wide key and editor access to each base: 403 organization_knowledge_access_required for a project key or knowledge_forbidden without editor access, 400 knowledge_base_not_found for an unknown id, 409 knowledge_voice_requires_pipeline_assistant for voice on a realtime session. Each refusal names the base in knowledge_base_id.

        3 attributes
        • chatbooleanrequired

          Search it in web chat and WhatsApp.

        • voicebooleanrequired

          Search it on calls. Needs a pipeline session, not realtime.

        • priorityintegerrequired0 to 100

          Each search reaches up to four of the attached bases that have a live publication, highest priority first (then by id), and searches them in parallel.

    • versionintegerrequired

    • draft_revisioninteger

      The revision a draft save names as expected_draft_revision; 0 before the first draft.

    • draftobject | null

      Whether a draft exists, without its config (GET /assistants/{id}/draft has it).

      3 attributes
      • revisioninteger

      • base_versioninteger

      • updated_atstringISO 8601 timestamp

    • created_atstringISO 8601 timestamp

    • updated_atstringISO 8601 timestamp

  • 400 Validation error: usually invalid_request, with the failing fields in issues when there are any
  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 403 Refused, for example a read-only key on a write (read_only_key), a role too low for the route (insufficient_role), or a route that needs a console session
  • 404 Not found, or outside what the key can see
  • 409 Conflict
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
POST /api/assistants/{id}/versions/{version}/restore
curl -X POST "https://api.myleadsfactory.tech/api/assistants/ASSISTANT_ID/versions/VERSION/restore" \
  -H "Authorization: Bearer $MLF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "target": "draft",
  "expected_version": 1
}'
Response 200
{
  "data": {
    "id": "asst_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "org_id": "org_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "project_id": "proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "name": "Front desk",
    "config": {
      "agent": {
        "instructions": "You answer enquiries for Acme Travel."
      },
      "tools": {
        "definitions": [
          {}
        ]
      },
      "session": null,
      "variables": [
        {
          "key": {},
          "label": {},
          "description": {},
          "default": {}
        }
      ],
      "knowledge": {
        "key": {
          "chat": {},
          "voice": {},
          "priority": {}
        }
      }
    },
    "version": 1,
    "draft_revision": 1,
    "draft": {
      "revision": 1,
      "base_version": 1,
      "updated_at": "2026-10-28T09:30:00.000Z"
    },
    "created_at": "2026-10-28T09:30:00.000Z",
    "updated_at": "2026-10-28T09:30:00.000Z"
  }
}