LionVoice API v1
ベースURL: https://api.lionvoice.app/api/v1。音声、Lion-AI、電話 — ひとつのプロダクト。頭脳のブランドは全体で Lion-AI。エンジン識別子は内部で、API応答では任意。
Base URL: https://api.lionvoice.app/api/v1
APIにモデル選択パラメータはない — 外に出てる頭脳は Lion-AI だけ。
ベースURL: https://api.lionvoice.app/api/v1。音声、Lion-AI、電話 — ひとつのプロダクト。頭脳のブランドは全体で Lion-AI。エンジン識別子は内部で、API応答では任意。
Base URL: https://api.lionvoice.app/api/v1
APIにモデル選択パラメータはない — 外に出てる頭脳は Lion-AI だけ。
1. ダッシュボード(APIキー)で APIキーをつくる — シークレットは一度だけ。2. エージェントをつくる。3. 電話番号(E.164)をつないでエージェントにマップ。4. テスト発信する。
export LV_KEY='lv_live_…'
# 1) who am I
curl -sS https://api.lionvoice.app/api/v1/tenant \
-H "Authorization: Bearer $LV_KEY"
# 2) create an agent
curl -sS https://api.lionvoice.app/api/v1/agents \
-H "Authorization: Bearer $LV_KEY" \
-H "Content-Type: application/json" \
-d '{
"name":"Reception",
"language":"en",
"voice":"Lion-AI Warm",
"prompt":"You are a receptionist. Address the caller as you.",
"first_message":"Hi, how can I help?",
"max_duration_sec":600
}'
# 3) attach a number
curl -sS https://api.lionvoice.app/api/v1/phone-numbers \
-H "Authorization: Bearer $LV_KEY" \
-H "Content-Type: application/json" \
-d '{"number_e164":"+37052431010","label":"Reception"}'
# 4) test outbound (use your own test line)
curl -sS https://api.lionvoice.app/api/v1/calls \
-H "Authorization: Bearer $LV_KEY" \
-H "Content-Type: application/json" \
-d '{"to_number":"+447554522255","agent_id":1}'
Create a key in the dashboard (API keys) or POST /keys. The secret is shown once. Send it as Bearer or X-LV-Api-Key. Ping does not need a key. A revoked key returns 401.
curl -sS https://api.lionvoice.app/api/v1/tenant \ -H "Authorization: Bearer lv_live_…" # or -H "X-LV-Api-Key: lv_live_…"
レート制限:APIキーあたり毎分120リクエスト。HTTP 429 は指数バックオフで再試行できる。Header Retry-After は60秒。
Headers: none. Auth: none.
# Response 200
{
"ok": true,
"service": "LionVoice API",
"version": "v1",
"time": "2026-09-07T09:00:00+00:00"
}
Headers: Authorization: Bearer lv_live_…
# Response 200
{
"ok": true,
"tenant": {
"id": 1,
"name": "AURIUS INTERNATIONAL LTD",
"email": "ops@example.invalid",
"plan": "studio",
"plan_included_minutes": 500,
"overage_eur_per_min": 0.09,
"balance_eur": 12.50,
"webhook_signing": {
"algorithm": "hmac-sha256",
"header": "X-LV-Signature",
"prefix": "269d7d4b"
},
"sip": {
"server": "sip.example.com",
"username": "200",
"port": 5060,
"transport": "udp",
"caller_id": "+37052431010",
"status": "registered"
},
"features": {
"callback_memory": 1,
"named_greeting": 1,
"cli_identity": 1,
"birthday_calls": 0,
"crm_bridge": 0
},
"modules": {
"voice": true,
"email_ai": true,
"chat_ai": true
},
"email_mailbox": "t1@email.lionvoice.app",
"email_mailbox_status": "ready"
}
}
| Field | Meaning |
|---|---|
plan | Current plan slug |
plan_included_minutes | Minutes included this month |
balance_eur | Wallet |
sip | Host / user / port / transport / status — never the password |
webhook_signing.prefix | First 8 chars of the HMAC secret. Full secret is not on GET /tenant. |
features.callback_memory | Remind why I already called this number |
features.named_greeting | Greet first + last name from billing |
features.cli_identity | Authorise by caller number |
features.birthday_calls | Birthday / care campaigns |
features.crm_bridge | Paid CRM / accounting attach (+€79/mo) |
modules.email_ai | Email AI entitled (manage via /email) |
modules.chat_ai | Chat AI entitled (manage via /chat) |
email_mailbox | Inbound forward address (no password) |
GET /agents · POST /agents · GET /agents/{id} · PATCH /agents/{id} · DELETE /agents/{id}
Headers: Authorization: Bearer lv_live_… · Content-Type: application/json
# POST /agents Body
{
"name": "Reception",
"language": "en",
"voice": "Lion-AI Warm",
"prompt": "You are a receptionist. Address the caller as you.",
"first_message": "Hi, how can I help?",
"max_duration_sec": 600,
"first_speaker": "assistant",
"webhook_url": "https://example.com/lionvoice/hooks"
}
# Response 200
{
"ok": true,
"agent": {
"id": 12,
"name": "Reception",
"language": "en",
"voice": "Lion-AI Warm",
"engine": "Lion-AI",
"max_duration_sec": 600,
"webhook_url": "https://example.com/lionvoice/hooks"
}
}
GET /files · POST /files {"filename","content","agent_id?"} · GET/PATCH/DELETE /files/{id}. Max a few pages per file (500 KB).
GET /tools. Create in the dashboard. The engine POSTs to your url with the secret header you set. CRM bridge add-on €79/mo.
POST /phone-numbers
{
"number_e164": "+37052431010",
"label": "Reception"
}
PATCH /phone-numbers/{id} {"agent_id","inbound_enabled":true}
Not a public REST write (password stays in the vault). Dashboard → SIP / VoIP: host, port, username, password, transport. LionVoice registers like a softphone. Then map the DID under Phone numbers.
ページネーション: GET /calls は limit(1–200、デフォルト25)と offset(0+)を受け付ける。カーソルはまだない。もっと先は大きい offset でもう一度。
GET /calls?limit=25&offset=0&agent_id=
# Response
{ "ok": true, "calls": [
{
"call_uuid": "6c202718-…",
"direction": "inbound",
"from_number": "+447554522255",
"to_number": "+37052431010",
"status": "completed",
"billable_seconds": 42,
"cost_eur": 0.00
}
]}
GET /calls/{uuid} — transcript + recording URL.
{
"ok": true,
"call": {
"call_uuid": "6c202718-…",
"transcript": "Lion-AI: Hi…\nCustomer: …",
"summary": "Invoice balance question",
"recording_url": "https://app.lionvoice.app/app/recording.php?uuid=…"
}
}
POST /calls — outbound. Body field is to_number (E.164), plus agent_id and optional schedule_at (UTC).
curl -sS https://api.lionvoice.app/api/v1/calls \
-H "Authorization: Bearer lv_live_…" \
-H "Content-Type: application/json" \
-d '{"to_number":"+447554522255","agent_id":1}'
POST /calls/{uuid}/transfer {"to"} E.164 or SIP URI.
GET /schedules · DELETE /schedules/{id}. schedule_at is UTC.
GET /analytics?days=14 · GET /usage?year=&month= · GET /plans · POST /topup {"amount_eur"} · POST /checkout.
POST /keys {"label"} — full secret only on create. DELETE /keys?id=.
Headers: Authorization: Bearer lv_live_…. Rotates the HMAC key used for X-LV-Signature. The full secret is returned once (same pattern as POST /keys). GET /tenant never returns it. After rotate, the previous secret stops verifying immediately — update your receiver first.
curl -sS -X POST https://api.lionvoice.app/api/v1/webhook-secret/regenerate \
-H "Authorization: Bearer $LV_KEY"
# Response 201
{
"ok": true,
"webhook_secret": "hex64…",
"prefix": "269d7d4b",
"note": "Save this secret now — it is not returned on GET /tenant."
}
テナント webhooks(ダッシュボードまたは POST /v1/webhooks):https URL + イベントのチェック。HMAC X-LV-Signature t=<unix>,v1=<hmac of timestamp + "." + raw body>。シークレットは一度だけ。2xx を返す。id(event_id)で重複排除。再試行は新しい delivery_id。エージェントの webhook_url は call.ended のレガシー購読としてまだ動く。
ダッシュボードで Webhooks を開いて、https URL を貼って、イベントにチェック、作成。署名シークレットを一度コピーして、Webhookをテスト。メンテするZIPはない。
Dashboard: app.lionvoice.app/app/?page=webhooks — paste https URL, tick events, Create, copy the secret once, then Test webhook.
Events: call.started, call.answered, call.ended, call.failed, transcript.completed, recording.ready, tool.executed.
HTTPS only. HMAC header X-LV-Signature: t=<unix>,v1=<hex> over timestamp + "." + raw body. Reject timestamps older than five minutes. Return 2xx. Deduplicate on id (event_id). A retry is a new delivery_id. Delivery logs store status, HTTP, time, event_id, delivery_id — not the payload.
# Headers
X-LV-Event: call.ended
X-LV-Delivery-Id: del_01J…
X-LV-Timestamp: 1757232000
X-LV-Signature: t=1757232000,v1=hexhmac
# Body (no transcript / phone in test events)
{
"id": "evt_01J…",
"type": "call.ended",
"created_at": "2026-09-07T09:00:00+00:00",
"data": {
"call_id": "6c202718-…",
"duration_sec": 84,
"status": "completed"
}
}
POST /v1/webhooks
GET /v1/webhooks
DELETE /v1/webhooks/{id}
POST /v1/webhooks/{id}/test
POST /v1/webhooks/{id}/rotate-secret
GET /v1/webhooks/{id}/deliveries
GET /v1/webhooks/snippet?lang=php
Same engine as the dashboard. Agent webhook_url remains a legacy subscriber for call.ended.
Control the Email AI mailbox from your own CRM / helpdesk. Requires modules.email_ai=true. Without the module → 403 module_not_enabled.
Dashboard: app.lionvoice.app/app/?page=email
GET /v1/email
GET /v1/email/branding
PATCH /v1/email/branding
GET /v1/email/messages?limit=25&offset=0
GET /v1/email/messages/{id}
GET /v1/email/usage
curl -sS -H "Authorization: Bearer lv_live_…" \
https://api.lionvoice.app/api/v1/email
# PATCH branding (logo, theme dark|light|neutral, font_key, header/footer HTML)
curl -sS -X PATCH -H "Authorization: Bearer lv_live_…" \
-H "Content-Type: application/json" \
-d '{"theme":"neutral","logo_url":"https://cdn.example.com/logo.png","footer_html":"<p>Thanks</p>"}' \
https://api.lionvoice.app/api/v1/email/branding
List returns metadata only (has_body_in / has_body_out). Detail returns full body_in / body_out. Never stores or returns mailbox IMAP passwords.
curl -sS -H "Authorization: Bearer lv_live_…" \ "https://api.lionvoice.app/api/v1/email/messages?limit=10" curl -sS -H "Authorization: Bearer lv_live_…" \ https://api.lionvoice.app/api/v1/email/messages/42
Configure the website chat widget and read session transcripts from your systems. Requires modules.chat_ai=true.
Public visitor endpoint (no API key — CORS / origin allowlist): POST https://lionvoice.app/api/lv-chat.php
GET /v1/chat
GET /v1/chat/widget
PATCH /v1/chat/widget
GET /v1/chat/sessions?limit=20
GET /v1/chat/sessions/{session_key}
GET /v1/chat/usage
curl -sS -H "Authorization: Bearer lv_live_…" \
https://api.lionvoice.app/api/v1/chat
curl -sS -X PATCH -H "Authorization: Bearer lv_live_…" \
-H "Content-Type: application/json" \
-d '{"enabled":true,"primary_color":"#0abfdc","position":"br","launcher_text":"Chat","greeting":{"en":"Hi — how can I help?","lt":"Labas — kuo galiu padėti?"},"origins":["https://example.com"]}' \
https://api.lionvoice.app/api/v1/chat/widget
Embed snippet is returned on GET /chat as embed_snippet. Positions: br bl tr tl.
curl -sS -H "Authorization: Bearer lv_live_…" \ https://api.lionvoice.app/api/v1/chat/sessions curl -sS -H "Authorization: Bearer lv_live_…" \ https://api.lionvoice.app/api/v1/chat/sessions/a1b2c3d4e5f67890
Bring your own BotFather token. LionVoice never returns the token after save. Alerts for Email AI inbound/outbound and Chat AI replies.
GET /v1/telegram
POST /v1/telegram {"bot_token":"123:AA…"}
PATCH /v1/telegram {"notify_email":true,"notify_chat":true}
DELETE /v1/telegram
POST /v1/telegram/link # after you tap Start in Telegram
POST /v1/telegram/test
curl -sS -X POST -H "Authorization: Bearer lv_live_…" \
-H "Content-Type: application/json" \
-d '{"bot_token":"123456:AA…"}' \
https://api.lionvoice.app/api/v1/telegram
# → open bot_link, tap Start, then:
curl -sS -X POST -H "Authorization: Bearer lv_live_…" \
https://api.lionvoice.app/api/v1/telegram/link
Paid module (billing_integrations, from Billing). Without it, API returns 403; the dashboard still shows Integrations with an upsell.
Custom connector: if your accounting app is not in the catalogue but has API docs — email hello@lionvoice.app the link. Same-day install when docs are clear.
Paste your Stripe secret and/or accounting API token in the dashboard (?page=integrations). LionVoice encrypts credentials and uses them so Voice, Chat and Email can look up your customers — who to serve, open invoices, payer codes — without inventing data.
Live today: Stripe (BYOK), Invoice123, F-sąskaita. Other majors (Xero, QuickBooks, Zoho Books, Exact, Sage, FreshBooks, Moneybird, FreeAgent, Holded, bexio, sevDesk, lexoffice, Wave, Saskaitos.lt, …) appear in the catalogue; OAuth / full sync ships next — you can already store keys where the provider uses a static token.
Platform Stripe (your LionVoice subscription) stays separate from tenant BYOK.
| Method | Path | Notes |
|---|---|---|
| GET | /integrations | Catalogue + connection status (secrets masked) |
| GET | /integrations/{provider} | One provider + connection |
| PUT/PATCH/POST | /integrations/{provider} | Body: credentials map or flat fields; optional enabled, test:true |
| POST | /integrations/{provider}/test | Live ping to provider API |
| DELETE | /integrations/{provider} | Disconnect / wipe credentials |
| GET/POST | /billing/lookup | email and/or phone / caller_id → customer context |
curl -sS -X PUT https://api.lionvoice.app/api/v1/integrations/stripe \
-H "Authorization: Bearer lv_live_…" \
-H "Content-Type: application/json" \
-d '{"secret_key":"sk_live_…","enabled":true,"test":true}'
curl -sS "https://api.lionvoice.app/api/v1/billing/lookup?email=client@example.com" \
-H "Authorization: Bearer lv_live_…"
Voice agents also get a customer_billing_lookup tool pointing at the same lookup. Call-config injects a short billing context when the CLI phone matches a connected provider.
Docs: Invoice123 · F-sąskaita Postman
Mini accounting for tenants: invoices (SF), payment notices (PN), cash receipts (PPK), received (supplier) invoices, clients, products/services, recurring schedules, banks, statement import and a client self-service portal. Dashboard: app.lionvoice.app/app/?page=books.
All amounts are integer cents (*_cents). Documents use the tenant logo, company type (UAB / individual activity / public / budgetary institution), VAT-payer flag and one of three selectable templates; the footer always keeps the lionvoice.app credit.
| Page | What it does |
|---|---|
?page=books&tab=dashboard | Income / expenses / profit, VAT threshold, monthly chart |
?page=books&tab=invoices | Issue, preview, PDF, email, mark paid (with bank + method), edit, create a PN from an invoice |
?page=books&tab=clients | Client list; open a client for totals, invoices, recurring services, edit, “View as client” |
?page=books&tab=expenses | Supplier invoices; smart scan (image/PDF) extracts supplier, VAT, lines and saves |
?page=books&tab=recurring | Recurring SF/PN schedules (interval, max count, contract, price after contract, notes) |
?page=books&tab=items | Product / service catalogue (edit included) |
?page=books&tab=receipts | Cash receipts (PPK), edit + email |
?page=books&tab=banks | Bank / Maxima till / Perlo terminal accounts, statement import, matching, collected totals |
?page=books&tab=settings | Seller details, VAT payer + company type, logo, invoice template, numbering |
Upload CSV/TSV/TXT/XLS/PDF from a bank, Maxima till or Perlo terminals (?page=books&tab=banks). The system parses the rows, stores them in lv_books_bank_tx, and auto-matches incoming payments to unpaid invoices (amount + counterparty / invoice number); unmatched rows can be assigned manually. When matched, the invoice is marked paid with the chosen bank.
Passwordless magic link. The tenant’s client opens it and sees their summary, invoices (with online-pay buttons), payment history and recurring-service progress.
Magic link: GET /api/lv-client-portal.php?token=<48hex>&lang=lt — the token is stored hashed, valid 14 days. A tenant can open it directly from the client page via View as client (no password).
Email chooser (shared marketplace): GET /api/lv-client-portal.php?email=client@example.com lists every LionVoice vendor account for that email; choosing one emails a sign-in link. This is how a client who uses several vendors picks the right account.
Optional parameters: lang=lt|en. PDFs are streamed from /api/lv-books-pdf.php?doc=invoice|receipt&id=&format=pdf&lang=.
GET /api/lv-books-template-preview.php?tpl=tpl1|tpl2|tpl3&lang=lt&t=<tenant_id>&format=html|pdf renders a sample document with the tenant branding — used by the template picker’s “Preview sample” link.
Dashboard ?page=books&tab=expenses&new=1 → upload an image or PDF; supplier name, codes, invoice number/dates, net/VAT/total and line items are extracted and saved without manual entry. Server-side only; provider name is never shown to clients.
Clients bring their own credentials. In ?page=integrations they pick a provider — Wise, URBO, Paysera, ContoQuick, Stripe, Invoice123, F-sąskaita and others — and paste their keys; credentials are encrypted per tenant. Providers using a static token or webhook secret are usable immediately; OAuth/full sync ships connector by connector.
Generic receiver (records an incoming payment and auto-matches an invoice):
POST /api/lv-integration-webhook.php?provider=wise&t=<tenant_id>&secret=<webhook_secret>
Header alternative: X-LV-Signature: <webhook_secret>
Body (JSON): { "amount": "120.00", "date": "2026-09-18",
"sender_name": "Acme", "reference": "SF-202609-0001" }
Accepted amount fields: amount, amount_cents, value, sum, total, gross. Counterparty: counterparty, sender_name, payer_name, customer_name, name. Reference: reference, invoice_number, description, details. Wrong or missing secret → 403; missing amount → 422.
Wise connection is live-tested via GET /v1/profiles (BYOK token) and shows the profile count. Paysera Checkout generates a signed hosted-payment redirect (data + ss1 = md5(data + sign_password)); the callback returns to the generic webhook above and auto-matches the invoice.
Documentation: Wise · URBO · Paysera · ContoQuick
The sender address is assigned by the system and shown read-only. From name and Signature are pulled from the tenant requisites; open ?page=email_ai and press Edit to change them. Changing the mailbox itself is support-only.
All paths are under https://api.lionvoice.app/api/v1 with Authorization: Bearer lv_live_…. Requires modules.books=true; otherwise 403 module_not_enabled. Amounts are integer cents.
| Method | Path | Notes |
|---|---|---|
| GET / PATCH | /books/profile | Seller details, bank, VAT payer, company type, template (tpl1|tpl2|tpl3) |
| GET / POST | /books/invoices | ?limit=; POST body: buyer_name, buyer_email, client_id, bank_id, notes, issue_date, due_date, lang, items[] |
| GET / PATCH / DELETE | /books/invoices/{id} | Read, edit (buyer, dates, notes, status, bank), delete |
| GET | /books/invoices/{id}/download | Streams the invoice PDF |
| POST | /books/invoices/{id}/mark-paid | Body: bank_id, method (bank/card/cash/other) |
| POST | /books/invoices/{id}/send | Emails the PDF to the buyer |
| POST | /books/invoices/{id}/make-pn | Creates a PN (payment notice) copy |
| GET / POST | /books/clients | List / create (payer code, personal code, client type, notes) |
| GET / PATCH / DELETE | /books/clients/{id} | Client + stats (month/year/unpaid/paid + invoices) |
| GET / POST | /books/expenses | Received (supplier) invoices |
| PATCH / DELETE | /books/expenses/{id} | Edit / delete |
| GET / POST | /books/items | Products / services catalogue |
| PATCH / DELETE | /books/items/{id} | Edit / delete |
| GET / POST | /books/receipts | Cash receipts (PPK) |
| PATCH / DELETE | /books/receipts/{id} | Edit / delete |
| GET | /books/recurring | Recurring schedules |
| PATCH / DELETE | /books/recurring/{id} | Edit (interval, max, contract, notes) / delete |
| GET / POST | /books/banks | Bank / Maxima till / Perlo accounts + collected totals |
| DELETE | /books/banks/{id} | Remove account |
| GET | /books/bank-tx | Imported statement payments (?limit=) |
| POST | /books/bank-tx/{id}/assign | Body: invoice_id — match + mark paid |
| POST | /books/bank-tx/{id}/ignore | Ignore a row |
| POST | /books/portal-link | Body: client_id, optional ttl_days, lang → returns a passwordless portal URL |
| POST | /books/invoices/{id}/payment-link | Creates a hosted payment link with the tenant’s connected provider (Paysera Checkout signed redirect) and stores it on the invoice; body: optional lang, test |
# Create an invoice
curl -sS -X POST https://api.lionvoice.app/api/v1/books/invoices \
-H "Authorization: Bearer " -H "Content-Type: application/json" \
-d '{"buyer_name":"Acme","buyer_email":"billing@acme.example","notes":"Thanks!",
"items":[{"description":"AI calls pack","qty":1,"unit_cents":15000}]}'
# Mark it paid via a bank
curl -sS -X POST https://api.lionvoice.app/api/v1/books/invoices/12/mark-paid \
-H "Authorization: Bearer " -H "Content-Type: application/json" \
-d '{"bank_id":1,"method":"bank"}'
# Passwordless client portal link
curl -sS -X POST https://api.lionvoice.app/api/v1/books/portal-link \
-H "Authorization: Bearer " -H "Content-Type: application/json" \
-d '{"client_id":5,"ttl_days":14,"lang":"lt"}'
形: {"ok":false,"error":"code","message":"…"}。再試行可: 429 と 5xx。不可: 400、401、403、404。409 はだいたい不可。
{
"ok": false,
"error": "insufficient_balance",
"message": "Your wallet balance is too low."
}
# Email / Chat when module off
{
"ok": false,
"error": "module_not_enabled",
"module": "email_ai",
"hint": "Enable this module in the dashboard Billing / Modules, then retry."
}
| HTTP | Retry? | Typical error |
|---|---|---|
| 400 | No | valid_to_number_required |
| 401 | No | unauthorized |
| 403 | No | plan / cap |
| 404 | No | not_found |
| 409 | Usually no | conflict |
| 429 | Yes, exponential backoff | rate_limited |
| 500 | Yes | engine |
公式クライアントはロードマップ。いまは下の curl、PHP、JavaScript、Python 例をコピー。OpenAPI ファイル(/openapi.json)を Postman にインポート。
# JavaScript
const r = await fetch('https://api.lionvoice.app/api/v1/tenant', {
headers: { Authorization: 'Bearer lv_live_…' }
});
# Python
import requests
requests.get('https://api.lionvoice.app/api/v1/ping').json()
# PHP
$ch = curl_init('https://api.lionvoice.app/api/v1/tenant');
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ['Authorization: Bearer lv_live_…'],
CURLOPT_RETURNTRANSFER => true,
]);