Cookbook

Copy-paste examples for common tasks. Every recipe includes cURL, TypeScript (SDK), Python, and Node.js variants. Replace YOUR_API_KEY with your per-user API key.

Base URL: https://api.lvng.ai/api

Authenticate

All requests need an API key via the Authorization header as a Bearer token. The x-api-key header is also supported.

cURL
400">curl https:400">class="text-zinc-500">//api.lvng.ai/api/v2/agents \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY"
TypeScript (SDK)
400">import { LvngClient } 400">from 400">class="text-emerald-400">'@lvng/sdk';

400">const lvng = 400">new LvngClient({
  apiKey: process.env.LVNG_API_KEY
});
Python
400">import os
400">import requests

BASE = 400">class="text-emerald-400">"https:400">class="text-zinc-500">//api.lvng.ai/api"
HEADERS = {
    400">class="text-emerald-400">"Authorization": f400">class="text-emerald-400">"Bearer {os.environ['LVNG_API_KEY']}",
    400">class="text-emerald-400">"Content-Type": 400">class="text-emerald-400">"application/json"
}
Node.js
400">const axios = require(400">class="text-emerald-400">'axios');

400">const api = axios.create({
  baseURL: 400">class="text-emerald-400">'https:400">class="text-zinc-500">//api.lvng.ai/api',
  headers: { 400">class="text-emerald-400">'Authorization': 400">class="text-emerald-400">`Bearer ${process.env.LVNG_API_KEY}` }
});

List Workflows

Get all workflows in your workspace.

cURL
400">curl https:400">class="text-zinc-500">//api.lvng.ai/api/v2/workflows \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY"
TypeScript (SDK)
400">const { workflows } = 400">await lvng.workflows.list();
console.log(workflows);
Python
resp = requests.get(f400">class="text-emerald-400">"{BASE}/v2/workflows", headers=HEADERS)
workflows = resp.json()[400">class="text-emerald-400">"data"]
for wf in workflows:
    print(f400">class="text-emerald-400">"{wf['name']} — {wf['status']}")
Node.js
400">const { data } = 400">await api.get(400">class="text-emerald-400">'/v2/workflows');
console.log(data.data);

Execute a Workflow

Trigger a workflow with input variables and get the run ID.

cURL
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v2/workflows/WF_ID/execute \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY" \
  -H 400">class="text-emerald-400">"Content-Type: application/json" \
  -d 400">class="text-emerald-400">'{"inputs": {"topic": "Q4 market analysis"}}'
TypeScript (SDK)
400">const run = 400">await lvng.workflows.execute(400">class="text-emerald-400">'WF_ID', {
  inputs: { topic: 400">class="text-emerald-400">'Q4 market analysis' }
});
console.log(400">class="text-emerald-400">'Run ID:', run.id);
Python
resp = requests.post(
    f400">class="text-emerald-400">"{BASE}/v2/workflows/WF_ID/execute",
    headers=HEADERS,
    json={400">class="text-emerald-400">"inputs": {400">class="text-emerald-400">"topic": 400">class="text-emerald-400">"Q4 market analysis"}}
)
run = resp.json()[400">class="text-emerald-400">"data"]
print(f400">class="text-emerald-400">"Run ID: {run['id']}")
Node.js
400">const { data } = 400">await api.post(400">class="text-emerald-400">'/v2/workflows/WF_ID/execute', {
  inputs: { topic: 400">class="text-emerald-400">'Q4 market analysis' }
});
console.log(400">class="text-emerald-400">'Run ID:', data.data.id);

Create an Agent

Deploy a new AI agent with a custom system prompt and tools.

cURL
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v2/agents \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY" \
  -H 400">class="text-emerald-400">"Content-Type: application/json" \
  -d '{
    400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Research Assistant",
    400">class="text-emerald-400">"system_prompt": 400">class="text-emerald-400">"You are a helpful research assistant.",
    400">class="text-emerald-400">"model": 400">class="text-emerald-400">"claude-sonnet-4-6",
    400">class="text-emerald-400">"tools": [400">class="text-emerald-400">"web_search", 400">class="text-emerald-400">"knowledge_search"]
  }'
TypeScript (SDK)
400">const agent = 400">await lvng.agents.create({
  name: 400">class="text-emerald-400">'Research Assistant',
  systemPrompt: 400">class="text-emerald-400">'You are a helpful research assistant.',
  model: 400">class="text-emerald-400">'claude-sonnet-4-6',
  tools: [400">class="text-emerald-400">'web_search', 400">class="text-emerald-400">'knowledge_search']
});
console.log(400">class="text-emerald-400">'Agent ID:', agent.id);
Python
resp = requests.post(f400">class="text-emerald-400">"{BASE}/v2/agents", headers=HEADERS, json={
    400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Research Assistant",
    400">class="text-emerald-400">"system_prompt": 400">class="text-emerald-400">"You are a helpful research assistant.",
    400">class="text-emerald-400">"model": 400">class="text-emerald-400">"claude-sonnet-4-6",
    400">class="text-emerald-400">"tools": [400">class="text-emerald-400">"web_search", 400">class="text-emerald-400">"knowledge_search"]
})
agent = resp.json()[400">class="text-emerald-400">"data"]
print(f400">class="text-emerald-400">"Agent ID: {agent['id']}")

Message an Agent

Send a message to a running agent and get a response.

cURL
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v2/agents/AGENT_ID/message \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY" \
  -H 400">class="text-emerald-400">"Content-Type: application/json" \
  -d 400">class="text-emerald-400">'{"message": "What are the top trends in AI for 2026?"}'
TypeScript (SDK)
400">const response = 400">await lvng.agents.message(400">class="text-emerald-400">'AGENT_ID', {
  message: 400">class="text-emerald-400">'What are the top trends in AI for 2026?'
});
console.log(response.content);
Python
resp = requests.post(
    f400">class="text-emerald-400">"{BASE}/v2/agents/AGENT_ID/message",
    headers=HEADERS,
    json={400">class="text-emerald-400">"message": 400">class="text-emerald-400">"What are the top trends in AI for 2026?"}
)
print(resp.json()[400">class="text-emerald-400">"data"][400">class="text-emerald-400">"content"])

Search Knowledge

Semantic search across your ingested knowledge graph.

cURL
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/knowledge/search \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY" \
  -H 400">class="text-emerald-400">"Content-Type: application/json" \
  -d 400">class="text-emerald-400">'{"query": "revenue trends Q4", "limit": 10}'
TypeScript (SDK)
400">const results = 400">await lvng.knowledge.search({
  query: 400">class="text-emerald-400">'revenue trends Q4',
  limit: 10
});
results.forEach(r => console.log(r.title, r.score));
Python
resp = requests.post(f400">class="text-emerald-400">"{BASE}/knowledge/search", headers=HEADERS, json={
    400">class="text-emerald-400">"query": 400">class="text-emerald-400">"revenue trends Q4",
    400">class="text-emerald-400">"limit": 10
})
for result in resp.json()[400">class="text-emerald-400">"data"]:
    print(f400">class="text-emerald-400">"{result['title']} — score: {result['score']}")

Chat with AI

Send a message to the AI and get a response.

cURL
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v2/chat \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY" \
  -H 400">class="text-emerald-400">"Content-Type: application/json" \
  -d '{
    400">class="text-emerald-400">"message": 400">class="text-emerald-400">"Summarize the latest market research",
    400">class="text-emerald-400">"channelId": 400">class="text-emerald-400">"CHANNEL_ID"
  }'
Python
resp = requests.post(f400">class="text-emerald-400">"{BASE}/v2/chat", headers=HEADERS, json={
    400">class="text-emerald-400">"message": 400">class="text-emerald-400">"Summarize the latest market research",
    400">class="text-emerald-400">"channelId": 400">class="text-emerald-400">"CHANNEL_ID"
})
print(resp.json()[400">class="text-emerald-400">"data"][400">class="text-emerald-400">"content"])

Stream Chat (SSE)

Stream AI responses in real-time using Server-Sent Events.

cURL (streaming)
400">curl -N -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v2/chat/stream \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY" \
  -H 400">class="text-emerald-400">"Content-Type: application/json" \
  -d 400">class="text-emerald-400">'{"message": "Write a 3-paragraph market analysis"}'
TypeScript (SSE)
400">const response = 400">await fetch(400">class="text-emerald-400">'https:400">class="text-zinc-500">//api.lvng.ai/api/v2/chat/stream', {
  method: 400">class="text-emerald-400">'POST',
  headers: {
    400">class="text-emerald-400">'Authorization': 400">class="text-emerald-400">`Bearer ${process.env.LVNG_API_KEY}`,
    400">class="text-emerald-400">'Content-Type': 400">class="text-emerald-400">'application/json'
  },
  body: JSON.stringify({ message: 400">class="text-emerald-400">'Write a 3-paragraph analysis' })
});

400">const reader = response.body.getReader();
400">const decoder = 400">new TextDecoder();

while (true) {
  400">const { done, value } = 400">await reader.read();
  400">if (done) break;
  400">const chunk = decoder.decode(value);
  process.stdout.write(chunk);
}
Python (SSE)
400">import sseclient
400">import requests

resp = requests.post(
    f400">class="text-emerald-400">"{BASE}/v2/chat/stream",
    headers=HEADERS,
    json={400">class="text-emerald-400">"message": 400">class="text-emerald-400">"Write a 3-paragraph analysis"},
    stream=True
)

client = sseclient.SSEClient(resp)
for event in client.events():
    print(event.data, end=400">class="text-emerald-400">"", flush=True)

Send a Channel Message

Post a message to a workspace channel.

cURL
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v2/messages \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY" \
  -H 400">class="text-emerald-400">"Content-Type: application/json" \
  -d '{
    400">class="text-emerald-400">"channel_id": 400">class="text-emerald-400">"CHANNEL_ID",
    400">class="text-emerald-400">"content": 400">class="text-emerald-400">"Hello 400">from the API!"
  }'
Python
resp = requests.post(f400">class="text-emerald-400">"{BASE}/v2/messages", headers=HEADERS, json={
    400">class="text-emerald-400">"channel_id": 400">class="text-emerald-400">"CHANNEL_ID",
    400">class="text-emerald-400">"content": 400">class="text-emerald-400">"Hello 400">from the API!"
})
msg = resp.json()[400">class="text-emerald-400">"data"]
print(f400">class="text-emerald-400">"Message ID: {msg['id']}")
Node.js
400">const { data } = 400">await api.post(400">class="text-emerald-400">'/v2/messages', {
  channel_id: 400">class="text-emerald-400">'CHANNEL_ID',
  content: 400">class="text-emerald-400">'Hello 400">from the API!'
});
console.log(400">class="text-emerald-400">'Message ID:', data.data.id);

Generate & Revoke API Keys

Programmatically manage API keys (requires JWT auth, not API key auth).

cURL
# Create a key
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v2/api-keys \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_JWT_TOKEN" \
  -H 400">class="text-emerald-400">"Content-Type: application/json" \
  -d 400">class="text-emerald-400">'{"name": "ci-pipeline", "scopes": ["read", "execute"]}'

# List keys
400">curl https:400">class="text-zinc-500">//api.lvng.ai/api/v2/api-keys \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_JWT_TOKEN"

# Revoke a key
400">curl -X 400">DELETE https:400">class="text-zinc-500">//api.lvng.ai/api/v2/api-keys/KEY_ID \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_JWT_TOKEN"
Python
# Create
resp = requests.post(f400">class="text-emerald-400">"{BASE}/v2/api-keys",
    headers={400">class="text-emerald-400">"Authorization": f400">class="text-emerald-400">"Bearer {jwt_token}", 400">class="text-emerald-400">"Content-Type": 400">class="text-emerald-400">"application/json"},
    json={400">class="text-emerald-400">"name": 400">class="text-emerald-400">"ci-pipeline", 400">class="text-emerald-400">"scopes": [400">class="text-emerald-400">"read", 400">class="text-emerald-400">"execute"]}
)
new_key = resp.json()[400">class="text-emerald-400">"data"][400">class="text-emerald-400">"key"]
print(f400">class="text-emerald-400">"New key: {new_key}")  # Save this — shown once!

# Revoke
requests.delete(f400">class="text-emerald-400">"{BASE}/v2/api-keys/{key_id}",
    headers={400">class="text-emerald-400">"Authorization": f400">class="text-emerald-400">"Bearer {jwt_token}"}
)

Create a Digital Twin

Add an AI persona to your workspace.

cURL
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v2/twins \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY" \
  -H 400">class="text-emerald-400">"Content-Type: application/json" \
  -d '{
    400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Marketing Expert",
    400">class="text-emerald-400">"personality": 400">class="text-emerald-400">"creative, data-driven, concise",
    400">class="text-emerald-400">"system_prompt": 400">class="text-emerald-400">"You are a senior marketing strategist with 15 years of experience."
  }'
Python
resp = requests.post(f400">class="text-emerald-400">"{BASE}/v2/twins", headers=HEADERS, json={
    400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Marketing Expert",
    400">class="text-emerald-400">"personality": 400">class="text-emerald-400">"creative, data-driven, concise",
    400">class="text-emerald-400">"system_prompt": 400">class="text-emerald-400">"You are a senior marketing strategist with 15 years of experience."
})
twin = resp.json()[400">class="text-emerald-400">"data"]
print(f400">class="text-emerald-400">"Twin ID: {twin['id']}")

Full Cookbook on GitHub

Browse the complete cookbook with runnable scripts, CI/CD templates, and integration patterns.

LVNG-AI/cookbook

Next Steps