# Lelemon API > Put AI agents on WhatsApp inside your own product. Guides at https://docs.lelemon.cl. Use this documentation to integrate a system with the Lelemon API v2 or to operate Lelemon conversational agents from another AI agent. The guides explain each flow end to end. The OpenAPI contract at https://docs.lelemon.cl/openapi.json is the source of truth for fields, bodies and errors. If a guide and the contract disagree, the contract wins. API base: https://api.lelemon.cl/v2. Every request carries the key in the header Authorization: Bearer lel_live_.... Send an Idempotency-Key on every POST. Branch on the error code, never on the detail text. Every operation declares x-lelemon-effect (read, write, destructive or money) in the contract. Ask for ?dryRun=true where a route accepts it: nothing is saved or sent. An error may carry a fix object (set, remove, retry, call or stop) that says what to do next. Send only documented body fields: unknown ones are rejected with 400. An MCP server for the API is described in https://docs.lelemon.cl/tools/mcp. A guide that takes an account from empty to a working agent is at https://docs.lelemon.cl/get-started/setup-from-zero. The v1 API (/v1/external) is deprecated and documented under /legacy/v1. Use v2 for new work. v2 routes (method, path and purpose): - GET /v2/me: Retrieve the current key - GET /v2/scopes: List scopes - POST /v2/agents: Create an agent - GET /v2/agents: List agents - GET /v2/agents/{id}: Retrieve an agent - PATCH /v2/agents/{id}: Update an agent - DELETE /v2/agents/{id}: Delete an agent - POST /v2/agents/{id}/activate: Activate an agent - POST /v2/agents/{id}/pause: Pause an agent - GET /v2/agents/{id}/versions: List versions - GET /v2/agents/{id}/versions/{versionId}: Retrieve a version - POST /v2/agents/{id}/versions/{versionId}/restore: Restore a version - GET /v2/agents/{id}/facts: List the fixed facts of an agent - PUT /v2/agents/{id}/facts: Save a fixed fact of an agent - DELETE /v2/agents/{id}/facts/{key}: Forget a fixed fact of an agent - GET /v2/agent-templates: List agent templates - GET /v2/models: List models - POST /v2/subaccounts: Create a subaccount - GET /v2/subaccounts: List subaccounts - GET /v2/subaccounts/{id}: Retrieve a subaccount - PATCH /v2/subaccounts/{id}: Update a subaccount - DELETE /v2/subaccounts/{id}: Delete a subaccount - POST /v2/subaccounts/{id}/api-keys: Give a subaccount its own key - POST /v2/whatsapp/connections: Create a WhatsApp connection link - GET /v2/whatsapp/connections: List WhatsApp connections - GET /v2/whatsapp/connections/{id}: Retrieve a WhatsApp connection - DELETE /v2/whatsapp/connections/{id}: Revoke a pending WhatsApp connection - GET /v2/whatsapp/phone-numbers: List WhatsApp phone numbers - GET /v2/whatsapp/phone-numbers/{id}: Retrieve a WhatsApp phone number - PATCH /v2/whatsapp/phone-numbers/{id}: Change the agent, label or state of a number - DELETE /v2/whatsapp/phone-numbers/{id}: Disconnect a WhatsApp phone number - GET /v2/whatsapp/phone-numbers/{id}/commerce-settings: Read the cart and catalog settings of a number - PATCH /v2/whatsapp/phone-numbers/{id}/commerce-settings: Turn the cart button or the catalog icon of a number on or off - POST /v2/actions: Create an action - GET /v2/actions: List actions - GET /v2/actions/authorization: Read the current authorization text - POST /v2/actions/signing-secret/rotate: Rotate the signing secret of your actions - GET /v2/actions/{id}/signing-secret: Retrieve the signing secret of an action - GET /v2/actions/{id}: Retrieve an action - PATCH /v2/actions/{id}: Update an action - DELETE /v2/actions/{id}: Delete an action - POST /v2/actions/{id}/test: Test an action - POST /v2/mcp-servers: Connect an MCP server - GET /v2/mcp-servers: List MCP servers - GET /v2/mcp-servers/{id}: Retrieve an MCP server - PATCH /v2/mcp-servers/{id}: Update an MCP server - DELETE /v2/mcp-servers/{id}: Disconnect an MCP server - GET /v2/mcp-servers/{id}/tools: List the tools of an MCP server - POST /v2/mcp-servers/{id}/discover: Discover tools - GET /v2/mcp-servers/{id}/run-identity: Read the run identity of an MCP server - POST /v2/mcp-servers/{id}/run-identity: Turn on or rotate the run identity of an MCP server - DELETE /v2/mcp-servers/{id}/run-identity: Turn off the run identity of an MCP server - GET /v2/data-connectors/format: Get the lelemon-connector/v1 format - POST /v2/data-connectors/format/validate: Validate a connector document - POST /v2/data-connectors: Register a data connector - GET /v2/data-connectors: List data connectors - GET /v2/data-connectors/{id}: Retrieve a data connector - PATCH /v2/data-connectors/{id}: Update a data connector - DELETE /v2/data-connectors/{id}: Delete a data connector - GET /v2/data-connectors/{id}/signing-secret: Retrieve the signing secret of a data connector - POST /v2/data-connectors/{id}/signing-secret/rotate: Rotate the signing secret of a data connector - POST /v2/data-connectors/{id}/check: Check a data connector - GET /v2/data-connectors/{id}/manifest: Retrieve the manifest of a data connector - GET /v2/data-connectors/{id}/accounts: Search accounts by email - GET /v2/data-connectors/{id}/accounts/{account}: Read the card of an account live - POST /v2/data-connectors/{id}/accounts/{account}/reveal: Reveal one masked value of an account - POST /v2/data-connectors/{id}/accounts/{account}/actions/{action}/open: Get the link of an account action - GET /v2/data-connectors/{id}/views/{view}: Read a view live - GET /v2/data-connectors/{id}/accesses: List who looked at what through a connector - POST /v2/agents/{id}/skills: Create a skill - GET /v2/agents/{id}/skills: List skills - GET /v2/agents/{id}/skills/{skillId}: Retrieve a skill - PATCH /v2/agents/{id}/skills/{skillId}: Update a skill - DELETE /v2/agents/{id}/skills/{skillId}: Delete a skill - GET /v2/agents/{id}/tools: List an agent's tools - PUT /v2/agents/{id}/tools/{toolId}: Grant a tool - DELETE /v2/agents/{id}/tools/{toolId}: Remove a tool - GET /v2/approvals: List approvals - GET /v2/approvals/{id}: Retrieve an approval - POST /v2/approvals/{id}/approve: Approve an action - POST /v2/approvals/{id}/reject: Reject an action - POST /v2/approvals/{id}/request-review: Ask for a human review of a decision - GET /v2/automated-decisions: List automated decisions - GET /v2/automated-decisions/{id}: Retrieve an automated decision - POST /v2/automated-decisions/{id}/request-review: Ask for a human review of an automated decision - GET /v2/actions/{id}/approval-floor: Read the approval floor of a shared action - PUT /v2/actions/{id}/approval-floor: Set the approval floor of a shared action - GET /v2/team-questions: List team questions - GET /v2/team-questions/{id}: Retrieve a team question - GET /v2/team-questions/{id}/context: Read a team question with its context - POST /v2/team-questions/{id}/answer: Answer a team question - POST /v2/agents/{id}/runs: Give an agent a job - GET /v2/runs: List runs - GET /v2/runs/{id}: Retrieve a run - POST /v2/runs/{id}/cancel: Cancel a run - POST /v2/runs/{id}/answer: Answer a run that asked something - POST /v2/agents/{id}/schedules: Schedule a job for an agent - GET /v2/schedules: List scheduled tasks - GET /v2/schedules/{id}: Retrieve a scheduled task - PATCH /v2/schedules/{id}: Change a scheduled task - DELETE /v2/schedules/{id}: Delete a scheduled task - POST /v2/schedules/{id}/fire: Fire a scheduled task now - POST /v2/pipelines: Create a pipeline - GET /v2/pipelines: List pipelines - GET /v2/pipelines/{id}: Retrieve a pipeline - PATCH /v2/pipelines/{id}: Update a pipeline - DELETE /v2/pipelines/{id}: Delete a pipeline - POST /v2/pipelines/{id}/clone: Clone a pipeline - POST /v2/pipelines/{id}/stages/reorder: Reorder the stages of a pipeline - POST /v2/pipelines/{id}/stages: Create a stage - GET /v2/pipelines/{id}/stages: List the stages of a pipeline - GET /v2/pipelines/{id}/stages/{stageId}: Retrieve a stage - PATCH /v2/pipelines/{id}/stages/{stageId}: Update a stage - DELETE /v2/pipelines/{id}/stages/{stageId}: Delete a stage - POST /v2/pipelines/{id}/stages/{stageId}/set-entry: Make a stage the entry stage - POST /v2/pipelines/{id}/fields: Create a field - GET /v2/pipelines/{id}/fields: List the fields of a pipeline - GET /v2/pipelines/{id}/fields/{fieldId}: Retrieve a field - PATCH /v2/pipelines/{id}/fields/{fieldId}: Update a field - DELETE /v2/pipelines/{id}/fields/{fieldId}: Delete a field - POST /v2/pipelines/{id}/routing-rules: Create a routing rule - GET /v2/pipelines/{id}/routing-rules: List the routing rules of a pipeline - GET /v2/pipelines/{id}/routing-rules/{ruleId}: Retrieve a routing rule - PATCH /v2/pipelines/{id}/routing-rules/{ruleId}: Update a routing rule - DELETE /v2/pipelines/{id}/routing-rules/{ruleId}: Delete a routing rule - POST /v2/knowledge-collections: Create a collection - GET /v2/knowledge-collections: List collections - POST /v2/knowledge-collections/search: Search the knowledge - GET /v2/knowledge-collections/{id}: Retrieve a collection - PATCH /v2/knowledge-collections/{id}: Update a collection - DELETE /v2/knowledge-collections/{id}: Delete a collection - POST /v2/knowledge-collections/{id}/documents: Add a document - GET /v2/knowledge-collections/{id}/documents: List documents - GET /v2/knowledge-collections/{id}/documents/{docId}: Retrieve a document - PATCH /v2/knowledge-collections/{id}/documents/{docId}: Update a document - DELETE /v2/knowledge-collections/{id}/documents/{docId}: Delete a document - PUT /v2/agents/{id}/knowledge-collections/{collectionId}: Let an agent search a collection - DELETE /v2/agents/{id}/knowledge-collections/{collectionId}: Stop an agent from searching a collection - POST /v2/contacts: Create a contact - GET /v2/contacts: List contacts - PUT /v2/contacts/by-external-ref/{externalRef}: Create or update a contact by your own id - GET /v2/contacts/{id}: Retrieve a contact - PATCH /v2/contacts/{id}: Update a contact - DELETE /v2/contacts/{id}: Erase a contact - POST /v2/contact-fields: Create a contact field - GET /v2/contact-fields: List the contact fields - GET /v2/contact-fields/{id}: Retrieve a contact field - PATCH /v2/contact-fields/{id}: Update a contact field - DELETE /v2/contact-fields/{id}: Delete a contact field - POST /v2/companies: Create a company - GET /v2/companies: List companies - GET /v2/companies/{id}: Retrieve a company - PATCH /v2/companies/{id}: Update a company - DELETE /v2/companies/{id}: Delete a company - POST /v2/lead-forms: Create a lead form - GET /v2/lead-forms: List lead forms - GET /v2/lead-forms/{id}: Retrieve a lead form - PATCH /v2/lead-forms/{id}: Update a lead form - DELETE /v2/lead-forms/{id}: Delete a lead form - GET /v2/suppressions/{id}: Retrieve a suppression - POST /v2/cases: Open a case - GET /v2/cases: List cases - GET /v2/cases/{id}: Retrieve a case - PATCH /v2/cases/{id}: Update a case - DELETE /v2/cases/{id}: Delete a case - POST /v2/cases/{id}/move: Move a case to a stage - POST /v2/cases/{id}/assign: Assign a case to a member - POST /v2/cases/{id}/close: Close a case - POST /v2/cases/{id}/reopen: Reopen a case - POST /v2/cases/{id}/take-control: Take control of a case - POST /v2/cases/{id}/release-control: Hand a case back to the agent - POST /v2/cases/{id}/read: Mark a case as read - GET /v2/case-queue: Read the attention queue of a member - POST /v2/cases/move-batch: Move several cases to a stage - POST /v2/cases/{id}/archive: Archive a case - POST /v2/cases/{id}/unarchive: Bring an archived case back - POST /v2/cases/{id}/mute: Mute the contact of a case - POST /v2/cases/{id}/unmute: Unmute the contact of a case - POST /v2/cases/{id}/escalate: Hand a case to a person - POST /v2/cases/{id}/fields/{key}/reveal: Reveal a sensitive field of a case - GET /v2/contacts/{id}/events: List the events of a contact - POST /v2/cases/{id}/reminders: Add a reminder to a case - GET /v2/cases/{id}/reminders: List the reminders of a case - GET /v2/reminders/{id}: Retrieve a reminder - PATCH /v2/reminders/{id}: Edit a reminder - DELETE /v2/reminders/{id}: Delete a reminder - POST /v2/reminders/{id}/complete: Complete a reminder - POST /v2/reminders/{id}/dismiss: Dismiss a reminder - POST /v2/presence-signals: Report who is online in your app - GET /v2/presence/settings: Read the presence setting - PUT /v2/presence/settings: Turn presence on or off - GET /v2/organization: Get the organization - PATCH /v2/organization: Rename the organization - GET /v2/organization/settings: Get the organization settings - PATCH /v2/organization/settings: Change the organization settings - GET /v2/organization/company-profile: Get the company profile - PATCH /v2/organization/company-profile: Change the company profile - POST /v2/cases/{id}/notes: Add a note to a case - GET /v2/cases/{id}/notes: List the notes of a case - GET /v2/cases/{id}/notes/{noteId}: Retrieve a note - PATCH /v2/cases/{id}/notes/{noteId}: Edit a note - DELETE /v2/cases/{id}/notes/{noteId}: Delete a note - POST /v2/cases/{id}/attachments: Upload a file to a case - GET /v2/cases/{id}/attachments: List the files of a case - GET /v2/cases/{id}/attachments/{attachmentId}: Retrieve a file of a case - DELETE /v2/cases/{id}/attachments/{attachmentId}: Delete a file of a case - GET /v2/cases/{id}/attachments/{attachmentId}/download: Get the download link of a file - POST /v2/files: Upload a file - GET /v2/files: List files - GET /v2/files/{id}: Retrieve a file - DELETE /v2/files/{id}: Delete a file - GET /v2/cases/{id}/messages: List the messages of a case - POST /v2/cases/{id}/messages: Add a message to a case - POST /v2/cases/{id}/messages/{messageId}/redact: Redact a message - GET /v2/cases/{id}/turns: List the turns the agent took in a case - GET /v2/usage: Get the usage of your agents - GET /v2/case-metrics: List the times of the cases that changed in a range - POST /v2/budgets: Create a monthly budget - GET /v2/budgets: List the budgets - GET /v2/budgets/{id}: Get a budget - PATCH /v2/budgets/{id}: Change a budget - DELETE /v2/budgets/{id}: Delete a budget - GET /v2/members: List the active members of the organization - GET /v2/members/audit-log: List who invited, changed the role of or removed members - GET /v2/members/{id}/availability: Read whether a team member is available - PUT /v2/members/{id}/availability: Mark a team member available or away - PATCH /v2/members/{id}/role: Change the role of a member - PATCH /v2/members/{id}/case-scope: Change which cases a member sees - DELETE /v2/members/{id}: Remove a member from the organization - GET /v2/invitations: List the invitations of the organization - POST /v2/invitations: Invite a person to the organization - POST /v2/invitations/{id}/resend: Resend an invitation - POST /v2/invitations/{id}/cancel: Cancel an invitation - GET /v2/scheduling/agendas: List the agendas - POST /v2/scheduling/agendas: Create an agenda - GET /v2/scheduling/agendas/{id}: Retrieve an agenda - PATCH /v2/scheduling/agendas/{id}: Update an agenda - GET /v2/scheduling/agendas/{id}/members: List the team of an agenda - POST /v2/scheduling/agendas/{id}/members: Add a person to the team of an agenda - PATCH /v2/scheduling/agendas/{id}/members/{memberId}: Update a person in the team of an agenda - DELETE /v2/scheduling/agendas/{id}/members/{memberId}: Remove a person from the team of an agenda - GET /v2/scheduling/availability: Read the free slots of an agenda - POST /v2/scheduling/meetings: Book a meeting - GET /v2/scheduling/meetings: List meetings - GET /v2/scheduling/meetings/{id}: Retrieve a meeting - POST /v2/scheduling/meetings/{id}/cancel: Cancel a meeting - POST /v2/scheduling/meetings/{id}/reschedule: Move a meeting to another slot - POST /v2/webhook-endpoints: Create a webhook endpoint - GET /v2/webhook-endpoints: List webhook endpoints - GET /v2/webhook-endpoints/{id}: Retrieve a webhook endpoint - PATCH /v2/webhook-endpoints/{id}: Update a webhook endpoint - DELETE /v2/webhook-endpoints/{id}: Delete a webhook endpoint - POST /v2/webhook-endpoints/{id}/rotate-secret: Rotate the signing secret - POST /v2/webhook-endpoints/{id}/test: Send a test event - GET /v2/webhook-endpoints/{id}/deliveries: List the deliveries of an endpoint - POST /v2/events/{id}/resend: Resend an event - GET /v2/event-types: List the event types - GET /v2/recipient-allowlist: Get the recipient allowlist - PUT /v2/recipient-allowlist: Replace the recipient allowlist - POST /v2/whatsapp/templates: Create a template - GET /v2/whatsapp/templates: List templates - POST /v2/whatsapp/templates/sync: Sync template statuses - GET /v2/whatsapp/templates/{id}: Retrieve a template - PATCH /v2/whatsapp/templates/{id}: Update a template - DELETE /v2/whatsapp/templates/{id}: Delete a template - POST /v2/whatsapp/templates/{id}/render: Render a template - POST /v2/whatsapp/templates/{id}/test: Send a test message - POST /v2/whatsapp/messages: Send a template - GET /v2/whatsapp/messages/{id}: Retrieve a template message - POST /v2/whatsapp/messages/{id}/cancel: Cancel a scheduled message - POST /v2/contact-events: Report a contact event - GET /v2/contact-events/{id}: Retrieve a contact event - POST /v2/triggers: Create a trigger - GET /v2/triggers: List triggers - GET /v2/triggers/{id}: Retrieve a trigger - PATCH /v2/triggers/{id}: Update a trigger - DELETE /v2/triggers/{id}: Delete a trigger - GET /v2/triggers/{id}/runs: List the runs of a trigger - GET /v2/opt-outs: List opt-outs - PUT /v2/contacts/{contactId}/opt-outs/{channel}: Opt a contact out - DELETE /v2/contacts/{contactId}/opt-outs/{channel}: Clear an opt-out - POST /v2/campaigns: Create a campaign - GET /v2/campaigns: List campaigns - GET /v2/campaigns/{id}: Retrieve a campaign - PATCH /v2/campaigns/{id}: Update a campaign - DELETE /v2/campaigns/{id}: Delete a campaign - POST /v2/campaigns/{id}/preview: Preview a campaign - POST /v2/campaigns/{id}/launch: Launch a campaign - POST /v2/campaigns/{id}/pause: Pause a campaign - POST /v2/campaigns/{id}/resume: Resume a campaign - POST /v2/campaigns/{id}/cancel: Cancel a campaign - GET /v2/campaigns/{id}/recipients: List recipients - POST /v2/email/domains: Add a sender domain - GET /v2/email/domains: List the sender domains - GET /v2/email/domains/{id}: Get a sender domain with its status and DNS records - PATCH /v2/email/domains/{id}: Change the default sender or the inbound agent of a domain - DELETE /v2/email/domains/{id}: Remove a sender domain - POST /v2/email/domains/{id}/verify: Check the DNS records now - POST /v2/email/messages: Write first by email - GET /v2/email/messages/{id}: Retrieve an email message - GET /v2/teams: List the teams - POST /v2/teams: Create a team - GET /v2/teams/{id}: Retrieve a team - PATCH /v2/teams/{id}: Update a team - DELETE /v2/teams/{id}: Delete a team - POST /v2/teams/{id}/merge: Merge another team into this one - PUT /v2/teams/{id}/pipelines/{pipelineId}: Move a pipeline into a team - PUT /v2/teams/{id}/members/{memberId}: Add a member to a team or change their role in it - DELETE /v2/teams/{id}/members/{memberId}: Remove a member from a team - GET /v2/integrations/linear: Get the Linear connection - PUT /v2/integrations/linear: Connect Linear - PATCH /v2/integrations/linear: Update the Linear connection - DELETE /v2/integrations/linear: Disconnect Linear - POST /v2/cases/{id}/escalate-to-team: Escalate a case to the technical team - GET /v2/cases/{id}/team-escalations: List the escalations of a case ## Documentation - [Changelog](/changelog.md): Changes to the Lelemon API and its documentation. - [Verify signatures](/webhooks/verify.md): Check the Lelemon-Signature header of every delivery against the raw body. - [Receive events](/webhooks/receive.md): Lelemon tells your server when something changes, so you never poll. Register an endpoint, answer fast and handle retries. - [Event catalog](/webhooks/events.md): Every event type you can subscribe to, with the JSON Schema of its data. Generated from the API. - [Sell on WhatsApp with a catalog and a cart](/use-cases/whatsapp-sales-agent.md): An agent that qualifies leads on WhatsApp, shows products from your Meta catalog, receives the cart, hands over to a person and re-engages contacts with a template campaign. - [Support with tools and human approval](/use-cases/support-with-approvals.md): A support agent that looks up orders through your HTTP action and proposes refunds that a person approves, with an approval threshold, a monthly cap per customer and a floor for platforms. - [Run Lelemon for your customers with subaccounts](/use-cases/platform-subaccounts.md): Create one subaccount per customer, share actions and MCP servers with all of them, set a conversation cap and an approval floor, and receive their events in one webhook. - [Book, move and cancel meetings with an agent](/use-cases/meeting-scheduling.md): An agent that offers real free times from your agenda, books and cancels meetings with the scheduling tools of Lelemon, and a WhatsApp reminder that your backend keeps in step through webhooks. - [A copilot for your team with your own data](/use-cases/internal-copilot.md): Serve account cards from your back office in the lelemon-connector/v1 format, check them with the SDK and the CLI, and let an internal copilot read them with masked personal data and audited reveals. - [Give an agent a background job](/use-cases/background-runs.md): Hand an agent a goal, follow the run by webhook, answer the question it asks and cancel a job, with the person it works for declared by your key. - [SDK, CLI and MCP](/tools/sdks.md): The tools that sit on top of the Lelemon API. Pick the TypeScript SDK, the command line or the MCP server. - [TypeScript SDK](/tools/sdk.md): Install @lelemon-ai/sdk, call every v2 operation with types, and get retries, idempotency keys, pagination and webhook verification for free. - [MCP server](/tools/mcp.md): Connect Claude, Cursor or ChatGPT to Lelemon with one URL and your login. Every operation of the API v2 becomes a tool, limited to the permissions you grant. - [Command line](/tools/cli.md): The lelemon command validates a data connector against the format and serves a fixture so you can build your back office integration without deploying anything. - [v1 (legacy)](/legacy/v1.md): The v1 external API is deprecated. Its reference and Spanish guides stay available while you move to v2. - [WhatsApp messages](/guides/whatsapp.md): Every official WhatsApp format that works in Chile, and what the person can send back. - [Track usage and cap conversations](/guides/usage-and-budgets.md): See how many conversations your agents handle, read what they did in a turn, measure how long cases take, and cap the month with a budget in conversations and an alert at 80%. - [Use Claude as your team's assistant](/guides/team-assistant.md): Connect Claude to Lelemon with one URL so it reads the questions your agents left for the team, searches your knowledge and drafts the answers, without handing it any sensitive data. - [Schedule meetings](/guides/scheduling.md): Show the free slots of an agenda in your own screen, book, move and cancel meetings, hear about them by webhook and set a team member as available or away. - [Scheduled tasks](/guides/scheduled-tasks.md): Have an agent write by email to a contact on fixed dates, with a file from one of its actions, and keep the conversation if the contact answers. - [Give an agent a job that runs on its own](/guides/runs.md): Hand an agent a goal, follow it by API or webhooks, answer its questions and cancel it, with the person it works for declared by your key. - [Show who is online](/guides/presence.md): Tell Lelemon which of your users are in your app, so your team sees them as online or as last seen in contacts and cases. - [Run Lelemon for your customers](/guides/platforms.md): Create one subaccount per customer and manage its agents, pipelines, numbers and keys from your own code. - [Pipelines](/guides/pipelines.md): Create a pipeline with stages, fields, routing rules and quick replies, then move and close the cases that travel through it. - [Keep a tool's data out of storage with noPersist](/guides/no-persist.md): Mark an action or an MCP server noPersist so what it returns lives only in the turn that called it. - [Moving from v1](/guides/migrate.md): How the v1 external API maps to v2, what changed in ids, errors, lists and webhooks. - [Knowledge](/guides/knowledge.md): Teach an agent your business with collections and documents, upload text or files, follow the ingestion status and grant a collection to an agent. - [Build your own inbox](/guides/inbox.md): Show conversations inside your product and let your users answer without the Lelemon dashboard. - [Message on events](/guides/events-and-triggers.md): Report what happened in your system. A trigger picks the template, checks the rules and lets the agent continue if the contact answers. - [Erase a contact or a message](/guides/erasure.md): Honour an erasure request under Chilean Law 21.719, or remove a message that holds data that must not stay. - [Write by email](/guides/email.md): Verify a sender domain, send the first email of a case and let the agent continue the thread when the contact replies. - [Connect your back office](/guides/data-connectors.md): Serve account cards and views from your own system in the open lelemon-connector/v1 format. Lelemon reads them live, masks personal data and never stores a copy. - [Contacts](/guides/contacts.md): Create, find, search, update and erase the people your agents talk to, keep your own id and your own fields on each one, and send events about them. - [Run a campaign](/guides/campaigns.md): Send one approved template to many contacts, in batches, inside the hours you choose. - [Best practices](/guides/best-practices.md): Habits that keep a Lelemon integration reliable, and the mistakes to avoid. - [Approve agent actions and answer the team](/guides/approvals.md): Put an action behind a person, decide it by API or in the dashboard, and let an agent ask your team a question without handing over the case. - [API keys](/guides/api-keys.md): Choose the scopes and allowed sites of an API key, manage keys from the dashboard, and issue keys for subaccounts. - [Agents](/guides/agents.md): Create an agent from a template or from scratch, write its prompt, pick a model, give it skills, knowledge and tools, choose its channels and turn it on. - [Actions and MCP in v2](/guides/actions-and-mcp.md): Give an agent your own HTTP endpoints and MCP servers, fill fields with Lelemon variables, and operate the Lelemon API itself from an MCP client. - [Set up an account from zero](/get-started/setup-from-zero.md): From an empty account to an agent that books appointments, step by step by API, SDK or MCP. Pipeline, agent, tools, channels, webhook and the first conversation. - [Quickstart](/get-started/quickstart.md): Go from an API key to an agent that answers a message and a webhook that tells you about it, in five steps. - [Build with AI](/get-started/build-with-ai.md): Point your coding agent at the Lelemon docs and contract so it builds against the real API. - [Versioning](/basics/versioning.md): The API version is in the path, and v2 only adds. - [Scopes](/basics/scopes.md): Every scope an API key can carry and what it allows. Generated from the API. - [Rate limits](/basics/rate-limits.md): The two limits on the API, the headers that tell you where you stand and what to do when you pass one. - [Lists](/basics/lists.md): Every list has the same shape and pages with a cursor. - [IDs and objects](/basics/ids.md): Every id is an opaque string with a prefix that tells you what it points to. - [Idempotency](/basics/idempotency.md): Retry any POST safely with an Idempotency-Key. - [Errors](/basics/errors.md): Errors follow RFC 9457 problem details, with a stable code to branch on. - [Authentication and scopes](/basics/authentication.md): Send your API key as a bearer token. Keys belong to the organization and carry scopes. - [webhook_endpoint_limit](/errors/webhook_endpoint_limit.md): 422 Unprocessable. An organization can have up to 16 webhook endpoints, enabled or disabled. Every event is delivered to each endpoint that listens to it, so the cap also bounds how many deliveries one event can make. - [unsupported_file_type](/errors/unsupported_file_type.md): 422 Unprocessable. Allowed: PDF, DOCX, TXT and MD. - [unprocessable](/errors/unprocessable.md): 422 Unprocessable. The request is well formed and the fields are valid, but a rule of the object does not allow it in its current state. The `detail` names the rule and `param` the field when there is one. - [unknown_field](/errors/unknown_field.md): 400 Bad request. The body has a field the route does not document. `param` names the first one, and the detail lists up to ten. Remove it and send the request again. Free-form maps such as `metadata` accept any key. - [unauthorized](/errors/unauthorized.md): 401 Unauthorized. Missing, invalid or revoked API key. Send it as Authorization: Bearer . - [thinking_not_supported](/errors/thinking_not_supported.md): 422 Unprocessable. The model in `llmConfig.model` cannot turn thinking off, so `thinking: "off"` is rejected. `GET /v2/models` says which models accept it. - [template_variable_missing](/errors/template_variable_missing.md): 422 Unprocessable. The instructions ask for a variable that has no value. - [template_not_approved](/errors/template_not_approved.md): 422 Unprocessable. WhatsApp has not approved this template, so nothing can be sent with it yet. - [template_across_accounts](/errors/template_across_accounts.md): 422 Unprocessable. A template belongs to one WhatsApp Business Account. Choose numbers that share it. - [team_question_not_open](/errors/team_question_not_open.md): 409 Conflict. The team question was already answered or closed. It cannot be answered twice. - [subscription_canceled](/errors/subscription_canceled.md): 403 Forbidden. The subscription of this organization is canceled. The API is closed until it is reactivated. - [subject_required](/errors/subject_required.md): 422 Unprocessable. The first email of a case needs a subject. - [slot_not_available](/errors/slot_not_available.md): 409 Conflict. That time is no longer free in the agenda, or it was never one of its slots. Nothing was booked. - [service_unavailable](/errors/service_unavailable.md): 503 Service unavailable. Lelemon is temporarily unavailable. Retry with backoff. - [sender_domain_not_verified](/errors/sender_domain_not_verified.md): 422 Unprocessable. The sender address must belong to a verified domain of the organization. Check GET /v2/email/domains. - [scope_missing](/errors/scope_missing.md): 403 Forbidden. The key is valid but was created without the scope this operation needs. The operation page in the API reference lists the scope it requires and `missingScopes` in the answer names the ones this key lacks. - [schedule_limit_reached](/errors/schedule_limit_reached.md): 409 Conflict. The agent or the organization already has the maximum number of scheduled tasks. Delete or reuse one before creating another. - [run_not_waiting](/errors/run_not_waiting.md): 409 Conflict. The run is not paused with a question, so it has nothing to receive an answer. Read the run: only status waiting_for_answer takes one. - [run_finished](/errors/run_finished.md): 409 Conflict. The run already ended (completed, stopped, failed or canceled), so there is nothing left to cancel. - [review_not_available](/errors/review_not_available.md): 422 Unprocessable. Only a decision marked automatedDecision takes a review request, and an approval only once someone decided it. - [resource_in_use](/errors/resource_in_use.md): 409 Conflict. Something still depends on this object, for example a contact with open cases or a pipeline with a case in it, so it cannot be deleted. The `detail` names what depends on it. - [required_fields_missing](/errors/required_fields_missing.md): 422 Unprocessable. The stage the case is moving to or entering requires fields that the case does not have yet. `param` names the first missing one. - [recipient_not_allowed](/errors/recipient_not_allowed.md): 422 Unprocessable. This organization cannot send email to that address. - [rate_limited](/errors/rate_limited.md): 429 Too many requests. This key sent more than 3000 requests in the last minute. The RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset headers of every answer say where the key stands, and Retry-After says how many seconds to wait. - [presence_not_configured](/errors/presence_not_configured.md): 409 Conflict. Presence is off for this organization: no presence setting is saved yet, so signals have nothing to update and presence filters have nothing to read. - [phone_number_in_use](/errors/phone_number_in_use.md): 409 Conflict. This number is already connected. - [payload_too_large](/errors/payload_too_large.md): 413 Payload too large. The body is bigger than the limit of the route. JSON bodies take up to 1 MB; a file route has its own limit, which the `detail` states. - [organization_deleted](/errors/organization_deleted.md): 403 Forbidden. The organization of this key was deleted. - [not_found](/errors/not_found.md): 404 Not found. No object with this id exists in the organization of the key. The id may have a typo, belong to another organization or subaccount, or the object was deleted. - [no_whatsapp_number](/errors/no_whatsapp_number.md): 422 Unprocessable. The organization has no active WhatsApp number that can send this template. - [no_outbound_channel](/errors/no_outbound_channel.md): 422 Unprocessable. This case has no channel to write to the person. The message was not sent. - [model_not_supported](/errors/model_not_supported.md): 422 Unprocessable. The `llmConfig.model` is not a public model id of the list in `GET /v2/models`, or it is one that was withdrawn. - [method_not_allowed](/errors/method_not_allowed.md): 405 Method not allowed. The path exists but not with this HTTP method, for example a `DELETE` on a route that only reads. The API reference lists the methods of each path. - [message_variable_missing](/errors/message_variable_missing.md): 422 Unprocessable. The template needs a variable that has no value. The message was not created. - [meeting_not_active](/errors/meeting_not_active.md): 409 Conflict. The meeting is canceled, completed or was marked as a no-show, so it cannot be canceled or moved. - [mcp_server_unreachable](/errors/mcp_server_unreachable.md): 422 Unprocessable. The MCP server did not answer a tools request. Check the URL and the credentials. Redirects are not followed. - [linear_rejected](/errors/linear_rejected.md): 422 Unprocessable. Linear did not accept the API key, the team or the project. Check that the key is valid and can see the team. - [invalid_timezone](/errors/invalid_timezone.md): 422 Unprocessable. The timezone is not an IANA name. Use a name such as America/Santiago. - [invalid_request](/errors/invalid_request.md): 400 Bad request. A field of the request is missing, has the wrong type or breaks a limit, or the body has a field that does not exist. The `param` of the answer names the first field that failed and the `detail` says which rule it broke. - [invalid_cursor](/errors/invalid_cursor.md): 400 Bad request. The `cursor` is not one this API issued, was changed on the way, or was issued for a list with other filters. A cursor is only valid for the same filters and the same list. - [invalid_cron](/errors/invalid_cron.md): 422 Unprocessable. The cron expression could not be read. Use five fields (minute hour day-of-month month day-of-week), for example 0 9 2 * * for the 2nd of each month at 09:00. - [internal_error](/errors/internal_error.md): 500 Server error. Something failed on our side after the request started. The same Idempotency-Key returns this same error, so check whether the operation happened before retrying with a new key. - [interactive_unsupported_channel](/errors/interactive_unsupported_channel.md): 422 Unprocessable. Buttons, lists and catalog messages only exist on WhatsApp. This case is on another channel. The message was not sent. - [idempotency_key_reused](/errors/idempotency_key_reused.md): 409 Conflict. This `Idempotency-Key` was already used within the last 24 hours with a different method, path or body. A key identifies one request: the same key must always carry the same request. It also answers when the response stored for the key was erased because it held personal data of a person who was suppressed: send the request again with a new key. - [idempotency_key_in_use](/errors/idempotency_key_in_use.md): 409 Conflict. A request with this `Idempotency-Key` is still running, so this second copy cannot be answered yet. It happens when a client retries before the first call finished. - [grant_not_allowed](/errors/grant_not_allowed.md): 403 Forbidden. A key can only hand out scopes it has itself, and some scopes (the `subaccounts:*` ones) are never handed down. The request asked for a scope the creating key cannot grant. - [forbidden](/errors/forbidden.md): 403 Forbidden. The key is valid and has the scope, but what it asks for is not allowed to it: the object belongs to another organization or subaccount, or the role behind the key is too low. - [field_not_sensitive](/errors/field_not_sensitive.md): 422 Unprocessable. Only a field the pipeline marks as sensitive can be revealed. Read any other field from the case. - [external_ref_conflict](/errors/external_ref_conflict.md): 409 Conflict. Another contact in this organization already has this `externalRef`. An `externalRef` is unique per organization. - [domain_in_use](/errors/domain_in_use.md): 409 Conflict. Another organization already registered this domain. - [data_connector_unavailable](/errors/data_connector_unavailable.md): 422 Unprocessable. Your connector did not answer in time, answered with an error, or its address is not reachable. Nothing was stored. - [data_connector_not_ready](/errors/data_connector_not_ready.md): 409 Conflict. The connector is not active. Read its signing secret, serve the format and call POST /v2/data-connectors/{id}/check. - [data_connector_limit](/errors/data_connector_limit.md): 422 Unprocessable. An organization can have up to 10 data connectors. Delete one first. - [data_connector_invalid_response](/errors/data_connector_invalid_response.md): 422 Unprocessable. Your connector answered, but an account card, a search answer or a view page does not follow lelemon-connector/v1. The `detail` lists the failing paths with the rule each breaks, never the values. The check endpoint reads the manifest only, so it can pass while a card fails. - [contact_without_email](/errors/contact_without_email.md): 422 Unprocessable. The contact has no email address to write to. - [contact_opted_out](/errors/contact_opted_out.md): 422 Unprocessable. The contact opted out of this channel, so nothing is sent to them. - [conflict](/errors/conflict.md): 409 Conflict. The request is valid but clashes with the current state of the object, for example changing something that another request changed first or that is in a state that does not allow it. The `detail` says the state. - [channel_window_closed](/errors/channel_window_closed.md): 422 Unprocessable. More than 24 hours passed since the last message of the person and WhatsApp only accepts approved templates now. The message was not sent. - [catalog_not_connected](/errors/catalog_not_connected.md): 422 Unprocessable. The WhatsApp number that sends the message has no catalog, or the catalogId is not the one connected to it. The message was not sent. - [case_message_limit_reached](/errors/case_message_limit_reached.md): 409 Conflict. The case reached its limit of messages. Open a new case to keep talking. - [case_channel_not_api](/errors/case_channel_not_api.md): 422 Unprocessable. Only cases that came through the API can be written to as the contact. On other channels the contact writes by themselves. - [case_agent_in_control](/errors/case_agent_in_control.md): 409 Conflict. The agent is handling this case and would answer over your message. Take control first, or close the case. - [budget_exceeded](/errors/budget_exceeded.md): 402 Payment required. A budget with the action `stop` reached its monthly limit, so the agent no longer answers on that scope. The `budget` object of the answer says which budget, its limit and what was spent. - [approval_not_pending](/errors/approval_not_pending.md): 409 Conflict. Someone decided this approval first, or it expired. Read it to see its status. It cannot be decided twice. - [approval_decision_not_allowed](/errors/approval_decision_not_allowed.md): 403 Forbidden. This key is not named as an approver by the policy of the tool, it created the request itself, or it lacks the approvals:write scope. - [api_key_invalid](/errors/api_key_invalid.md): 401 Unauthorized. Missing, invalid or revoked API key. Send it as Authorization: Bearer . - [agent_version_conflict](/errors/agent_version_conflict.md): 409 Conflict. Someone saved the agent after you read it. Read it again and retry with its current version. - [agent_not_ready](/errors/agent_not_ready.md): 422 Unprocessable. The agent cannot be turned on yet because it lacks something required: instructions or a model. The `detail` lists what is missing and `param` names the first field. - [agent_not_exposed](/errors/agent_not_exposed.md): 403 Forbidden. This agent is internal and was not created through the API, so it is not exposed. Create a copilot with POST /v2/agents and audience internal. - [agent_channel_disabled](/errors/agent_channel_disabled.md): 422 Unprocessable. The agent does not have this channel enabled. - [actor_role_above_key](/errors/actor_role_above_key.md): 403 Forbidden. The actor declares a role higher than this key can declare. Declare a lower role or use a key with more reach. - [action_variable_needs_authorization](/errors/action_variable_needs_authorization.md): 400 Bad request. The action sends `contact.phone` or `contact.whatsapp_id` to your system, and those two leave Lelemon only with the authorization of the destination (article 15 bis of Law 21.719). The request has no `authorization` and the action has no current one for this destination. - [action_variable_in_query](/errors/action_variable_in_query.md): 400 Bad request. In a `GET` action everything goes in the URL, and the URL stays in the logs of your system and of whatever sits in front of it. `contact.phone`, `contact.whatsapp_id` and the variables that come from a field of the case do not go there. - [action_origin_not_allowed](/errors/action_origin_not_allowed.md): 403 Forbidden. This key may not create actions that call that site. An administrator adds the site to the key. - [action_destination_blocked](/errors/action_destination_blocked.md): 400 Bad request. That address cannot be used. It must be a public http or https URL that answers. - [Que el agente escriba primero](/legacy/guides/lelemon-api-triggers.md): Un agente contesta cuando le escriben. Con un trigger, además **empieza la conversación**: tu sistema avisa que pasó algo y el agente le escribe a esa persona. - [Métricas de las conversaciones para tu bodega de datos](/legacy/guides/lelemon-api-metricas.md): Una fila por conversación con sus tiempos: cuándo entró, cuándo el agente la derivó a una persona, cuándo alguien la tomó, cuándo se cerró y quién la cerró. Sirve para llevarlas cada hora a BigQuery u otra bodega y medir ahí cuántas resuelve el agente solo, cuántas pasan a una persona y cuánto esperan. - [Mandarle un mensaje a una persona desde tu sistema](/legacy/guides/lelemon-api-mensajes.md): Tu sistema escribe en una conversación que ya existe, por el mismo canal en que la persona habla con nosotros, sin que corra el agente. Sirve para una encuesta de satisfacción cuando el caso llega a su etapa de cierre, o para responderle desde tu mesa de soporte a alguien cuyo caso ya está escalado, sin copiar y pegar en la bandeja. - [Inventariar los agentes de Lelemon para una auditoría](/legacy/guides/lelemon-api-inventario.md): Documento para el equipo de cumplimiento o de tecnología que tiene que armar, y mantener al día, el inventario de los agentes de Lelemon de su organización: qué agentes hay, cómo están configurados y, sobre todo, **a qué terceros viajan los datos de las personas que atienden**. Sirve, por ejemplo, para alimentar el registro de actividades de tratamiento (Ley 21.719). Alcanza para implementarlo sin preguntarnos nada. - [Recibir avisos de Lelemon y resolver escalamientos desde otra aplicación](/legacy/guides/lelemon-api-externa.md): Documento para el equipo que va a escribir la integración. Describe las dos mitades —los avisos que les mandamos por webhook y cómo nos cuentan que resolvieron un escalamiento— y alcanza para implementar el lado de ustedes sin preguntarnos nada. - [Poner a una persona del equipo disponible o ausente desde tu sistema](/legacy/guides/lelemon-api-disponibilidad.md): Tu sistema cambia si una persona de tu equipo recibe casos nuevos. Sirve cuando los turnos viven en otro lado: al salir de turno la pones `ausente` y el reparto deja de asignarle casos, sin que ella apriete su botón. - [Mantener al día lo que el agente sabe](/legacy/guides/lelemon-api-conocimiento.md): Guía para empujar documentos a una colección de conocimiento desde un sistema propio, con una credencial de organización. Sirve para un flujo de n8n, para una GitHub Action, o para cualquier cosa que sepa hacer un `PUT`. - [Mantener el catálogo de un campo de lista desde una planilla](/legacy/guides/lelemon-api-catalogos.md): Tu sistema reemplaza las opciones de los campos de lista de un embudo. Sirve cuando el catálogo vive en otro lado —una hoja de cálculo, tu ERP, tu base de productos— y cambia seguido: en vez de cargarlo a mano en la pantalla, lo sincronizas. - [Crear un agente sin entrar a la pantalla](/legacy/guides/lelemon-api-aprovisionar.md): Guía para aprovisionar agentes desde un sistema propio, con una credencial de organización. Sirve para un flujo de n8n, para un guion de onboarding, o para cualquier cosa que sepa hacer un `POST`. - [Hablarle a un agente de Lelemon desde otra aplicación](/legacy/guides/lelemon-api-agentes.md): Documento para el equipo que va a escribir la integración. Describe los tres endpoints con los que una aplicación externa le delega una conversación a un agente de Lelemon y alcanza para implementar el lado de ustedes sin preguntarnos nada. - [Agendar en tu propia pantalla](/legacy/guides/lelemon-api-agenda.md): Tu sistema muestra los horarios libres de tu equipo y deja que la persona elija uno, sin salir de tu aplicación. La reunión queda en Google Calendar con su link de videollamada, y la invitación le llega sola a quien agendó. - [Darle acciones a un agente de Lelemon desde otra aplicación](/legacy/guides/lelemon-api-acciones.md): Documento para el equipo que va a escribir la integración. Describe cómo registrar una acción HTTP —una llamada a un sistema de ustedes que el agente puede hacer en medio de una conversación— y cómo concedérsela o quitársela a un agente. Alcanza para implementar el lado de ustedes sin preguntarnos nada. - [Lelemon documentation](/index.md): Put AI agents on WhatsApp and email inside your own product. Create agents, run conversations from code and send the right message when something happens. - [Use cases](/use-cases.md): Six complete setups, from an empty account to an agent that works, with every call in order, the real result of each step and a script you can run. - [Error codes](/errors.md): Every error code the Lelemon API v2 returns, with its HTTP status. Generated from the API contract.