Layi Docs

Layi SDK

Automate Layi agents, installed apps, knowledge, and workflows directly from your own services

Last updated: June 2026

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.

Provision agents
Create supervisors or specialists, assign prompts, and register MCP tools in one API call.
Wire knowledge
Upload documents, MinIO objects, or embeddings so every run stays grounded in your data.
Stream outcomes
Subscribe to Temporal-backed run streams for dashboards, alerts, or auditing.

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

Agent lifecycle automation
Promote new prompts via CI/CD, rotate knowledge, or rehydrate memory slots after a deploy.
Observability hooks
Subscribe to run events, warnings, and human-in-the-loop escalations so your tooling stays in sync.
FastMCP integrations
Register MCP servers per agent to keep network boundaries tight while exposing only the tools you whitelist.
Org automations
Provision orgs, roles, and quotas when HRIS systems emit joiners/movers/leavers events.

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.

Mobile App