Layi Docs
Layi SDK
Automate Layi agents, installed apps, knowledge, and workflows directly from your own services
Build on the durable workforce
The Layi SDK mirrors everything our dashboard can do—spin up workers, attach knowledge, stream runs, and orchestrate tool calls. Use it to weave agents into CRMs, ticketing queues, voice IVRs, or your own platform without waiting on UI releases.
Installation
Install directly from the Layi SDK subdirectory—same package we ship internally. Python 3.11+ is required.
Authenticate & configure
Generate a customer API key from Org Manager → Settings → API Keys, then export it wherever your workload runs. Installed service-template APIs use the customer key format pk_xxx:sk_xxx; do not use internal admin API keys for customer integrations.
- Set LAYI_API_KEY
export LAYI_API_KEY=pk_xxx:sk_xxx before running installed-service SDK scripts, or inject it through your secrets manager.
- Select environment
Point `LAYI_API_BASE` to staging or prod (defaults to https://agent.layi.ai).
- Allowlisted IPs
If your org restricts ingress, add the SDK host to Org Manager's network policy so runs are accepted.
Installed services
Use client.Services when your integration needs to discover or run actions from installed apps such as Receptionist, HR/payroll, or AI Data. These methods wrap the same customer-safe service-template API used by the dashboard and inherit tenant scoping, approval gates, advisory compliance checks, and audit events.
For direct HTTP calls, see API Integration. For model/tool access, see MCP Integration.
import asynciofrom layi import Layiasync def main(): client = Layi(api_key="pk_xxx:sk_xxx") service_id = "svc_123" contract = await client.Services.get_integration_contract(service_id=service_id) print("service=", contract["service_id"]) plan = await client.Services.plan_action( service_id=service_id, action_key="talent.list_volume_tier", params={"tier": "senior"}, ) print("plan=", plan["action_key"], plan["access_class"]) result = await client.Services.execute_action( service_id=service_id, action_key="talent.list_volume_tier", params={"tier": "senior"}, ) print("status=", result["status"]) tools = await client.Services.list_mcp_tools(service_id=service_id) print("mcp_tools=", [tool["name"] for tool in tools.get("tools", [])]) task = await client.Services.create_a2a_task( service_id=service_id, action_key="talent.list_volume_tier", params={"tier": "senior"}, partner_ref="partner-job-123", callback_url="https://partner.example/a2a/callback", callback_secret_ref="partner-callback-secret", ) print("task=", task["task_id"], task["status_url"])asyncio.run(main())Write, admin, and export operations may require approved_execution=True and an approval note. A2A callbacks use callback_secret_ref; do not send raw callback secrets in SDK payloads.
Quick start
This example bootstraps MCP tools, creates an agent, and streams output back to your service.
import asynciofrom layi import Layi from layi.tools import MCPToolsasync def main(): client = Layi(api_key="sk_live_xxx") tools = MCPTools( "https://tools.your-org.internal/mcp/", name="InternalToolbelt", ) agent = await client.Agent.create( name="OpsDuty", system_prompt="Resolve operations tickets with policy-compliant responses.", mcp_tools=[tools], allowed_tools=["lookup_inventory", "open_ticket"], ) # Recommended: initialize tool discovery via agent-service to reflect enabled tools await tools.initialize_via_agent_service( agents_client=agent._client, agent_id=agent._agent_id, ) thread = await client.Thread.create() run = await agent.run("Update the warehouse shipment ETA", thread) async for chunk in await run.get_stream(): print(chunk, end="")if __name__ == "__main__": asyncio.run(main())Public channels
Embed guest chat on customer sites and ingest external events via public webhooks.
import asynciofrom layi import Layiasync def main(): client = Layi(api_key="sk_live_xxx") # Public guest chat session = await client.PublicChat.create_session( handle="my-widget-handle", origin="https://example.com", ) chat = await client.PublicChat.send_message( token=session.token, session_id=session.session_id, thread_id=session.thread_id, message="Hi!", ) print("chat=", chat.agent_run_id, chat.run_id) # Public webhooks webhook = await client.PublicWebhooks.send( handle="my-handle", secret="my-shared-secret", payload={"event": "ticket.created", "ticket_id": "123"}, ) print("webhook=", webhook.thread_id, webhook.workflow_id)asyncio.run(main())Usage & billing (read-only)
Pull subscription, usage logs, and credit balances for dashboards or alerts.
import asynciofrom layi import Layiasync def main(): client = Layi(api_key="sk_live_xxx") status = await client.Billing.check_status() sub = await client.Billing.subscription() bal = await client.Billing.credit_balance() logs = await client.Billing.usage_logs(limit=50) print(status) print(sub) print(bal) print("usage_logs=", len(logs))asyncio.run(main())Live voice (token mint)
Mint LiveKit tokens via the voice gateway. Set LAYI_VOICE_API_BASE if voice is hosted separately.
import asynciofrom layi import Layiasync def main(): client = Layi( api_key="sk_live_xxx", voice_api_url="https://agent.layi.ai", ) tok = await client.Voice.mint_livekit_token(org_id="org_123") print(tok.server_url)asyncio.run(main())Tools registry
Manage toolkits, integrations, credentials, and MCP registrations through the same surface used by the dashboard.
import asynciofrom layi import Layiasync def main(): client = Layi(api_key="sk_live_xxx") toolkits = await client.ToolRegistry.list_toolkits() categories = await client.ToolRegistry.list_categories() integrations = await client.ToolRegistry.list_integrations() print("toolkits=", len(toolkits)) print("categories=", len(categories)) print("integrations=", len(integrations))asyncio.run(main())Embed (hosted widget)
For enterprises that prefer minimal code, we ship a hosted widget script with the Layi client. The only required input is your widget_id or handle.
<!-- Load the hosted widget script (served by the Layi dashboard at /layi-widget.js) --><script src="https://<your-layi-dashboard-domain>/layi-widget.js" async></script><!-- Zero-JS: auto-mount via data attributes --><div data-layi-widget-id="widget-123" data-layi-api-base="https://agent.layi.ai" data-layi-title="Ask Layi"></div><!-- Or: mount manually (1 line JS) --><script> window.LayiWidget.mount({ widgetId: "widget-123", apiBase: "https://agent.layi.ai", title: "Ask Layi", });</script>Note: the widget calls /public/chat/sessions and /public/chat/messages on LAYI_API_BASE. Ensure the widget’s allowed domains include your site (configured server-side).
Org admin via SDK
Manage API keys programmatically (useful for CI/CD, service accounts, or key rotation).
import asynciofrom layi import Layiasync def main(): client = Layi(api_key="sk_live_xxx") created = await client.APIKeys.create( title="CI Deploy Bot", description="Used by our deployment pipeline", ) print("created key_id=", created.key_id) keys = await client.APIKeys.list() print("keys=", [k.key_id for k in keys]) # Revoke or delete when rotating # await client.APIKeys.revoke(created.key_id) # await client.APIKeys.delete(created.key_id)if __name__ == "__main__": asyncio.run(main())What the SDK unlocks
Enterprise deployment tips
Treat SDK workloads like any other production integration.
- Rotate keys
Use Org Manager's rolling API keys and store them in Vault or AWS Secrets Manager.
- Isolate traffic
Pin SDK hosts to a service account and network segment so tool credentials never leak.
- Test with staging
Every API mirrors between staging + prod; run automated smoke tests before promoting prompts.