Lera API

v178 operations
https://leracore.com/openapi.json

Lera API Documentation

To use the API you need a secret key (lr_sk_) created from the panel, under Settings → API Keys. The full key is shown only once when you create it: store it then. It can be rotated keeping its name, and revoked whenever you want. Older keys starting with lera_sk_ keep working.

The key goes in the Authorization header of every request, as a Bearer token, and it is what identifies the workspace: no account id is passed. Do not publish it in the browser or in your website code; it is meant for server-to-server calls. If you suspect it has leaked, revoke it and create another.

Every catalogue operation is a POST with a JSON body, reads included. With no parameters, send an empty object. The routes that do not come from the catalogue (the catalogue itself and the partner ones) use their own method (GET, POST, PATCH or DELETE), shown on each row.

Base URL:

https://leracore.com

Every path on this page hangs off it. Append the path of each operation as is.

Examples of calls:

curl -H "Authorization: Bearer lr_sk_..." https://leracore.com/api/v1/tools
curl -X POST -H "Authorization: Bearer lr_sk_..." -H "Content-Type: application/json" \
  -d '{}' https://leracore.com/api/v1/tools/list_agents
curl -X POST -H "Authorization: Bearer lr_sk_..." -H "Content-Type: application/json" \
  -d '{"limit":10,"direction":"inbound"}' https://leracore.com/api/v1/tools/list_calls

If you import openapi.json into Postman, leave the body of read operations as {} or ask it to generate parameters from the examples. Generating them from the schema fills the filters with made-up values, and a query filtered by a value that does not exist returns an empty list.

MCP connector: build and operate your agents from your own assistant

https://leracore.com/mcp

Lera has a remote MCP server, nothing to install, with the same operations as this API and the same secret key in the Authorization header. It lets Claude Code, Cursor, VS Code, Codex or any MCP client build and manage your agents by talking with you.

It also carries the guide on how to build an agent that works (the lera_guide operation, with the recipes proven on real calls, the flow specification and the fix for every linter warning), the lera://guia/<topic> resources and the crear_agente, editar_flujo, revisar_agente and mejorar_desde_llamada prompts. The assistant reads it before building anything. With test_agent_chat it tests the draft by text with the same engine as the call before proposing a change, and with list_agent_versions and restore_agent_version it sets the draft back to an earlier published version.

Everything stays as a draft: the server never publishes an agent unless you ask. Each operation carries annotations (read-only, destructive) so your client asks for permission where it matters, and errors say what to fix.

Cursor allows about 40 operations across all its servers: with ?toolset=construir in the URL you see only the agent-building ones; with ?toolset=operar, calls, numbers and outbound; with no parameter, all of them. If your account is a partner, add the X-Lera-Client header as in the API.

Claude Code — It goes in terminal.

claude mcp add --transport http lera https://leracore.com/mcp --header "Authorization: Bearer lr_sk_…"

Cursor — It goes in ~/.cursor/mcp.json.

{
  "mcpServers": {
    "lera": {
      "url": "https://leracore.com/mcp?toolset=construir",
      "headers": { "Authorization": "Bearer lr_sk_…" }
    }
  }
}

VS Code — It goes in .vscode/mcp.json.

{
  "servers": {
    "lera": {
      "type": "http",
      "url": "https://leracore.com/mcp",
      "headers": { "Authorization": "Bearer lr_sk_…" }
    }
  }
}

Codex — It goes in ~/.codex/config.toml.

[mcp_servers.lera]
url = "https://leracore.com/mcp"
bearer_token_env_var = "LERA_API_KEY"
tool_timeout_sec = 120
# y en tu entorno: LERA_API_KEY=lr_sk_…

Key scope:

  • read — read only. Operations that write answer 403 insufficient_scope.
  • manage — reading and writing.
  • An expired account is read only through the API too: writes answer 402 account_read_only.
  • A suspended account does not operate through the API: everything answers 403 workspace_suspended.

Usage limits:

  • - 120 requests per minute per key and origin. Beyond that the answer is 429.

Partner accounts: one key for all your clients

  • - If your account is a partner account, the X-Lera-Client header makes the operation run against one of your clients. You do not need a key per client.
  • - X-Lera-Client: <workspace_id> — the operation runs against that client. The id comes from GET /api/v1/partner/clients.
  • - X-Lera-Client: all — reads only. The result comes labelled per client, under clients instead of result.
  • - The key must be issued from the root account. A client that does not hang off it answers 404 client_not_found, and all on a write answers 400 all_only_for_reads: fanning a write across your whole book in a single request is not allowed.

Errors

  • 401 unauthorized — The key is missing, malformed or has been revoked.
  • 401 api_key_expired — The key had an expiry date and it has passed.
  • 402 account_read_only — The account has expired: it can read, not write.
  • 403 insufficient_scope — A read-only key against an operation that writes.
  • 403 workspace_suspended — The account is suspended and does not operate.
  • 404 tool_not_found — That operation name does not exist.
  • 400 all_only_for_reads — X-Lera-Client: all on an operation that writes.
  • 403 not_a_partner — X-Lera-Client on an account that is not a partner. Partner access is requested in Settings → Company and Lera activates it.
  • 403 not_a_partner_root — The key was created inside a client, not in the root account.
  • 404 client_not_found — That client does not hang off your account.
  • 403 subprocessing_agreement_required — Creating a client without having accepted the current sub-processing agreement (Settings → Company).
  • 429 too_many_requests — The request limit has been exceeded.

Terms of useTrust CenterEmail us

Reference

Agents
READPOST /api/v1/tools/get_agentReturns the full configuration of an agent by id: prompt, voice, functions and limits.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.

Request

curl -X POST https://leracore.com/api/v1/tools/get_agent \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c..."
}'

Responses

CodeDescription
200
{
  "result": {
    "id": "cmk1a2b3c...",
    "name": "Recepción",
    "description": "Atiende el teléfono principal y coge citas",
    "kind": "voice",
    "mode": "conversation_flow",
    "status": "published",
    "language": "es"
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READPOST /api/v1/tools/lera_guideReturns the guide on how to build an agent that works: recipes proven on real calls (appointments, transfers, data collection, outbound, chat), the flow specification, how to build a knowledge base that finds things, and the linter warnings with their fix. Without a topic, the index.

Parameters

NameDescription
temastring(body)The guide topic. Recipes start with "receta-". Without it, the index of all topics.Values: receta-prompt-unico · receta-citas-calcom-flujo · receta-transferencia-prompt-unico · receta-transferencia-flujo · receta-recoger-datos · receta-saliente · receta-chat · trabajo · revisar-llamadas · analisis-post-llamada · crear-agente · flujos · nodos · recoger-datos · repaso · funciones · citas-calcom · transferencias · base-conocimiento · montar-base-conocimiento · comportamiento · modelo-y-latencia · numeros · canal-web · chat · linter · no-duplicar-motor · seguridad

Request

curl -X POST https://leracore.com/api/v1/tools/lera_guide \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "result": {
    "tema": "receta-citas-calcom-flujo",
    "titulo": "Receta: citas con Cal.com en un agente de flujo",
    "guia": "# Receta: citas con Cal.com en un agente de flujo\n\nCUANDO: ..."
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READPOST /api/v1/tools/list_agent_templatesReturns the agent templates available by industry, so you can start from one instead of a blank page.

Parameters

No parameters. Send an empty object.

Request

curl -X POST https://leracore.com/api/v1/tools/list_agent_templates \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "result": [
    {
      "key": "clinica",
      "name": "Clínica",
      "sector": "salud"
    }
  ]
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READPOST /api/v1/tools/list_agent_versionsLists the published versions of an agent, newest first, and marks the one currently answering.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.

Request

curl -X POST https://leracore.com/api/v1/tools/list_agent_versions \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c..."
}'

Responses

CodeDescription
200
{
  "result": {
    "agent_id": "cmk1a2b3c...",
    "status": "published",
    "versions": [
      { "id": "cmv4d5e6f...", "version": 4, "createdAt": "2026-10-06T10:12:00.000Z", "active": true },
      { "id": "cmv1a2b3c...", "version": 3, "createdAt": "2026-10-02T17:40:00.000Z", "active": false }
    ]
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READPOST /api/v1/tools/list_agentsReturns the workspace agents with their type, mode, status and source template.

Parameters

No parameters. Send an empty object.

Request

curl -X POST https://leracore.com/api/v1/tools/list_agents \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "result": [{
    "id": "cmk1a2b3c...",
    "name": "Recepción",
    "kind": "voice",
    "mode": "conversation_flow",
    "status": "published",
    "templateKey": "clinica",
    "updatedAt": "2026-09-01T10:00:00.000Z"
  }]
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READPOST /api/v1/tools/test_agent_chatTests an agent draft by text with the same engine as the call: returns what it would reply, which node the flow ends up in, the variables collected and the functions it would have called. Functions run in test mode and never touch your system. Stateless: to continue the conversation, pass the previous turns and the flow state returned by the previous turn. Limit of 30 messages per minute.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
message* requiredstring(body)
historyarray<object>(body)
flow_stateobject(body)Flow agents only: the flow object returned by the previous turn, as is. Without it, the test starts at the start node.

Request

curl -X POST https://leracore.com/api/v1/tools/test_agent_chat \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "message": "texto de ejemplo"
}'

Responses

CodeDescription
200
{
  "result": {
    "agent_id": "cmk1a2b3c...",
    "mode": "conversation_flow",
    "kind": "voice",
    "reply": "Claro, ¿para qué día le viene bien?",
    "flow": {
      "nodeId": "pedir-dia",
      "vars": { "servicio": "corte" },
      "visited": ["saludo", "pedir-dia"],
      "executedFunctions": []
    },
    "functionCalls": [],
    "ended": false,
    "descartes": []
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/tools/convert_agentConverts an agent to another type (voice or chat, single prompt or flow) by creating a new draft with its whole configuration, function keys included. The original stays unchanged.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
to* requiredstring(body)Values: voice · chat · single_prompt · conversation_flow

Request

curl -X POST https://leracore.com/api/v1/tools/convert_agent \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "to": "voice"
}'

Responses

CodeDescription
200
{
  "result": {
    "id": "cmk7c6d5e...",
    "name": "Recepción (chat)",
    "kind": "chat",
    "mode": "single_prompt",
    "status": "draft",
    "original_id": "cmk1a2b3c...",
    "perdidas": [{ "tipo": "herramienta_transferencia", "nombre": "pasar_a_recepcion" }],
    "siguiente_paso": "Revisa el prompt y el flujo del agente NUEVO (agent_id cmk7c6d5e...) y adapta lo que hablaba de llamadas..."
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/tools/create_agentCreates a draft voice agent. Given the business details, the prompt is generated to template quality.

Parameters

NameDescription
name* requiredstring(body)Agent name, to recognise it in the panel.
kindstring(body)Whether the agent is voice or chat.Values: voice · chat
modestring(body)How the agent is built: single prompt or node flow.Values: single_prompt · conversation_flow
template_keystring(body)Industry template to start from. Returned by list_agent_templates.
business_namestring(body)Real business name. Used in the greeting and in the prompt.
summarystring(body)What the business does, in one sentence. Used to generate the prompt.
servicesarray<string>(body)The business services. They feed the prompt and what the agent can offer.
tonestring(body)Tone the agent speaks with (warm, formal, direct…).
transferboolean(body)Whether the agent should be able to hand the call to a person.
promptstring(body)Agent instructions: what it does, what it asks and how it answers.
markdown_link_allowed_hostsarray<string>(body)
markdown_link_include_wwwboolean(body)
markdown_link_allow_httpboolean(body)

Request

curl -X POST https://leracore.com/api/v1/tools/create_agent \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "name": "texto de ejemplo",
  "kind": "voice",
  "mode": "single_prompt"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "agentId": "cmk1a2b3c...",
    "name": "Recepción",
    "status": "draft"
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/tools/duplicate_agentDuplicates an existing agent as a new draft, leaving the original untouched.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.

Request

curl -X POST https://leracore.com/api/v1/tools/duplicate_agent \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c..."
}'

Responses

CodeDescription
200
{
  "result": {
    "id": "cmk9z8y7x...",
    "name": "Recepción (copia)",
    "status": "draft"
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/tools/import_agentCreates an agent in this workspace from an exported JSON. Secrets have to be set again by hand.

Parameters

NameDescription
agent_export* requiredobject(body)The object export_agent returned, as is.

Request

curl -X POST https://leracore.com/api/v1/tools/import_agent \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_export": {}
}'

Responses

CodeDescription
200
{
  "result": {
    "id": "cmk9z8y7x...",
    "name": "Recepción",
    "status": "draft"
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
UPDATEPOST /api/v1/tools/export_agentExports an agent to portable JSON so you can move it to another workspace. Secrets come back redacted.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.

Request

curl -X POST https://leracore.com/api/v1/tools/export_agent \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c..."
}'

Responses

CodeDescription
200
{
  "result": {
    "version": 1,
    "agent": {
      "name": "Recepción",
      "kind": "voice",
      "mode": "conversation_flow"
    },
    "config": {
      "prompt": "...",
      "customTools": [
        {
          "url": "***"
        }
      ]
    }
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
UPDATEPOST /api/v1/tools/publish_agentPublishes the draft and creates an active version. Until you publish, calls keep using the previous version.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.

Request

curl -X POST https://leracore.com/api/v1/tools/publish_agent \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c..."
}'

Responses

CodeDescription
200
{
  "result": {
    "id": "cmk1a2b3c...",
    "status": "published",
    "version": 4
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
UPDATEPOST /api/v1/tools/restore_agent_versionSets the draft back to a previous published version. It does not publish: calls keep using the active version until you publish. Any unpublished draft is lost.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
version_id* requiredstring(body)

Request

curl -X POST https://leracore.com/api/v1/tools/restore_agent_version \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "version_id": "cmk1a2b3c..."
}'

Responses

CodeDescription
200
{
  "result": {
    "id": "cmk1a2b3c...",
    "restored_version": 3,
    "is_active_version": false,
    "nota": "El borrador es ahora esa versión. Lo publicado no cambia hasta publish_agent."
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
UPDATEPOST /api/v1/tools/set_business_hoursSets the business hours, time zone and special days. It does not switch the agent off: it informs it.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
enabledboolean(body)Set or remove the hours. Removing them does not switch the agent off.
time_zonestring(body)Time zone used to decide whether it is open.
weeklyarray<array>(body)The ranges for each day, Monday to Sunday. Seven lists, no more no less.
exceptionsarray<object>(body)Holidays and closures. They replace the weekly hours on those dates.

Request

curl -X POST https://leracore.com/api/v1/tools/set_business_hours \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "enabled": true,
  "time_zone": "texto de ejemplo"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "agentId": "cmk1a2b3c...",
    "days": 5,
    "exceptions": 2,
    "functions": [
      "consultar_pedido"
    ],
    "reminder": "Borrador actualizado: publica el agente para que el cambio entre en producción."
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
UPDATEPOST /api/v1/tools/set_call_recordingTurns call audio recording on or off. When on, the agent reads a fixed legal notice that cannot be removed.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
enabled* requiredboolean(body)Turns audio recording on or off for this agent calls.
purposestring(body)Why it is recorded. Stored alongside the consent.Values: calidad · contratacion · incidencias · formacion
retention_daysany(body)Days the audio is kept. It can only SHORTEN the workspace period.

Request

curl -X POST https://leracore.com/api/v1/tools/set_call_recording \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "enabled": true,
  "purpose": "calidad",
  "retention_days": "texto de ejemplo"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "agentId": "cmk1a2b3c...",
    "enabled": true,
    "functions": [
      "consultar_pedido"
    ],
    "reminder": "Borrador actualizado: publica el agente para que el cambio entre en producción."
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
UPDATEPOST /api/v1/tools/update_agentUpdates an agent draft: name, prompt, greeting, voice, model, behaviour and knowledge bases.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
namestring(body)Agent name, to recognise it in the panel.
promptstring(body)Agent instructions: what it does, what it asks and how it answers.
tonestring(body)Tone the agent speaks with (warm, formal, direct…).
agent_namestring(body)Name the agent introduces itself with when answering.
business_namestring(body)Real business name. Used in the greeting and in the prompt.
begin_messagestring(body)Fixed greeting phrase. Empty, the model improvises it on each call.
farewell_messagestring(body)Fixed farewell phrase. Empty, the model improvises it.
voice_providerstring(body)Voice provider. It determines which voices can be chosen.
voice_idstring(body)Voice id at its provider. Only voices belonging to the workspace.
modelstring(body)Agent language model. It drives latency and reliability.
greeting_enabledboolean(body)Whether the agent speaks first or waits for the caller.
greeting_interruptibleboolean(body)Whether the greeting can be interrupted.
end_chat_after_silence_msnumber(body)
auto_close_messagestring(body)
markdown_link_allowed_hostsarray<string>(body)
markdown_link_include_wwwboolean(body)
markdown_link_allow_httpboolean(body)
speak_when_silentboolean(body)On silence, it checks once whether the person is still there before hanging up.
knowledge_base_idsarray<string>(body)Ids of the knowledge bases assigned to the agent. Empty list removes them all.
kb_top_knumber(body)How many knowledge base chunks are retrieved per turn.
kb_min_scorenumber(body)Search similarity cut-off. Calibrated with SPOKEN language: raising it loses data that is there.
kb_instructionstring(body)Guidance for building the knowledge base query.
silence_reminder_secnumber(body)Seconds of silence before the agent asks if you are still there.
silence_hangup_secnumber(body)Seconds of silence after which it hangs up.
end_call_enabledboolean(body)Whether the agent can hang up by itself when done.
max_duration_secnumber(body)Maximum call duration. On reaching it, the call is cut.
transfer_modestring(body)How it hands the call to a person in a single-prompt agent.Values: none · phone · pending_request · phone_or_pending_request
transfer_e164string(body)Number it hands the call to, in E.164 format.
transfer_messagestring(body)Phrase said right before handing the call over.
transfer_toolsarray<object>(body)
agent_swap_toolsarray<object>(body)Single prompt only: tools that hand the conversation over to ANOTHER agent in the project. Same call and number; the destination carries on with the history. Replaces the whole list.
cold_transfer_modestring(body)How the call is handed over: give it to the carrier and leave, or bridge it.Values: sip_refer · sip_invite
responsivenessnumber(body)How long it waits after the last word. Higher answers sooner.
interruption_sensitivitynumber(body)How easily it can be interrupted. Low resists background noise; high cuts off at once.
enable_backchannelboolean(body)Whether the agent backchannels while the other speaks (“uh-huh”, “sure”).
backchannel_frequencynumber(body)How often it backchannels. High does it every few words.
backchannel_wordsarray<string>(body)Words it backchannels with.
post_call_analysisarray<object>(body)Fields extracted on their own from each call when it ends, besides the summary.
ai_disclosureboolean(body)Whether the greeting says it is a virtual assistant. Disclosing is the customer duty.
pii_categoriesarray<string>(body)Personal data ERASED from the transcript and summary on hangup.
voicemail_optionobject(body)What it does on an outbound call if voicemail picks up. Without it, it talks as if to a person.
voice_modelstring(body)Synthesis model. Only touch it for more quality or less latency.Values: eleven_turbo_v2 · eleven_turbo_v2_5 · eleven_flash_v2_5 · eleven_v4_turbo · eleven_flash_v2 · eleven_multilingual_v2 · eleven_v3 · sonic-3.6 · sonic-3 · sonic-3-latest · sonic-3.5
voice_speednumber(body)Speech speed. 1 is normal.
enable_expressive_modeboolean(body)
expressive_emotion_tagsarray<string>(body)
expressive_mode_promptany(body)
voice_temperaturenumber(body)Voice expressiveness. Low sounds steadier; high, more variable.
model_priorityboolean(body)
llm_temperaturenumber(body)How far the model strays from the most likely answer.
background_soundstring(body)Background ambience so the call does not sound sterile. null, none.Values: office
background_sound_volumenumber(body)How loud that ambience is. Only applies if one is set.
thinking_sound_volumenumber(body)
normalize_for_speechboolean(body)Turns figures and times into how they are said aloud. On by default.
languagestring(body)Language it answers calls in (es, en, fr). It belongs to the agent, not the panel.
volumenumber(body)Volume of the agent voice.
fallback_voice_idsarray<string>(body)Backup voices if its provider gives no audio. They must be from ANOTHER provider.
enable_dynamic_responsivenessboolean(body)Adjusts response speed on its own as the conversation goes.
enable_dynamic_voice_speedboolean(body)Adjusts speech speed on its own during the call.
keypadobject(body)Phone keypad: accepting keys pressed by the caller (on by default) and letting the agent press keys.
denoising_modestring(body)Clean-up of the audio the agent HEARS, not what the caller hears.Values: no-denoise · noise-cancellation · noise-and-background-speech-cancellation
stt_modestring(body)Fast (default) or accurate transcription: accurate waits a little longer for silence so dictated numbers arrive whole, at the cost of a slightly longer wait each turn.Values: fast · accurate
boosted_keywordsarray<string>(body)Words that are hard to transcribe and worth boosting (brands, surnames).
pronunciation_dictionaryarray<object>(body)How specific words are pronounced.
behaviorobject(body)Behaviour switches: do not invent data, repeat to confirm, ask to spell…

Request

curl -X POST https://leracore.com/api/v1/tools/update_agent \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "name": "texto de ejemplo",
  "prompt": "texto de ejemplo"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "agentId": "cmk1a2b3c...",
    "functions": [
      "consultar_pedido"
    ],
    "reminder": "Borrador actualizado: publica el agente para que el cambio entre en producción."
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
UPDATEPOST /api/v1/tools/write_agent_promptRegenerates the full prompt of an existing agent from the business details and saves it to the draft.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
business_namestring(body)Real business name. Used in the greeting and in the prompt.
summarystring(body)What the business does, in one sentence. Used to generate the prompt.
servicesarray<string>(body)The business services. They feed the prompt and what the agent can offer.
transferboolean(body)Whether the agent should be able to hand the call to a person.
template_keystring(body)Industry template to start from. Returned by list_agent_templates.

Request

curl -X POST https://leracore.com/api/v1/tools/write_agent_prompt \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "business_name": "texto de ejemplo",
  "summary": "texto de ejemplo"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "agentId": "cmk1a2b3c...",
    "functions": [
      "consultar_pedido"
    ],
    "reminder": "Borrador actualizado: publica el agente para que el cambio entre en producción."
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
Calls and analytics
READPOST /api/v1/tools/get_agent_latencyBreaks down the latency of an agent recent calls, end to end and by component.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
callsnumber(body)How many recent calls are looked at for the calculation.

Request

curl -X POST https://leracore.com/api/v1/tools/get_agent_latency \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c..."
}'

Responses

CodeDescription
200
{
  "result": {
    "agentId": "cmk1a2b3c...",
    "agentName": "Recepción",
    "mode": "conversation_flow",
    "model": "gpt-4.1-mini",
    "callsAnalizadas": 10,
    "e2e": {
      "p50": 1290,
      "p90": 1980
    }
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READPOST /api/v1/tools/get_analyticsReturns workspace analytics: totals, by status, by direction, by hour and average duration.

Parameters

No parameters. Send an empty object.

Request

curl -X POST https://leracore.com/api/v1/tools/get_analytics \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "result": {
    "totalCalls": 128,
    "byStatus": {
      "completed": 119,
      "failed": 9
    },
    "byDirection": {
      "inbound": 120,
      "outbound": 8
    },
    "byHour": {
      "10": 14,
      "11": 21
    },
    "averageDurationSeconds": 96
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READPOST /api/v1/tools/get_callReturns the detail of a call: summary, transcript, events and functions executed.

Parameters

NameDescription
call_id* requiredstring(body)Call id. Returned by list_calls.

Request

curl -X POST https://leracore.com/api/v1/tools/get_call \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "call_id": "cmk1a2b3c..."
}'

Responses

CodeDescription
200
{
  "result": {
    "id": "cmk...",
    "status": "completed",
    "direction": "inbound",
    "callerName": "Ana",
    "callerPhone": "+34600111222",
    "summary": "Pide cita para el jueves",
    "transcript": [
      {
        "role": "agent",
        "text": "Empresa Ejemplo, ¿en qué puedo ayudarte?"
      }
    ]
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READPOST /api/v1/tools/get_chatA whole chat agent conversation: the messages, the functions the agent ran, the summary and the analysis.

Parameters

NameDescription
chat_id* requiredstring(body)

Request

curl -X POST https://leracore.com/api/v1/tools/get_chat \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "chat_id": "cmk1a2b3c..."
}'

Responses

CodeDescription
200

Returns the outcome inside result.

{ "result": ... }

application/json; charset=utf-8

400Invalid request
403Forbidden
READPOST /api/v1/tools/get_concurrencyReturns how many calls are in progress and how many lines are free, to self-throttle your dialling.

Parameters

No parameters. Send an empty object.

Request

curl -X POST https://leracore.com/api/v1/tools/get_concurrency \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "result": {
    "current_concurrency": 1,
    "concurrency_limit": 5,
    "available": 4,
    "reserved_inbound_concurrency": 2,
    "available_for_outbound": 2,
    "limit_scope": "account"
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READPOST /api/v1/tools/list_callsReturns recent calls, filterable by status, direction and phone number. Up to 50 per request.

Parameters

NameDescription
statusstring(body)Filter by how the call ended.
directionstring(body)Whether the call came in or the agent placed it.Values: inbound · outbound
phonestring(body)Part of the caller phone number, to filter by.
limitnumber(body)Maximum number of results returned.

Request

curl -X POST https://leracore.com/api/v1/tools/list_calls \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "result": [
    {
      "id": "cmk...",
      "status": "completed",
      "direction": "inbound",
      "callerName": "Ana",
      "callerPhone": "+34600111222",
      "summary": "Pide cita para el jueves"
    }
  ]
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READPOST /api/v1/tools/list_chatsLists the recent conversations of your chat agents: status, channel (web or API), messages, summary and sentiment.

Parameters

NameDescription
agent_idstring(body)Agent id. Returned by list_agents.
statusstring(body)Values: ongoing · ended · error
limitnumber(body)Maximum number of results returned.

Request

curl -X POST https://leracore.com/api/v1/tools/list_chats \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200

Returns the outcome inside result.

{ "result": ... }

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/tools/start_outbound_callPlaces an outbound call. Variables are passed per call and interpolated into the prompt and functions.

Parameters

NameDescription
to_number* requiredstring(body)Number to call, in E.164 format (+34600111222).
agent_idstring(body)Agent placing the call. If omitted, the number outbound agent is used.
variablesobject(body)Values for this call only. They are interpolated into the prompt and functions.
idempotency_keystring(body)Your own key so retrying the same request does not place two calls.

Request

curl -X POST https://leracore.com/api/v1/tools/start_outbound_call \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "to_number": "+34600111222",
  "agent_id": "cmk1a2b3c...",
  "variables": {}
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "call_id": "cmk...",
    "to_number": "+34600111222",
    "duplicate": false
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
UPDATEPOST /api/v1/tools/set_inbound_concurrency_reservationReserves N concurrent lines for inbound phone calls: outbound and the web channel cannot take them.

Parameters

NameDescription
reserved* requirednumber(body)

Request

curl -X POST https://leracore.com/api/v1/tools/set_inbound_concurrency_reservation \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "reserved": 10
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "workspace_id": "cmk1a2b3c...",
    "workspace_name": "Mi empresa",
    "reserved_inbound_concurrency": 2,
    "concurrency_limit": 5,
    "available_for_outbound": 3,
    "clamped": false
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/web-callsOpens a browser call from your backend and returns the room token for your frontend.

Parameters

NameDescription
agent_id* requiredstring(body)Agent that takes the call. It must be published.
variablesobject(body)Per-call values, strings only. Only variables declared on the agent are accepted.

Request

curl -X POST https://leracore.com/api/v1/web-calls \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "call_id": "cmk...",
  "access_token": "eyJhbGciOi...",
  "livekit_url": "wss://....livekit.cloud",
  "max_duration_sec": 600
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/chatsOpens a conversation with a chat agent. Returns the chat and the welcome message, if the agent has one.

Parameters

NameDescription
agent_id* requiredstring(body)Chat agent that answers. It must be published.
variablesobject(body)Values for the agent, strings only. Only variables declared on the agent are accepted.
metadataobject(body)Anything you want to store with the conversation (your customer id, for example). It comes back in the webhook.

Request

curl -X POST https://leracore.com/api/v1/chats \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "chat": { "id": "cmk...", "agent_id": "cmk...", "channel": "api", "status": "ongoing" },
  "messages": [{ "id": "cmk...", "role": "agent", "content": "Hola, soy el asistente virtual...", "created_at": "2026-10-02T09:00:00.000Z" }]
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/chats/{id}/messagesSends a message and returns only what the agent replies. Charged per agent message.

Parameters

NameDescription
content* requiredstring(body)What the person writes. Up to 2,000 characters.

Request

curl -X POST https://leracore.com/api/v1/chats/{id}/messages \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "messages": [{ "id": "cmk...", "role": "agent", "content": "Abrimos de lunes a viernes de 7:00 a 22:00.", "created_at": "2026-10-02T09:00:05.000Z" }],
  "chat": { "id": "cmk...", "status": "ongoing", "agent_messages": 1 }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/chats/{id}/endCloses the conversation. It is charged and analysed when it closes. If you do not close it, it closes on its own after the agent’s idle time.

Parameters

No parameters. Send an empty object.

Request

curl -X POST https://leracore.com/api/v1/chats/{id}/end \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "chat": { "id": "cmk...", "status": "ended", "end_reason": "api", "agent_messages": 4 }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
Phone numbers
READPOST /api/v1/tools/get_forwarding_codesCodes to forward the business number to its Lera inbound line, by carrier and line type, with what the carrier charges for forwarding.

Parameters

NameDescription
operator* requiredstring(body)Values: movistar · vodafone · orange · yoigo · masmovil · digi · lowi · pepephone · o2 · jazztel · simyo · finetwork · avatel · euskaltel · adamo · unknown · other
line* requiredstring(body)Values: fixed · mobile
modestring(body)How the agent is built: single prompt or node flow.Values: unanswered · always
ring_secondsnumber(body)
phone_number_idstring(body)Phone number id. Returned by list_phone_numbers.

Request

curl -X POST https://leracore.com/api/v1/tools/get_forwarding_codes \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "operator": "movistar",
  "line": "fixed"
}'

Responses

CodeDescription
200
{
  "result": {
    "lera_line": "+34848000000",
    "dial_first": { "codes": ["##002#"], "text": "Primero quita tu buzón de voz..." },
    "codes": [
      { "type": "noAnswer", "activate": "**61*848000000#", "deactivate": "##61#", "check": "*#61#", "published_by_operator": true },
      { "type": "busy", "activate": "**67*848000000#", "deactivate": "##67#", "check": "*#67#", "published_by_operator": true },
      { "type": "unreachable", "activate": "**62*848000000#", "deactivate": "##62#", "check": "*#62#", "published_by_operator": true }
    ],
    "remove_all_at_once": "##002#",
    "voicemail_back": { "codes": ["**61*1222#", "**67*1222#", "**62*1222#"], "text": "Para volver a tener el buzón de voz, tu operador lo activa con:" },
    "operator_cost": "Cada llamada desviada es una llamada desde tu teléfono a tu línea de Lera, y se cobra según tu tarifa.",
    "source": "https://ayuda.jazztel.com/movil/servicios/1743-desvio-de-llamadas"
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READPOST /api/v1/tools/list_phone_numbersReturns the workspace numbers with their assigned agents, allowed countries and status.

Parameters

No parameters. Send an empty object.

Request

curl -X POST https://leracore.com/api/v1/tools/list_phone_numbers \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "result": [
    {
      "id": "cmk...",
      "label": "Centralita",
      "e164": "+34600333444",
      "provider": "sip",
      "status": "active",
      "inboundAgentId": "cmk1a2b3c...",
      "outboundAgentId": "cmk4d5e6f..."
    }
  ]
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/tools/check_phone_numberDiagnoses a number: whether it is connected, has an inbound agent, and whether that agent is published.

Parameters

NameDescription
phone_number_idstring(body)Phone number id. Returned by list_phone_numbers.
e164string(body)Number in E.164 format, with country prefix (+34600111222).

Request

curl -X POST https://leracore.com/api/v1/tools/check_phone_number \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "phone_number_id": "cmk1a2b3c...",
  "e164": "+34600111222"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "phone_number": {
      "id": "cmk...",
      "e164": "+34600333444",
      "status": "active"
    },
    "inbound_agent": {
      "id": "cmk1a2b3c...",
      "name": "Recepción",
      "status": "published"
    },
    "problems": []
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/tools/import_phone_numberImports a number you already own (Twilio, Telnyx or SIP) so Lera answers its calls.

Parameters

NameDescription
e164* requiredstring(body)Number in E.164 format, with country prefix (+34600111222).
providerstring(body)Where the number comes from: Twilio, Telnyx or a SIP PBX.Values: twilio · telnyx · sip · custom
labelstring(body)Alias to recognise the number in the panel.

Request

curl -X POST https://leracore.com/api/v1/tools/import_phone_number \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "e164": "+34600111222",
  "provider": "twilio",
  "label": "texto de ejemplo"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "phone_number": {
      "id": "cmk...",
      "e164": "+34600333444",
      "status": "active"
    },
    "next_step": "Asigna el agente que atiende con assign_inbound_agent."
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/tools/request_inbound_lineGives the workspace an inbound line instantly, to forward the business number to it. The account’s first line is included; each additional one has a monthly fee, deducted from the balance today and then every month.

Parameters

NameDescription
agent_idstring(body)Published voice agent that answers the line’s calls. Required if more than one is published.
labelstring(body)Line alias, to recognise it in the panel.
accept_line_feeboolean(body)Required for an additional line: you accept its monthly fee (monthly_fee_eur), deducted from your balance from today. Without it, the response is line_fee_not_accepted with the price and nothing is assigned, so repeating the request does not buy two.

Request

curl -X POST https://leracore.com/api/v1/tools/request_inbound_line \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "label": "texto de ejemplo"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "lera_line": "+34848000000",
    "included": false,
    "monthly_fee_eur": 3,
    "next_step": "Dale los códigos para desviar su número a esta línea con get_forwarding_codes."
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
UPDATEPOST /api/v1/tools/assign_inbound_agentSets which agent answers inbound calls on a number. Pass null to leave it without an agent.

Parameters

NameDescription
phone_number_id* requiredstring(body)Phone number id. Returned by list_phone_numbers.
agent_idstring(body)Agent id. Returned by list_agents.

Request

curl -X POST https://leracore.com/api/v1/tools/assign_inbound_agent \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "phone_number_id": "cmk1a2b3c...",
  "agent_id": "cmk1a2b3c..."
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "e164": "+34600333444",
    "inboundAgentId": "cmk1a2b3c..."
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
UPDATEPOST /api/v1/tools/assign_outbound_agentSets which agent places outbound calls from a number. Pass null to leave it without an agent.

Parameters

NameDescription
phone_number_id* requiredstring(body)Phone number id. Returned by list_phone_numbers.
agent_idstring(body)Agent id. Returned by list_agents.

Request

curl -X POST https://leracore.com/api/v1/tools/assign_outbound_agent \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "phone_number_id": "cmk1a2b3c...",
  "agent_id": "cmk1a2b3c..."
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "e164": "+34600333444",
    "outboundAgentId": "cmk1a2b3c..."
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
UPDATEPOST /api/v1/tools/reconnect_phone_numberRetries connecting a number to inbound calling. Use it if the diagnosis says it is not connected.

Parameters

NameDescription
phone_number_idstring(body)Phone number id. Returned by list_phone_numbers.
e164string(body)Number in E.164 format, with country prefix (+34600111222).

Request

curl -X POST https://leracore.com/api/v1/tools/reconnect_phone_number \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "phone_number_id": "cmk1a2b3c...",
  "e164": "+34600111222"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "e164": "+34600333444",
    "inbound_ready": true
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
DELETEPOST /api/v1/tools/release_inbound_lineReleases an inbound line: it stops receiving calls and being charged. The month already paid is not refunded. If it had received calls, it is kept for the same account for 30 days.

Parameters

NameDescription
e164string(body)The inbound line, in E.164 format. Optional if you pass phone_number_id or the workspace has only one.
phone_number_idstring(body)Phone number id. Returned by list_phone_numbers.

Request

curl -X POST https://leracore.com/api/v1/tools/release_inbound_line \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "e164": "+34600111222",
  "phone_number_id": "cmk1a2b3c..."
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "released": "+34848000000",
    "kept_for_you": true
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
Conversation flow
READPOST /api/v1/tools/check_transfersReports which transfers this account can actually perform. Check it before promising one to anyone.

Parameters

NameDescription
agent_idstring(body)Agent id. Returned by list_agents.

Request

curl -X POST https://leracore.com/api/v1/tools/check_transfers \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "result": {
    "cuenta": {
      "puede_derivar": true,
      "linea_de_salida": true
    },
    "agente": {
      "modo": "flujo",
      "donde_se_configura": "patch_transfer (cada derivación en su nodo)",
      "derivaciones": [
        {
          "nodeId": "pasar_persona",
          "destino": "+34600333444"
        }
      ]
    }
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READPOST /api/v1/tools/get_agent_flowReturns the draft node flow along with the available functions. Read it before editing.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.

Request

curl -X POST https://leracore.com/api/v1/tools/get_agent_flow \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c..."
}'

Responses

CodeDescription
200
{
  "result": {
    "id": "cmk1a2b3c...",
    "mode": "conversation_flow",
    "conversationFlow": {
      "startNodeId": "inicio",
      "nodes": [
        {
          "id": "inicio",
          "type": "conversation"
        }
      ]
    },
    "availableCustomTools": [
      {
        "name": "consultar_pedido",
        "description": "Busca el pedido"
      }
    ]
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/tools/attach_function_to_nodeOffers a function at a specific stage of the flow. In a flow agent, creating the function is not enough.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
node_id* requiredstring(body)Flow node id. Returned by get_agent_flow.
function_name* requiredstring(body)Name of the agent function. Returned by list_agent_functions.
run_on_enterboolean(body)Run the function ON ENTERING the node, without waiting for the model to ask.

Request

curl -X POST https://leracore.com/api/v1/tools/attach_function_to_node \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "node_id": "cmk1a2b3c...",
  "function_name": "texto de ejemplo",
  "run_on_enter": true
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "agentId": "cmk1a2b3c...",
    "functionName": "consultar_pedido",
    "nodeId": "consulta",
    "functions": [
      "consultar_pedido"
    ]
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
UPDATEPOST /api/v1/tools/patch_nodeChanges a single flow node without touching the rest: its prompt, type, model or knowledge bases.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
node_id* requiredstring(body)Flow node id. Returned by get_agent_flow.
promptstring(body)Agent instructions: what it does, what it asks and how it answers.
static_textstring(body)Fixed phrase the node says as is, without generating. The fastest option.
instruction_modestring(body)Whether the fixed phrase or the node prompt wins.Values: prompt · static
typestring(body)Node type. Only between dialogue with tools and clean dialogue.Values: conversation · subagent
namestring(body)New node name. It is injected into the prompt, so write it properly.
llm_modelstring(body)Model for this node only. Useful to put a stronger one where it matters.
is_globalboolean(body)Makes the node reachable from any stage without an arrow.
global_conditionstring(body)When that global node is jumped to, phrased from what the caller says.
global_cooldownnumber(body)Stages that must pass before that global can fire again.
knowledge_base_idsarray<string>(body)Ids of the knowledge bases assigned to the agent. Empty list removes them all.
kb_configobject(body)Fine tuning of the search for this node only. Overrides the agent field by field.
agent_swapobject(body)Agent_swap nodes only: which agent the conversation is handed to and how (version, entry node, analysis, voice, language, history, wait message). Merged with its current settings.
thinking_soundboolean(body)

Request

curl -X POST https://leracore.com/api/v1/tools/patch_node \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "node_id": "cmk1a2b3c...",
  "prompt": "texto de ejemplo",
  "static_text": "texto de ejemplo"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "agentId": "cmk1a2b3c...",
    "nodeId": "cierre",
    "fields": [
      "prompt"
    ],
    "functions": [
      "consultar_pedido"
    ]
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
UPDATEPOST /api/v1/tools/patch_transferChanges how an agent transfers: destination, extension, cold or warm handoff, and what the caller hears.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
node_idstring(body)Flow node id. Returned by get_agent_flow.
targetstring(body)Where the call goes: an E.164 number or a SIP address of the PBX.
destination_promptstring(body)Instead of a fixed destination, describes where each case goes and the model picks. Mutually exclusive with target.
extensionstring(body)Extension dialled on answer. Only works when bridging.
extra_targetsarray<object>(body)Backup destinations if the first one does not answer.
announce_next_targetboolean(body)Whether it warns the caller before trying the next destination.
next_target_messagestring(body)Phrase for that warning. Empty, the agent writes it.
transfer_typestring(body)Whether the call is handed over or the case is introduced first.Values: cold · warm · agentic
cold_transfer_modestring(body)How the call is handed over: give it to the carrier and leave, or bridge it.Values: sip_refer · sip_invite
caller_idstring(body)Which number the person receiving the transferred call sees.Values: trunk · caller
ring_duration_msnumber(body)How long the destination rings before being given up on.
speak_during_executionboolean(body)Whether the agent says something while the function runs, so the wait is not silence.
transfer_messagestring(body)Phrase said right before handing the call over.
human_detectionboolean(body)Check a person answered before introducing the case.
hold_musicstring(body)What the caller hears while waiting for the transfer.Values: none · hold_music · office_ambience · keyboard_typing
handoff_privatestring(body)What the agent tells the person BEFORE handing the call over.
handoff_publicstring(body)What is said in front of the caller during the handover.
allow_unvalidated_targetboolean(body)Accept a destination that is neither a number nor SIP, like a bare PBX extension.

Request

curl -X POST https://leracore.com/api/v1/tools/patch_transfer \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "node_id": "cmk1a2b3c...",
  "target": "texto de ejemplo"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "agentId": "cmk1a2b3c...",
    "nodeId": "pasar_persona",
    "fields": [
      "target"
    ],
    "functions": [
      "consultar_pedido"
    ],
    "reminder": "Borrador actualizado: publica el agente para que el cambio entre en producción."
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
UPDATEPOST /api/v1/tools/update_agent_flowReplaces the whole draft graph and switches the agent to flow mode. For a single node, use patch_node.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
conversation_flow* requiredobject(body)The whole graph: start node and node list. It replaces the previous flow.

Request

curl -X POST https://leracore.com/api/v1/tools/update_agent_flow \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "conversation_flow": {}
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "agentId": "cmk1a2b3c...",
    "nodes": 6,
    "functions": [
      "consultar_pedido"
    ],
    "reminder": "Borrador actualizado: publica el agente para que el cambio entre en producción."
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
DELETEPOST /api/v1/tools/detach_function_from_nodeStops offering a function at that node. It does not delete it from the agent.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
node_id* requiredstring(body)Flow node id. Returned by get_agent_flow.
function_name* requiredstring(body)Name of the agent function. Returned by list_agent_functions.

Request

curl -X POST https://leracore.com/api/v1/tools/detach_function_from_node \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "node_id": "cmk1a2b3c...",
  "function_name": "texto de ejemplo"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "agentId": "cmk1a2b3c...",
    "functionName": "consultar_pedido",
    "nodeId": "consulta",
    "functions": [
      "consultar_pedido"
    ]
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
Functions and calendar
READPOST /api/v1/tools/list_agent_functionsReturns an agent custom functions with their method, URL and parameters.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.

Request

curl -X POST https://leracore.com/api/v1/tools/list_agent_functions \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c..."
}'

Responses

CodeDescription
200
{
  "result": {
    "agentId": "cmk1a2b3c...",
    "functions": [
      {
        "name": "consultar_pedido",
        "description": "Busca el pedido por su número",
        "method": "POST",
        "url": "https://tu-sistema.example.com/pedidos"
      }
    ]
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READPOST /api/v1/tools/list_calcom_event_typesLists the event types of a Cal.com account so you can pick one. Read only: nothing is stored.

Parameters

NameDescription
api_key* requiredstring(body)The user Cal.com key. It is never returned when reading.

Request

curl -X POST https://leracore.com/api/v1/tools/list_calcom_event_types \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "api_key": "texto de ejemplo"
}'

Responses

CodeDescription
200
{
  "result": {
    "eventTypes": [
      {
        "id": 123456,
        "title": "Consulta 30 min",
        "length": 30
      }
    ]
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READPOST /api/v1/tools/list_calendar_functionsReturns an agent calendar connector and its event type. It never returns the Cal.com key.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.

Request

curl -X POST https://leracore.com/api/v1/tools/list_calendar_functions \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c..."
}'

Responses

CodeDescription
200
{
  "result": {
    "agentId": "cmk1a2b3c...",
    "connected": true,
    "functions": [
      {
        "name": "reservar_cita",
        "kind": "book",
        "provider": "calcom"
      }
    ]
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/tools/add_agent_functionAdds a function: during the call the agent makes a signed request to your URL. Up to 10 per agent.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
name* requiredstring(body)Function identifier: lowercase, no spaces.
description* requiredstring(body)When the agent should use this function.
url* requiredstring(body)URL of your system. It must be https and reachable from outside.
methodstring(body)HTTP method used to call your URL. POST by default.Values: GET · POST · PUT · PATCH · DELETE
headersarray<object>(body)Your own request headers. content-type and any starting with x-lera- are not allowed.
parametersarray<object>(body)Data the agent collects during the call and sends you in the request.
speak_during_executionboolean(body)Whether the agent says something while the function runs, so the wait is not silence.
wait_messagestring(body)Phrase the agent says while the function runs. Empty uses the engine default.
wait_after_msnumber(body)Milliseconds the function must take before the waiting phrase is said. 1000 recommended.
thinking_soundboolean(body)
speak_after_executionboolean(body)Whether the agent speaks after running it. With false the turn closes, unless it fails.
mock_responsestring(body)Test response for the panel. On a real call your URL is called.
response_capturesarray<object>(body)Fields of your response saved as variables to use later.
timeout_msnumber(body)Maximum wait for your system, in milliseconds.

Request

curl -X POST https://leracore.com/api/v1/tools/add_agent_function \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "name": "texto de ejemplo",
  "description": "texto de ejemplo",
  "url": "https://tu-sistema.example.com/consultar",
  "method": "GET",
  "headers": []
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "agentId": "cmk1a2b3c...",
    "functionName": "consultar_pedido",
    "functions": [
      "consultar_pedido"
    ]
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/tools/add_agent_messageLets the agent send an SMS, an email or a WhatsApp during the call. Email is sent by Lera; SMS and WhatsApp need your own provider connected.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
name* requiredstring(body)
channel* requiredstring(body)Values: sms · email · whatsapp
descriptionstring(body)
body_modestring(body)Values: static · prompt · template
body* requiredstring(body)
subjectstring(body)
template_keystring(body)Industry template to start from. Returned by list_agent_templates.
tostring(body)Values: caller · variable · fixed
to_varstring(body)
to_fixedstring(body)

Request

curl -X POST https://leracore.com/api/v1/tools/add_agent_message \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "name": "texto de ejemplo",
  "channel": "sms",
  "body": "texto de ejemplo",
  "description": "texto de ejemplo",
  "body_mode": "static"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "agentId": "cmk1a2b3c...",
    "channel": "sms"
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/tools/connect_calendarConnects Cal.com to an agent so it can check availability and book appointments during the call.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
api_key* requiredstring(body)The user Cal.com key. It is never returned when reading.
event_type_id* requiredstring(body)Cal.com event type to book. Returned by list_calcom_event_types.
timezonestring(body)Time zone used to read slots and book appointments.
availability_wait_messagestring(body)Phrase while checking slots. Empty uses the engine one, in the agent language.
book_wait_messagestring(body)Phrase while booking. Empty uses the engine one.

Request

curl -X POST https://leracore.com/api/v1/tools/connect_calendar \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "api_key": "texto de ejemplo",
  "event_type_id": "cmk1a2b3c...",
  "timezone": "texto de ejemplo",
  "availability_wait_message": "texto de ejemplo"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "agentId": "cmk1a2b3c...",
    "eventTypeId": "123456",
    "functions": [
      "consultar_disponibilidad",
      "reservar_cita"
    ]
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
UPDATEPOST /api/v1/tools/set_post_call_actionsSets what happens when the call ends: send a message or call one of your functions, with an optional condition on the analysis.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
actions* requiredarray<object>(body)

Request

curl -X POST https://leracore.com/api/v1/tools/set_post_call_actions \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "actions": []
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "agentId": "cmk1a2b3c...",
    "count": 2
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
UPDATEPOST /api/v1/tools/update_agent_functionEdits a function by name. Only what you pass changes; to rename it, delete it and create it again.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
name* requiredstring(body)Name of the function to edit.
descriptionstring(body)When the agent should use this function.
urlstring(body)URL of your system. It must be https and reachable from outside.
methodstring(body)HTTP method used to call your URL. POST by default.Values: GET · POST · PUT · PATCH · DELETE
headersarray<object>(body)Your own request headers. content-type and any starting with x-lera- are not allowed.
parametersarray<object>(body)Data the agent collects during the call and sends you in the request.
speak_during_executionboolean(body)Whether the agent says something while the function runs, so the wait is not silence.
wait_messagestring(body)Phrase the agent says while the function runs. Empty uses the engine default.
wait_after_msnumber(body)Milliseconds the function must take before the waiting phrase is said. 1000 recommended.
thinking_soundboolean(body)
speak_after_executionboolean(body)Whether the agent speaks after running it. With false the turn closes, unless it fails.
mock_responsestring(body)Test response for the panel. On a real call your URL is called.
response_capturesarray<object>(body)Fields of your response saved as variables to use later.
timeout_msnumber(body)Maximum wait for your system, in milliseconds.

Request

curl -X POST https://leracore.com/api/v1/tools/update_agent_function \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "name": "texto de ejemplo",
  "description": "texto de ejemplo",
  "url": "https://tu-sistema.example.com/consultar"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "agentId": "cmk1a2b3c...",
    "functionName": "consultar_pedido",
    "functions": [
      "consultar_pedido"
    ]
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
DELETEPOST /api/v1/tools/remove_agent_functionDeletes a function from the agent and removes it from any flow stage that used it.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
name* requiredstring(body)Name of the function to delete.

Request

curl -X POST https://leracore.com/api/v1/tools/remove_agent_function \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "name": "texto de ejemplo"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "agentId": "cmk1a2b3c...",
    "functionName": "consultar_pedido",
    "functions": []
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
DELETEPOST /api/v1/tools/remove_calendar_functionsDisconnects the calendar from an agent. Remember to publish afterwards.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.

Request

curl -X POST https://leracore.com/api/v1/tools/remove_calendar_functions \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c..."
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "agentId": "cmk1a2b3c...",
    "functions": [
      "consultar_pedido"
    ]
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
Knowledge base
READPOST /api/v1/tools/discover_siteDiscovers a site pages from its sitemap so you can decide which to add. Read only: nothing is created.

Parameters

NameDescription
url* requiredstring(body)URL of your system. It must be https and reachable from outside.

Request

curl -X POST https://leracore.com/api/v1/tools/discover_site \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://tu-sistema.example.com/consultar"
}'

Responses

CodeDescription
200
{
  "result": {
    "pages": [
      {
        "url": "https://example.com/precios",
        "title": "Precios"
      }
    ]
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READPOST /api/v1/tools/list_knowledgeReturns the project knowledge entries (title and answer). An agent only uses them in the flow nodes that reference them; what it looks up during the conversation are its knowledge bases (list_knowledge_bases).

Parameters

No parameters. Send an empty object.

Request

curl -X POST https://leracore.com/api/v1/tools/list_knowledge \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "result": [
    {
      "id": "cmk...",
      "title": "Horario",
      "scope": "workspace",
      "status": "published",
      "keywords": [
        "horario"
      ],
      "answer": "De 9 a 18 de lunes a viernes."
    }
  ]
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READPOST /api/v1/tools/list_knowledge_basesReturns the project knowledge bases with their status and documents.

Parameters

No parameters. Send an empty object.

Request

curl -X POST https://leracore.com/api/v1/tools/list_knowledge_bases \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "result": [
    {
      "id": "cmk...",
      "name": "Web de la clínica",
      "status": "ready",
      "documentos": [
        {
          "id": "cmk...",
          "kind": "url",
          "title": "Precios",
          "status": "ready",
          "url": "https://example.com/precios"
        }
      ]
    }
  ]
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READPOST /api/v1/tools/test_knowledge_searchTries a question against the knowledge base the way the agent would search it: what is searched for, which chunks come up with their similarity, and which ones would reach the agent or are left out and why. Changes nothing.

Parameters

NameDescription
question* requiredstring(body)The question, written the way the person would say it.
agent_idstring(body)The agent whose bases and settings are used (those of its draft).
node_idstring(body)Flow agents only: the node whose bases are added to the agent’s.
knowledge_base_idsarray<string>(body)Without agent_id: the bases to try, with the default settings.

Request

curl -X POST https://leracore.com/api/v1/tools/test_knowledge_search \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "question": "texto de ejemplo"
}'

Responses

CodeDescription
200
{
  "result": {
    "pregunta": "¿Qué horario tenéis el sábado?",
    "consulta": "¿Qué horario tenéis el sábado?",
    "condensada": false,
    "canal": "voz",
    "topK": 3,
    "minScore": 0.28,
    "bases": 1,
    "fragmentos": [
      {
        "documento": "Horario del sábado",
        "fuenteId": "cmk...",
        "baseId": "cmk...",
        "puntuacion": 0.61,
        "entra": true,
        "texto": "La piscina abre los sábados de 9:00 a 14:00."
      },
      {
        "documento": "Precios",
        "fuenteId": "cmk...",
        "baseId": "cmk...",
        "puntuacion": 0.19,
        "entra": false,
        "fuera": "parecido_bajo",
        "texto": "La entrada cuesta 5 euros."
      }
    ]
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/tools/add_knowledgeAdds a knowledge entry (title and answer). Only the flow nodes that reference it read it: for an agent to know something, add a document to its knowledge base with add_knowledge_source.

Parameters

NameDescription
title* requiredstring(body)Title it is identified and searched by.
answer* requiredstring(body)The information the agent gives when answering.
keywordsarray<string>(body)Words this entry is found by.

Request

curl -X POST https://leracore.com/api/v1/tools/add_knowledge \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "title": "texto de ejemplo",
  "answer": "texto de ejemplo",
  "keywords": []
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "entryId": "cmk...",
    "title": "Horario",
    "action": "add"
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/tools/add_knowledge_sourceAdds a document to a base: text or a web page, which is re-read on its own every 12 hours.

Parameters

NameDescription
knowledge_base_id* requiredstring(body)Knowledge base id. Returned by list_knowledge_bases.
kind* requiredstring(body)Whether the document is pasted text or a web page.Values: text · url
titlestring(body)Title it is identified and searched by.
textstring(body)The pasted content, when the document is text.
urlstring(body)URL of your system. It must be https and reachable from outside.

Request

curl -X POST https://leracore.com/api/v1/tools/add_knowledge_source \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "knowledge_base_id": "cmk1a2b3c...",
  "kind": "text",
  "title": "texto de ejemplo",
  "text": "texto de ejemplo"
}'

Responses

CodeDescription
200
{
  "result": {
    "id": "cmk...",
    "kind": "text",
    "title": "Precios",
    "status": "processing"
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/tools/analyze_websiteReads the business website and extracts name, activity, services, FAQs, tone and a suggested greeting.

Parameters

NameDescription
url* requiredstring(body)URL of your system. It must be https and reachable from outside.

Request

curl -X POST https://leracore.com/api/v1/tools/analyze_website \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://tu-sistema.example.com/consultar"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "url": "https://example.com",
    "businessName": "Empresa Ejemplo",
    "summary": "Servicio de ejemplo para la documentación",
    "services": [
      "Limpieza",
      "Ortodoncia"
    ],
    "faqs": [
      {
        "q": "¿Tenéis parking?",
        "a": "Sí, gratuito."
      }
    ]
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/tools/create_knowledge_baseCreates an empty knowledge base. Documents are added afterwards and it is assigned to an agent.

Parameters

NameDescription
name* requiredstring(body)Knowledge base name.

Request

curl -X POST https://leracore.com/api/v1/tools/create_knowledge_base \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "name": "texto de ejemplo"
}'

Responses

CodeDescription
200
{
  "result": {
    "id": "cmk...",
    "name": "Web de la clínica",
    "status": "empty"
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
UPDATEPOST /api/v1/tools/update_knowledgeEdits a knowledge entry by id. Only the fields you pass change.

Parameters

NameDescription
id* requiredstring(body)Knowledge entry id. Returned by list_knowledge.
titlestring(body)Title it is identified and searched by.
answerstring(body)The information the agent gives when answering.
keywordsarray<string>(body)Words this entry is found by.
statusstring(body)Whether the entry is published or kept as a draft.Values: draft · published

Request

curl -X POST https://leracore.com/api/v1/tools/update_knowledge \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "id": "cmk1a2b3c...",
  "title": "texto de ejemplo",
  "answer": "texto de ejemplo"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "entryId": "cmk...",
    "title": "Horario",
    "action": "update"
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
DELETEPOST /api/v1/tools/remove_knowledgeDeletes a knowledge entry by id. To remove a document from a knowledge base, use remove_knowledge_source.

Parameters

NameDescription
id* requiredstring(body)Knowledge entry id. Returned by list_knowledge.

Request

curl -X POST https://leracore.com/api/v1/tools/remove_knowledge \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "id": "cmk1a2b3c..."
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "entryId": "cmk...",
    "action": "remove"
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
DELETEPOST /api/v1/tools/remove_knowledge_sourceRemoves a document from a base and deletes its chunks, so the agent can no longer answer from it.

Parameters

NameDescription
knowledge_base_id* requiredstring(body)Knowledge base id. Returned by list_knowledge_bases.
source_id* requiredstring(body)Document id inside the base. Returned by list_knowledge_bases.

Request

curl -X POST https://leracore.com/api/v1/tools/remove_knowledge_source \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "knowledge_base_id": "cmk1a2b3c...",
  "source_id": "cmk1a2b3c..."
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "id": "cmk..."
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
Variables and pre-call webhook
READPOST /api/v1/tools/get_pre_call_webhookReturns the pre-call webhook configuration. Of the headers, only the names are returned.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.

Request

curl -X POST https://leracore.com/api/v1/tools/get_pre_call_webhook \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c..."
}'

Responses

CodeDescription
200
{
  "result": {
    "agentId": "cmk1a2b3c...",
    "configurado": true,
    "url": "https://tu-sistema.example.com/quien-llama",
    "presupuesto_ms": 2500,
    "canales": [
      "phone_inbound"
    ],
    "se_le_permite_devolver": [
      "variables"
    ],
    "si_falla": "se atiende igual con el agente por defecto"
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/tools/add_call_variableAdds a call variable, usable as {{name}} in the greeting, the instructions and the functions.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
name* requiredstring(body)Variable name. Used as {{name}} in the prompt and functions.
descriptionstring(body)What the variable holds, so the agent knows how to use it.
default_valuestring(body)Value the variable takes if the call brings no other.

Request

curl -X POST https://leracore.com/api/v1/tools/add_call_variable \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "name": "texto de ejemplo",
  "description": "texto de ejemplo",
  "default_value": "texto de ejemplo"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "agentId": "cmk1a2b3c...",
    "variableName": "nombre_cliente",
    "functions": [
      "consultar_pedido"
    ]
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/tools/test_pre_call_webhookFires the webhook with a sample number and shows what your system replies, without placing a call.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
from_numberstring(body)Sample number the test is fired with.

Request

curl -X POST https://leracore.com/api/v1/tools/test_pre_call_webhook \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "from_number": "+34600111222"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "respondio": true,
    "ms": 412,
    "intentos": 1,
    "variables_que_devuelve": [
      "nombre_cliente",
      "ultimo_pedido"
    ],
    "problemas": []
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
UPDATEPOST /api/v1/tools/set_pre_call_webhookSets the URL Lera asks who is calling before answering, so the greeting already knows the name.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
url* requiredstring(body)URL of your system. It must be https and reachable from outside.
budget_msnumber(body)TOTAL wait limit. It is silence on the line: do not raise it without reason.
channelsarray<string>(body)Which doors it asks at: inbound phone, web widget or outbound.
allowarray<string>(body)What your system is allowed to return. By default, variables only.
on_failurestring(body)What happens if your endpoint does not answer: take the call anyway, or not.Values: continue · reject

Request

curl -X POST https://leracore.com/api/v1/tools/set_pre_call_webhook \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "url": "https://tu-sistema.example.com/consultar",
  "budget_ms": 1000,
  "channels": []
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "agentId": "cmk1a2b3c...",
    "host": "tu-sistema.example.com",
    "functions": [
      "consultar_pedido"
    ],
    "siguiente_paso": "Pruébalo con test_pre_call_webhook antes de publicar.",
    "reminder": "Borrador actualizado: publica el agente para que el cambio entre en producción."
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
UPDATEPOST /api/v1/tools/update_call_variableEdits a call variable by name. Only what you pass changes.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
name* requiredstring(body)Name of the variable to edit.
descriptionstring(body)What the variable holds.
default_valuestring(body)Value the variable takes if the call brings no other.

Request

curl -X POST https://leracore.com/api/v1/tools/update_call_variable \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "name": "texto de ejemplo",
  "description": "texto de ejemplo",
  "default_value": "texto de ejemplo"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "agentId": "cmk1a2b3c...",
    "variableName": "nombre_cliente",
    "functions": [
      "consultar_pedido"
    ]
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
DELETEPOST /api/v1/tools/remove_call_variableDeletes a call variable from an agent.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.
name* requiredstring(body)Name of the variable to delete.

Request

curl -X POST https://leracore.com/api/v1/tools/remove_call_variable \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c...",
  "name": "texto de ejemplo"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "agentId": "cmk1a2b3c...",
    "variableName": "nombre_cliente",
    "functions": [
      "consultar_pedido"
    ]
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
DELETEPOST /api/v1/tools/remove_pre_call_webhookRemoves the pre-call webhook. The agent stops knowing who is calling before answering.

Parameters

NameDescription
agent_id* requiredstring(body)Agent id. Returned by list_agents.

Request

curl -X POST https://leracore.com/api/v1/tools/remove_pre_call_webhook \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "cmk1a2b3c..."
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "agentId": "cmk1a2b3c...",
    "functions": [
      "consultar_pedido"
    ],
    "reminder": "Borrador actualizado: publica el agente para que el cambio entre en producción."
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
Do-not-call list
READPOST /api/v1/tools/list_optout_numbersReturns the numbers excluded from outbound calling.

Parameters

No parameters. Send an empty object.

Request

curl -X POST https://leracore.com/api/v1/tools/list_optout_numbers \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "result": {
    "numbers": [{
      "e164": "+34600111222",
      "reason": "pidió no recibir más llamadas",
      "createdAt": "2026-08-14T09:12:00.000Z"
    }]
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/tools/add_optout_numberExcludes a number from outbound calling: the agent will never call it again.

Parameters

NameDescription
e164* requiredstring(body)Number in E.164 format, with country prefix (+34600111222).
reasonstring(body)Why the number is excluded. It is recorded.

Request

curl -X POST https://leracore.com/api/v1/tools/add_optout_number \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "e164": "+34600111222",
  "reason": "texto de ejemplo"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "e164": "+34600111222"
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
DELETEPOST /api/v1/tools/remove_optout_numberRemoves a number from the do-not-call list, making it callable again.

Parameters

NameDescription
e164* requiredstring(body)Number in E.164 format, with country prefix (+34600111222).

Request

curl -X POST https://leracore.com/api/v1/tools/remove_optout_number \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "e164": "+34600111222"
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "e164": "+34600111222"
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
Account and web channel
READPOST /api/v1/tools/get_billing_summaryReturns the month usage (voice minutes, and chats and messages of the chat agent), the balance and the workspace limits. In a child project, the balance comes empty.

Parameters

No parameters. Send an empty object.

Request

curl -X POST https://leracore.com/api/v1/tools/get_billing_summary \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "result": {
    "isBillingChild": false,
    "balanceCents": 4210,
    "minutesUsed": 312.5,
    "chatsThisMonth": 41,
    "chatMessagesUsed": 268
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READPOST /api/v1/tools/get_web_embed_codeReturns the code (<script>) to put your agent on your website. With voice_agent_id visitors can call; with chat_agent_id they can write; with both, they choose from the same button. It has a placeholder for your public key, which you copy from Settings → API Keys → Public Keys.

Parameters

NameDescription
voice_agent_idstring(body)The voice agent that takes the call from the website. Optional if you give chat_agent_id.
chat_agent_idstring(body)The chat agent that answers in writing. Optional if you give voice_agent_id.
agent_idstring(body)Any agent: it goes to the channel of its kind (voice or chat). A shortcut when you only put one.

Request

curl -X POST https://leracore.com/api/v1/tools/get_web_embed_code \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "result": {
    "agents": {
      "voice": { "id": "cmk...", "name": "Recepción", "kind": "voice", "published": true },
      "chat": { "id": "cmq...", "name": "Chat recepción", "kind": "chat", "published": true }
    },
    "snippet": "<script src=\"https://leracore.com/widget/lera-widget.v1.js\" type=\"module\" data-public-key=\"TU_CLAVE_PUBLICA\" data-voice-agent-id=\"cmk...\" data-chat-agent-id=\"cmq...\" data-theme-color=\"#0033A0\"></script>",
    "where_is_the_key": "Ajustes -> API Keys -> pestaña Public Keys",
    "keys": [{ "name": "Web pública", "prefix": "lr_pk_a1b2c3d4", "allowedOrigins": ["https://example.com"] }]
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READPOST /api/v1/tools/list_integrationsReturns the project integrations and their status. Today there is the post-call webhook.

Parameters

No parameters. Send an empty object.

Request

curl -X POST https://leracore.com/api/v1/tools/list_integrations \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "result": [
    {
      "id": "cmk...",
      "type": "post_call_webhook",
      "status": "connected",
      "displayName": "Webhook de mi ERP"
    }
  ]
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READPOST /api/v1/tools/list_widget_keysReturns the web channel keys with their allowed sites and last use. Useful to diagnose the widget.

Parameters

No parameters. Send an empty object.

Request

curl -X POST https://leracore.com/api/v1/tools/list_widget_keys \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "result": [
    {
      "id": "cmk...",
      "name": "Web pública",
      "prefix": "lr_pk_a1b2c3d4",
      "allowedOrigins": [
        "https://example.com"
      ],
      "requireCaptcha": false,
      "lastUsedAt": "2026-09-05T18:22:00.000Z"
    }
  ]
}

application/json; charset=utf-8

400Invalid request
403Forbidden
UPDATEPOST /api/v1/tools/set_post_call_webhookSets the URL Lera sends every finished call to, with its summary, transcript and extracted data.

Parameters

NameDescription
url* requiredstring(body)URL of your system. It must be https and reachable from outside.
enabledboolean(body)Turn sending on or off without losing the URL. Defaults to true.

Request

curl -X POST https://leracore.com/api/v1/tools/set_post_call_webhook \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://tu-sistema.example.com/consultar",
  "enabled": true
}'

Responses

CodeDescription
200
{
  "result": {
    "ok": true,
    "id": "cmk...",
    "type": "webhook",
    "status": "enabled",
    "url": "https://tu-sistema.example.com/llamadas"
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
Partner accounts
READGET /api/v1/partner/clientsEvery client of the partner account with their minutes, their chats and messages (closed chats and agent replies in them), the calls their agent handed to a person through a Lera line with their amount (transfers and transfer_fee_cents, already inside cost_cents) and cost for the requested period, or the current month if you ask for none, to pass on to their invoice. The balance belongs to the account; what is broken down per client is the usage. The key must be issued from the root account: one created inside a client answers 403 not_a_partner_root. In the panel, the same lives under Settings → Clients.

Parameters

NameDescription
fromstring(query)Start of the period, in ISO 8601. Without it, the current month. To invoice a closed month, pass it.
tostring(query)End of the period, in ISO 8601 and exclusive. Without it, right now.

Request

curl "https://leracore.com/api/v1/partner/clients?from=...&to=..." \
  -H "Authorization: Bearer lr_sk_..."

Responses

CodeDescription
200
{
  "partner": { "workspace_id": "cmk...", "name": "Integrador" },
  "period": { "from": "2026-09-01T00:00:00.000Z", "to": "2026-09-07T12:00:00.000Z" },
  "clients": [{
    "workspace_id": "cmk...",
    "name": "Empresa Ejemplo",
    "slug": "empresa-ejemplo",
    "status": "ACTIVE",
    "external_id": "erp-4821",
    "phone_number": "+34600333444",
    "minutes": 128.4,
    "chats": 41,
    "chat_messages": 268,
    "cost_cents": 1794,
    "transfers": 6,
    "transfer_fee_cents": 180,
    "white_label": true,
    "max_concurrent_calls": 3,
    "monthly_cost_limit_cents": 5000,
    "monthly_minute_limit": null,
    "monthly_message_limit": null,
    "monthly_limit_action": "notify"
  }]
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/partner/clientsCreate a client in your partner account from your own system, without going through the panel. Sending external_id makes the call idempotent, so you can retry without creating duplicates: if that id already exists, it answers 200 with created=false and the existing client. The client hangs from your account, shares your balance and shows up in your console with its own usage. The key must be a manage key issued from the root account.

Parameters

NameDescription
name* requiredstring(body)Client name, as you will see it in your console.
external_idstring(body)The id that client has in YOUR system. If you send it, creation is idempotent: repeating the call returns the existing client instead of creating another.
contact_emailstring(body)The client’s contact email (the client company’s, not yours).
contact_first_namestring(body)First name of the client’s contact person.
contact_last_namestring(body)Last name of the client’s contact person.
included_minutesinteger(body)Their monthly plan in MINUTES, for voice. They renew on their own every month on the service start day. Setting it switches "on exhausted" to block.
included_messagesinteger(body)Their monthly plan in MESSAGES, for chat: a message is one agent reply. Separate from the minutes. Setting it switches chat to block.
included_transfersinteger(body)Calls handed to a person through an inbound line included per month, inside the voice agent: they share its start day. When used up the agent keeps handing them over and we email you; each extra one counts as overage. Only calls through an inbound line we provide count; through the client’s own number they do not.
cycle_startstring(body)Service start day (ISO 8601). Defaults to today. Applies to voice and chat, unless you send messages_cycle_start.
messages_cycle_startstring(body)Service start day for chat (ISO 8601), if it is not the same as the voice one.

Request

curl -X POST https://leracore.com/api/v1/partner/clients \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "created": true,
  "client": {
    "workspace_id": "cmk...",
    "name": "Colegio de Medicos",
    "slug": "colegio-de-medicos",
    "status": "ACTIVE",
    "external_id": "erp-4821",
    "contact_email": "secretaria@colegio.example",
    "contact_first_name": "Ana",
    "contact_last_name": "Pérez",
    "phone_number": null,
    "minutes": 0,
    "chats": 0,
    "chat_messages": 0,
    "cost_cents": 0,
    "white_label": true,
    "max_concurrent_calls": null,
    "monthly_cost_limit_cents": null,
    "monthly_minute_limit": null,
    "monthly_message_limit": null,
    "monthly_limit_action": "notify"
  }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READGET /api/v1/partner/clients/{workspace_id}One client with everything it has set (its caps, what happens when used up, its monthly plan and its minutes and messages packs, white label, identifier and email) and its activity as well as its spend: total calls, calls in the last 7 days and the last one. That is what tells you a pilot is alive, which the cost does not show. A workspace outside your root answers 404.

Parameters

NameDescription
fromstring(query)Start of the period, in ISO 8601. Without it, the current month.
tostring(query)End of the period, in ISO 8601 and exclusive. Without it, right now.

Request

curl "https://leracore.com/api/v1/partner/clients/{workspace_id}?from=...&to=..." \
  -H "Authorization: Bearer lr_sk_..."

Responses

CodeDescription
200
{
  "workspace_id": "cmk...",
  "name": "Empresa Ejemplo",
  "slug": "empresa-ejemplo",
  "status": "ACTIVE",
  "external_id": "erp-4821",
  "contact_email": "secretaria@empresa.example",
  "phone_number": "+34600333444",
  "minutes": 128.4,
  "chats": 41,
  "chat_messages": 268,
  "cost_cents": 1794,
  "transfers": 6,
  "transfer_fee_cents": 180,
  "white_label": true,
  "max_concurrent_calls": null,
  "monthly_cost_limit_cents": 5000,
  "monthly_minute_limit": 500,
  "monthly_message_limit": 1000,
  "monthly_transfer_limit": 10,
  "monthly_limit_action": "block",
  "messages_limit_action": "block",
  "paused": false,
  "minutes_plan": {
    "included_minutes": 500,
    "cycle_start": "2026-09-15T00:00:00.000Z",
    "cycle": { "from": "2026-09-15T00:00:00.000Z", "to": "2026-10-15T00:00:00.000Z" },
    "used_this_cycle": 312.5,
    "plan_left": 187.5,
    "pack_left": 200,
    "overage": 0,
    "remaining": 387.5,
    "percent_used": 44.6,
    "exhausted": false,
    "on_exhausted": "block"
  },
  "messages_plan": {
    "included_messages": 1000,
    "cycle_start": "2026-09-15T00:00:00.000Z",
    "cycle": { "from": "2026-09-15T00:00:00.000Z", "to": "2026-10-15T00:00:00.000Z" },
    "used_this_cycle": 418,
    "plan_left": 582,
    "pack_left": 0,
    "overage": 0,
    "remaining": 582,
    "percent_used": 41.8,
    "exhausted": false,
    "on_exhausted": "block"
  },
  "transfers_plan": {
    "included_transfers": 10,
    "cycle_start": "2026-09-15T00:00:00.000Z",
    "cycle": { "from": "2026-09-15T00:00:00.000Z", "to": "2026-10-15T00:00:00.000Z" },
    "used_this_cycle": 6,
    "plan_left": 4,
    "pack_left": 0,
    "overage": 0,
    "remaining": 4,
    "percent_used": 60,
    "exhausted": false,
    "on_exhausted": "notify"
  },
  "period": { "from": "2026-09-01T00:00:00.000Z", "to": "2026-09-07T12:00:00.000Z" },
  "calls_total": 214,
  "calls_last_7_days": 31,
  "last_call_at": "2026-09-07T11:42:00.000Z"
}

application/json; charset=utf-8

400Invalid request
403Forbidden
UPDATEPATCH /api/v1/partner/clients/{workspace_id}Changes what a client has set: its monthly minutes and messages, its euro spend cap, what happens when used up (block or notify), pause, white label, lines and details. Only what you send changes. Returns the client like GET.

Parameters

NameDescription
included_minutesinteger | null(body)Their monthly plan in MINUTES per cycle, for voice. null removes it.
included_messagesinteger | null(body)Their monthly plan in MESSAGES per cycle, for chat. null removes it: with no monthly messages and no messages pack, their chat has no cap of its own.
included_transfersinteger | null(body)Calls handed to a person through an inbound line included per cycle, inside the voice agent (its cycle is cycle_start). Never cut off: when used up the agent keeps handing them over, we email you and each extra one is overage. null removes it. Calls through the client’s own number do not count.
cycle_startstring | null(body)Service start day (ISO 8601): their minutes renew on that day every month, and their messages too unless you send messages_cycle_start. null goes back to the calendar month.
messages_cycle_startstring | null(body)Service start day for chat (ISO 8601): their messages renew on that day every month. null goes back to the calendar month.
monthly_cost_limit_centsinteger | null(body)SPEND cap in euro cents per calendar month, voice and chat together: the most that client can cost you on Lera. Not the same as included_minutes or included_messages. null removes it.
on_exhaustedstring(body)What happens when it uses up its own (plan + pack) or reaches the spend cap: block stops answering; notify keeps answering and emails you. Applies to voice and chat, unless you send messages_on_exhausted. In chat, block opens no new conversations and lets the open ones finish. It does not affect included transfers, which always keep going.Values: block · notify
messages_on_exhaustedstring(body)The same for chat only, if it does not behave like voice: block opens no new chats; notify keeps answering and emails you.
pausedboolean(body)true pauses it (if they stop paying you): their agent stops answering until you reactivate it.
max_concurrent_callsinteger | null(body)How many calls it can handle at once at most. null: no cap of its own.
external_idstring | null(body)Their id in your system. Unique among your clients: if another has it, 409 external_id_taken.
contact_emailstring | null(body)The client’s contact email.
contact_first_namestring(body)First name of the client’s contact person.
contact_last_namestring(body)Last name of the client’s contact person.
namestring(body)Client name.

Request

curl -X POST https://leracore.com/api/v1/partner/clients/{workspace_id} \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "workspace_id": "cmk...",
  "monthly_cost_limit_cents": 5000,
  "monthly_minute_limit": 500,
  "monthly_message_limit": 1000,
  "monthly_limit_action": "block",
  "messages_limit_action": "block",
  "monthly_transfer_limit": 10,
  "paused": false,
  "minutes_plan": { "included_minutes": 500, "remaining": 387.5, "on_exhausted": "block" },
  "messages_plan": { "included_messages": 1000, "remaining": 582, "on_exhausted": "block" },
  "transfers_plan": { "included_transfers": 10, "remaining": 4, "on_exhausted": "notify" }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READGET /api/v1/partner/clients/{workspace_id}/minute-packsTheir minutes and their minutes pack history: purchases (pack), corrections (adjustment) and what their calls used (consumption; minutes is what came out of the pack and call_minutes how long it lasted). Chats go in the messages pack (message-packs). The latest 100.

Parameters

No parameters.

Request

curl "https://leracore.com/api/v1/partner/clients/{workspace_id}/minute-packs" \
  -H "Authorization: Bearer lr_sk_..."

Responses

CodeDescription
200
{
  "minutes_plan": { "included_minutes": 500, "pack_left": 200, "remaining": 387.5, "on_exhausted": "block" },
  "movements": [
    { "id": "cmk...", "kind": "pack", "minutes": 200, "call_minutes": null, "overage_minutes": null, "reference": "factura-77", "note": null, "created_at": "2026-10-01T09:00:00.000Z" }
  ]
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/partner/clients/{workspace_id}/minute-packsThe client has paid you for a minutes pack: it is used after their monthly plan and never expires. Buying a pack re-arms the 80% and exhausted alerts.

Parameters

NameDescription
minutes* requiredinteger(body)Pack minutes (positive). To remove, negative with kind adjustment.
referencestring(body)The payment id in your system. Makes it idempotent: repeating it answers 200 with duplicate=true and does not add twice.
kindstring(body)pack (default) or adjustment to correct.Values: pack · adjustment
notestring(body)A note of yours. Their client does not see it.

Request

curl -X POST https://leracore.com/api/v1/partner/clients/{workspace_id}/minute-packs \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "duplicate": false,
  "minutes_plan": { "included_minutes": 500, "pack_left": 400, "remaining": 587.5, "on_exhausted": "block" }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
READGET /api/v1/partner/clients/{workspace_id}/message-packsTheir chat messages and their messages pack history: purchases (pack), corrections (adjustment) and what their chats used (consumption; messages is what came out of the pack and chat_messages how many times the agent replied). A message is one agent reply: the fixed greeting does not count. The latest 100.

Parameters

No parameters.

Request

curl "https://leracore.com/api/v1/partner/clients/{workspace_id}/message-packs" \
  -H "Authorization: Bearer lr_sk_..."

Responses

CodeDescription
200
{
  "messages_plan": { "included_messages": 1000, "pack_left": 1000, "remaining": 1582, "on_exhausted": "block" },
  "movements": [
    { "id": "cmk...", "kind": "pack", "messages": 1000, "chat_messages": null, "overage_messages": null, "reference": "cobro-123", "note": null, "created_at": "2026-10-01T09:00:00.000Z" }
  ]
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/partner/clients/{workspace_id}/message-packsThe client has paid you for a messages pack for their chat: it is used after their monthly messages and never expires. Separate from the minutes. Buying a pack re-arms the 80% and exhausted messages alerts.

Parameters

NameDescription
messages* requiredinteger(body)Pack messages (positive). To remove, negative with kind adjustment.
referencestring(body)The payment id in your system. Makes it idempotent within messages: if one payment brings minutes and messages, send both packs with the same reference.
kindstring(body)pack (default) or adjustment to correct.Values: pack · adjustment
notestring(body)A note of yours. Their client does not see it.

Request

curl -X POST https://leracore.com/api/v1/partner/clients/{workspace_id}/message-packs \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "duplicate": false,
  "messages_plan": { "included_messages": 1000, "pack_left": 1000, "remaining": 1582, "on_exhausted": "block" }
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/partner/clients/{workspace_id}/linesGives your client their inbound line, to which they forward their usual number. You manage your clients’ telephony: they see their line and how to forward, nothing else. One line per account is included and the rest have a monthly fee, paid by you. The forwarding codes, by carrier, with get_forwarding_codes and the X-Lera-Client header. workspace_id also accepts their external_id.

Parameters

NameDescription
agent_idstring(body)The published voice agent that answers. Not needed if the client has only one.
labelstring(body)A name for the line (for example, the branch).
accept_line_feeboolean(body)Required for an additional line: you accept its monthly fee (line_fee_cents), deducted from your balance starting today. Without it, 400 line_fee_not_accepted, so repeating the request does not buy two.

Request

curl -X POST https://leracore.com/api/v1/partner/clients/{workspace_id}/lines \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "assigned": "+34848000000",
  "line_fee_cents": 300,
  "next_line_is_extra": true,
  "next_line_blocked_reason": null,
  "lines": [
    { "e164": "+34848000000", "label": null, "agent_id": "agt_...", "included": false, "release_at": null, "release_reason": null }
  ]
}

application/json; charset=utf-8

400Invalid request
403Forbidden
DELETEDELETE /api/v1/partner/clients/{workspace_id}/lines/{e164}Releases one of your client’s lines. If it never received a call it is freed at once; if it did, it is not reassigned for 30 days in case a forward still points at it. Have your client remove their forward.

Parameters

No parameters. Send an empty object.

Request

curl -X POST https://leracore.com/api/v1/partner/clients/{workspace_id}/lines/{e164} \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "released": "+34848000000",
  "line_fee_cents": 300,
  "next_line_is_extra": true,
  "next_line_blocked_reason": null,
  "lines": []
}

application/json; charset=utf-8

400Invalid request
403Forbidden
CREATEPOST /api/v1/partner/clients/{workspace_id}/sessionsOpens the panel to your client without them signing up. Request it from your server (never from the browser: it carries your key) and redirect the person to url. The link works ONCE and expires after 5 minutes. workspace_id also accepts their external_id.

Parameters

NameDescription
email* requiredstring(body)The email of the person signing in. Without a user, one is created only inside that client. If it already has access to another Lera account, 409 email_in_use.
namestring(body)Their name, if the user is created.
rolestring(body)member (default): Viewer, read only. editor: Editor, can also change their agents' texts and knowledge bases, test and publish; never the model, voice, functions or telephony. You manage their team and keys. Neither sees your other clients or your console.Values: member · editor

Request

curl -X POST https://leracore.com/api/v1/partner/clients/{workspace_id}/sessions \
  -H "Authorization: Bearer lr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

CodeDescription
200
{
  "url": "https://leracore.com/app/enter?token=...",
  "expires_at": "2026-10-03T10:05:00.000Z",
  "user_created": true,
  "role": "member"
}

application/json; charset=utf-8

400Invalid request
403Forbidden
Operation catalogue
READGET /api/v1/toolsReturns the operation catalogue with its input schema, to discover them from code.

Parameters

No parameters.

Request

curl "https://leracore.com/api/v1/tools" \
  -H "Authorization: Bearer lr_sk_..."

Responses

CodeDescription
200
{
  "tools": [{
    "name": "list_agents",
    "description": "...",
    "input_schema": { "type": "object", "properties": {} }
  }]
}

application/json; charset=utf-8

400Invalid request
403Forbidden