Getting Started
From zero to your first synthesized audio in about 30 minutes. Lecturia is in invite-only beta — if you don't have an invitation yet, join the waitlist first.
Base URL for everything below:
https://api.lecturia.ai/v1/saas
Every endpoint except the two /auth/* calls authenticates with a bearer
API key (Authorization: Bearer lk_live_... or lk_test_...). Details in
Authentication.
1. Create your account
Register with the invite token from your invitation email. When
invite_token is present, the account is created for the address the
invitation is bound to (the email field is ignored):
curl -X POST https://api.lecturia.ai/v1/saas/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "dev@example.com",
"password": "correct horse battery staple",
"invite_token": "YOUR_INVITE_TOKEN"
}'
201returns your account and a session.202means email confirmation is pending — click the link in your inbox, then log in withPOST /auth/login.403 invite_invalidmeans the token can't be honoured (expired, consumed, or unknown — the API deliberately doesn't say which).
2. Get your first API key
During the beta your first key (with admin scope) is provisioned by the
Lecturia team together with your invitation. If you don't have one, reply to
your invitation email.
Keys are shown exactly once at creation and are never recoverable — store the plaintext in your secret manager immediately.
Once you hold an admin-scoped key you mint further keys yourself. Start with a sandbox key — it exercises the whole API without spending credits:
curl -X POST https://api.lecturia.ai/v1/saas/keys \
-H "Authorization: Bearer lk_live_YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "local dev", "scopes": ["read", "write"], "environment": "test" }'
The response's key field is your lk_test_... sandbox key. More in
Sandbox.
3. Verify the key works
curl https://api.lecturia.ai/v1/saas/me \
-H "Authorization: Bearer lk_test_YOUR_KEY"
A 200 with your account profile means you're authenticated.
4. Pick a voice
Voices ("e-readers") are listed with per-character pricing:
curl https://api.lecturia.ai/v1/saas/ereaders \
-H "Authorization: Bearer lk_test_YOUR_KEY"
Note an id from the response — the next call needs it.
5. Your first audio
POST /tts:synthesize turns up to 5,000 characters into an MP3 and returns
a 24-hour presigned URL. On a sandbox key this costs nothing:
curl -X POST "https://api.lecturia.ai/v1/saas/tts:synthesize" \
-H "Authorization: Bearer lk_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "text": "Hello from Lecturia.", "ereader_id": "YOUR_EREADER_ID", "format": "mp3" }'
// TypeScript (Node 18+, no dependencies)
const response = await fetch("https://api.lecturia.ai/v1/saas/tts:synthesize", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.LECTURIA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
text: "Hello from Lecturia.",
ereader_id: process.env.LECTURIA_EREADER_ID,
format: "mp3",
}),
});
if (!response.ok) {
const { error } = await response.json();
throw new Error(`${error.code}: ${error.message} (request ${error.request_id})`);
}
const { audio_url } = await response.json();
console.log("listen:", audio_url);
# Python 3.10+ (pip install httpx)
import os
import httpx
response = httpx.post(
"https://api.lecturia.ai/v1/saas/tts:synthesize",
headers={"Authorization": f"Bearer {os.environ['LECTURIA_API_KEY']}"},
json={
"text": "Hello from Lecturia.",
"ereader_id": os.environ["LECTURIA_EREADER_ID"],
"format": "mp3",
},
)
if response.is_error:
error = response.json()["error"]
raise RuntimeError(f"{error['code']}: {error['message']} (request {error['request_id']})")
print("listen:", response.json()["audio_url"])
Open audio_url in a browser — that's your first Lecturia audio.
6. Going live
- Purchase credits at app.lecturia.ai (web only —
the API has no purchase endpoint by design). Live synthesis charges
credits; a
freeaccount that never purchased is blocked from minting keys with402 api_access_requires_credits. - Mint a live key (
"environment": "live") the same way as the sandbox key. - Register a webhook to get
material.ready/tts_sync.completedevents instead of polling. - For whole ebooks, use the materials pipeline:
POST /materials/upload-url→ upload →POST /materials/{id}/confirm-upload→ convert chunks. Full schemas in the API Reference.
Troubleshooting
| You see | Why | Fix |
|---|---|---|
401 invalid_api_key | Key unknown, or you sent a truncated/mangled value | Re-copy the key; check for whitespace |
401 missing_api_key | No Authorization header reached us | Send Authorization: Bearer lk_... |
403 bearer_not_allowed_on_saas | You sent a session JWT instead of an API key | /v1/saas/* takes API keys only |
402 api_access_requires_credits | Free account without a credit purchase | Buy credits at app.lecturia.ai |
403 invite_invalid | The invite token can't be honoured | Request a fresh invitation |
Full list: Error codes. Every error carries a request_id —
include it when you contact support.