SDKs
Install the Python and TypeScript SDKs, sign in with a service account and make your first calls in a minute.
- Install liyagent or @liyagent/sdk
- Create a service account token
- List and install a template, ask an agent and handle errors
Liyagent has two official SDKs for the HTTP API. Both cover agents, runs, approvals, evals, knowledge and solution templates, and both send the same requests with the same retries and errors.
| Language | Package | Install |
|---|---|---|
| Python 3.10+ | liyagent on PyPI | pip install liyagent |
| TypeScript / JavaScript (Node 18+, Deno, Bun, browsers, edge) | @liyagent/sdk on npm | npm install @liyagent/sdk |
Get a token
The SDKs sign in with a service account, the credential a script or pipeline uses instead of a person's password. It keeps working where SSO or an authenticator code is required.
- Under Access → Users, add an account with no password and the role the script needs. Installing a template writes agents and guardrails, so it needs a role such as Administrator. Reading templates and asking agents needs less.
- Open Access → Service accounts and choose + New service account. Pick that account and how many days the secret lasts.
- Copy the secret. It is shown once. The token is
svc/<name>:<secret>.
See Service accounts for rotating and disabling them.
The address is the URL you open the console at: https://liyagent.com for the hosted service, or your own host if you run Liyagent yourself.
export LIYA_URL="https://liyagent.com"
export LIYA_TOKEN="svc/ci-deployer:..."Python quickstart
from liyagent import Client
with Client() as liya: # reads LIYA_URL and LIYA_TOKEN
for t in liya.templates.list(solution="itsm"):
print(t["key"], t["version"], t.get("title", ""))
plan = liya.templates.preview("it-ticket-triage", agent_id="desk-triage")
if plan["valid"]:
liya.templates.install("it-ticket-triage", agent_id="desk-triage")
else:
print("would be refused at", plan["step"], plan["refusal"]["detail"])
reply = liya.agents.ask("desk-triage", "VPN drops every 10 minutes since this morning")
print(reply["reply"] or reply.get("skipped"))AsyncClient has the same calls for asyncio: await liya.templates.list(), async for agent in liya.agents.list().
TypeScript quickstart
import { Client } from "@liyagent/sdk";
const liya = new Client(); // reads LIYA_URL and LIYA_TOKEN; or new Client({ baseUrl, token })
const { templates } = await liya.templates.list("itsm");
for (const t of templates) console.log(t.key, t.version, t.title);
const plan = await liya.templates.preview("it-ticket-triage", { agent_id: "desk-triage" });
if (plan.valid) await liya.templates.install("it-ticket-triage", { agent_id: "desk-triage" });
else console.log("would be refused at", plan.step, plan.refusal.detail);
const reply = await liya.agents.ask("desk-triage", "VPN drops every 10 minutes since this morning");
console.log(reply.reply || reply.skipped);CommonJS works too: const { Client } = require("@liyagent/sdk"). On the edge or in a browser, pass baseUrl and token explicitly. Never ship a service account secret to a browser.
What the SDKs cover
| Namespace | What it does |
|---|---|
agents | List (every page), get, create or change, delete, export and apply bundles (agents as code), ask, start, stop, run a workflow |
runs | Recent runs, a suspended run's checkpoint, resume it |
approvals | The queue of held calls: list, get, approve or reject by digest |
evals | Datasets, start a run, wait for it, compare with a pinned baseline |
knowledge | Answers from the knowledge base (API key), collections, draft articles to approve |
templates | List, preview, install with parameters, uninstall; author and publish your own |
Anything else: liya.request(...) in Python, liya.send(...) in TypeScript, with the same credentials, retries and errors. check_server() / checkServer() lists the operations the SDK uses that an older server does not serve.
Errors and retries
A refusal raises (or throws) a subclass of LiyagentError. Each one carries the HTTP status, the server's detail and the request id the server logged it under (request_id in Python, requestId in TypeScript).
| Status | Class | kind |
|---|---|---|
| 401 | AuthenticationError | auth |
| 403 | PermissionDeniedError (the message names the missing permission) | forbidden |
| 404 | NotFoundError | not_found |
| 400, 422 | BadRequestError | invalid |
| 409, 412 | ConflictError | conflict |
| 429 | RateLimitError | rate_limited |
| 5xx | InternalServerError | server |
| none | APIConnectionError (not reached, or timed out) | unreachable |
A 429 or 503, or a request that never reached the server, is sent again up to twice. A 500, 502 or 504 is also retried for GET, PUT and DELETE. The client waits as long as Retry-After says, or otherwise backs off exponentially. Set max_retries / maxRetries to change the number of retries, and timeout (seconds) / timeoutMs to change the timeout.
Support
- Questions and problems: docs@liyagent.com. Include the SDK version, the call you made and the error's request id.
- Security: see Security.
- What changed in each release: SDK changelog.