Base URL: https://api.lionvoice.app/api/v1. Mowa, Lion-AI i telefonia — jeden produkt. Mózg w całym produkcie to Lion-AI; identyfikatory silnika są wewnętrzne i opcjonalne w odpowiedziach API.
Base URL: https://api.lionvoice.app/api/v1
API nie ma parametru wyboru modelu — Lion-AI to jedyny widoczny mózg.
5-minutowy Quick Start dla programisty
1. W panelu utwórz klucz API (API keys) — sekret widać tylko raz. 2. Utwórz agenta. 3. Podłącz numer (E.164) i przypisz do agenta. 4. Wykonaj testowe połączenie wychodzące.
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}'
Uwierzytelnianie
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.
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.
POST/keys{"label"} — full secret only on create. DELETE /keys?id=.
POST /webhook-secret/regenerate
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."
}
Webhooki
Ustaw webhook_url na agencie (tylko https). Po każdym zakończonym połączeniu LionVoice wysyła JSON raz (8 s). Sprawdź X-LV-Signature sekretem z POST /webhook-secret/regenerate (pokazywany raz; GET /tenant tylko prefix). Zdarzenie: call.completed.
Beginner — Create a webhook
Dashboard → Webhooks: URL + events → Create. Secret shown once. Test webhook. Snippet to verify HMAC.
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"
}
}
Developer — Webhook API
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.
Email AI
Control the Email AI mailbox from your own CRM / helpdesk. Requires modules.email_ai=true. Without the module → 403 module_not_enabled.
Bring your own BotFather token. LionVoice never returns the token after save. Alerts for Email AI inbound/outbound and Chat AI replies.
Endpoints
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
Integrations (Stripe + accounting)
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.
REST
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
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.
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.
Dashboard pages
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”
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.
Client self-service portal
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=.
Invoice template preview
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.
Received-invoice smart scan
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.
Provider payment webhooks (BYOK)
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" }
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.
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.
REST API (Books)
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)
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
Examples
# 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"}'
Błędy
Kształt: {"ok":false,"error":"kod","message":"…"}. Do ponowienia: 429 i 5xx. Nie: 400, 401, 403, 404. 409 zwykle nie.
{
"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
SDK
Oficjalne klienty są w planie. Dziś: kopiuj przykłady curl, PHP, JavaScript i Python poniżej. Importuj OpenAPI (/openapi.json) do Postmana.