Run Lelemon for your customers
This guide is for platforms such as a POS, a CRM or a booking app. Your organization is the platform. Each of your customers is a subaccount: a full organization with its own agents, pipelines, cases, numbers and keys, isolated from your other subaccounts. Your platform pays for all of them.
- When your customer signs up, create the subaccount with your own id as externalRef and an Idempotency-Key.
- Lelemon answers with the sub_ id. A second subaccount with the same externalRef is a 409 external_ref_conflict.
- Any /v2 route acts on the subaccount when you add the header. The key does not change, only the organization.
- A subaccount is a full organization, isolated from your other subaccounts. One that is not yours answers 404.
- You create a tool once in your organization and share it. Each subaccount grants it to its own agents.
- When an agent of a subaccount uses the shared tool, your backend receives a call signed with your secret and Lelemon-Subaccount-Id, so it knows which customer is asking.
- One webhook endpoint with scope customers receives the events of all subaccounts. Each carries customerId, the sub_ id it belongs to.
1. Create the subaccount when your customer signs up
Send your own id as externalRef so you never need a lookup table. fromTemplates copies draft agents and pipelines: agent ids come from GET /v2/agent-templates (Lelemon's templates and the ones you saved from the dashboard; leave agents out when it comes back empty) and pipeline ids from GET /v2/pipelines.
A subaccount is this object:
Subaccountobject, 7 fields
objectenumrequiredsubaccountidstringrequiredexternalRefstringrequirednamestringrequiredcreatedAtstring (date-time)requiredupdatedAtstring (date-time)requiredcreatedSubaccountCreatedResourcesoptionalOnly on create: what fromTemplates made.
SubaccountCreatedResources2 fields
agentsstring[]requiredpipelinesstring[]required
Store the sub_... id next to your customer. If you lose it, GET /v2/subaccounts?externalRef=restaurant-1042 finds it.
externalRef is unique among your subaccounts: a second subaccount with the same value answers 409 external_ref_conflict. Use your customer's stable id, never an email, which can change.
The key you use needs subaccounts:write.
2. Act on it with your own key
Add the Lelemon-Subaccount header to any /v2 route. The key does not change, only the organization it acts on.
A subaccount that is not yours, or was deleted, answers 404, the same as one that never existed. /v2/subaccounts itself rejects the header with 400.
3. Connect their WhatsApp number
Create a connection link and show setupUrl as a button in your product. Your customer confirms the number in Meta and never opens Lelemon.
Use coexistence when your customer keeps using the WhatsApp Business app on that number, and dedicated for a number only the agent uses. When the link completes you receive phone_number.connected. A number belongs to the subaccount that connected it, and the agent that answers on it is routed to the entry stage of one of its pipelines.
A subaccount can have several pending links at once, one per phone, so you can connect every branch in parallel. Asking again for a phone that already has a pending link answers 409 resource_in_use. When a number is linked, Lelemon matches it to the pending link by the phone you asked for. A number that matches none of them is detached and ignored. Name each number with PATCH /v2/whatsapp/phone-numbers/{id} and { "label": "Branch Centro" }. Business hours and time zone belong to the organization, not to a number: the route does not set them.
4. One webhook endpoint for every subaccount
Create an endpoint with "scope": "customers" to receive the events of all your subaccounts. Each event carries customerId, the sub_... id it belongs to.
An endpoint with "scope": "self" receives the events of the platform organization only.
Tools inside each subaccount
Each customer can have its own agent with tools that only reach that customer's systems.
- Your key creates them.
POST /v2/actionsandPOST /v2/mcp-serverswithLelemon-Subaccountcreate the tool inside the subaccount. The site of the tool must be one of theallowedActionOriginsof your key. - Its key creates them. A subaccount key can hold
actions:write. Give it sites withallowedActionOriginswhen you create it. They must be sites of your own key. If you leave them out, the key gets the same sites as yours. - Isolation. An action or an MCP server belongs to one subaccount. Another subaccount, and you without the header, do not see it, change it or delete it.
Share a tool with all your subaccounts
Create the tool once in your organization with "sharedWithSubaccounts": true, or turn it on later with PATCH /v2/actions/{id}. Then:
GET /v2/agents/{id}/toolsfor an agent of a subaccount lists it withsharedByPlatform: true, andPUT /v2/agents/{id}/tools/{toolId}grants it.- The call to your system is signed with your signing secret and carries
Lelemon-Subaccount-Id, so your backend knows which customer is asking. Verify it withverifyRequestof the SDK. - A subaccount cannot read, change or delete it, and cannot create a tool with the same name. You cannot share a tool whose name a subaccount already uses.
- Turning sharing off, or deleting the action, removes it from the agents of your subaccounts.
- Only a platform can share. A subaccount that sends
sharedWithSubaccountsanswers422.
Share an MCP server with all your subaccounts
An MCP server works the same way. Connect it in your organization with "sharedWithSubaccounts": true in POST /v2/mcp-servers, or turn it on later with PATCH /v2/mcp-servers/{id}. Then:
GET /v2/mcp-serversin a subaccount lists it withsharedByPlatform: true, andGET /v2/agents/{id}/toolslists its tools withkind: "mcp_tool"andsharedByPlatform: true.PUT /v2/agents/{id}/tools/{toolId}grants them.- The calls go out to your server with your credentials. When you turned on the run identity of the server, each call carries the signed context of the subaccount that made it, so your server knows which customer is asking.
- A subaccount can read it and grant its tools, but cannot change it, discover its tools again or delete it. It cannot connect a server whose name starts like a shared one, and you cannot share a server whose name starts like one a subaccount already has.
- Turning sharing off, or deleting the server, removes its tools from the agents of your subaccounts.
- Only a platform can share. A subaccount that sends
sharedWithSubaccountsanswers422.
Keys inside a subaccount
POST /v2/subaccounts/{id}/api-keys issues a key that sees only that subaccount. Its scopes cannot exceed those of the key that created it and cannot include subaccounts:*. A subaccount key cannot use Lelemon-Subaccount or manage subaccounts. The response holds the secret, so it is never replayed from the idempotency cache.
With actions:write, the key also takes allowedActionOrigins, a subset of the sites of your own key. A site you do not have answers 403 with param: allowedActionOrigins, and sites without actions:write answer 400.
When a customer leaves
DELETE /v2/subaccounts/{id} closes the subaccount.