private-orders.{userId}
Events for every order of the account at once.
Channel parameters
Fill in your values — they appear in the channel name, in the code below and in the console. They are sent nowhere and never end up in the page URL.
is the numeric id of the key owner, returned by GET /user.
Channel name to subscribe to
private-orders.{userId}
The name still contains placeholders in braces. You cannot subscribe with it: the server authorizes channels by exact name.
import Pusher from 'pusher-js';
const pusher = new Pusher('7c4dd881d8116ac76fe89aff71d8c2ff', {
wsHost: 'ws.lumean.app',
wsPort: 443, wssPort: 443,
forceTLS: true,
enabledTransports: ['ws', 'wss'],
cluster: '',
channelAuthorization: {
endpoint: 'https://api.lumean.app/api/public/broadcasting/auth',
headers: { 'X-API-KEY': 'YOUR_API_KEY' },
},
});
const channel = pusher.subscribe('private-orders.{userId}');
channel.bind('policy_cooldown.applied', (data) => {
console.log(data);
});import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
const echo = new Echo({
broadcaster: 'pusher',
key: '7c4dd881d8116ac76fe89aff71d8c2ff',
wsHost: 'ws.lumean.app',
wsPort: 443, wssPort: 443,
forceTLS: true,
enabledTransports: ['ws', 'wss'],
cluster: '',
authEndpoint: 'https://api.lumean.app/api/public/broadcasting/auth',
auth: { headers: { 'X-API-KEY': 'YOUR_API_KEY' } },
});
echo.private('orders.{userId}')
// the leading dot is for Laravel Echo; pusher-js has none
.listen('.policy_cooldown.applied', (e) => {
console.log(e);
});# pip install websocket-client requests
import json, requests, websocket
APP_KEY = "7c4dd881d8116ac76fe89aff71d8c2ff"
WS_URL = "wss://ws.lumean.app:443/app/" + APP_KEY + "?protocol=7&client=python&version=1.0"
CHANNEL = "private-orders.{userId}"
ws = websocket.create_connection(WS_URL)
# 1. grab socket_id from the pusher:connection_established event
hello = json.loads(ws.recv())
socket_id = json.loads(hello["data"])["socket_id"]
# 2. authorize the private subscription with your API key
auth = requests.post("https://api.lumean.app/api/public/broadcasting/auth",
headers={"X-API-KEY": "YOUR_API_KEY"},
data={"socket_id": socket_id, "channel_name": CHANNEL},
).json()["auth"]
# 3. subscribe and listen for events
ws.send(json.dumps({"event": "pusher:subscribe",
"data": {"auth": auth, "channel": CHANNEL}}))
while True:
print(ws.recv())Payload example
Channel: private-orders.{userId}
This is an example from the spec. There is no connection and none is simulated: subscribing for real needs your API key.
.policy_cooldown.applied
{
"reason": "policy_cooldown_active",
"minutes": 1,
"retry_after": 0,
"retry_at": "1970-01-01T00:00:01+00:00",
"level": 1,
"threshold": 1
}Channel events: 14
Every event has its own anchor, a full payload table with descriptions and enums, and a sample shape. Names are shown in Laravel Echo notation — with the leading dot.
.policy_cooldown.applied
Echo: .policy_cooldown.applied · pusher-js: policy_cooldown.applied
Payload fields
Payload example
{
"reason": "policy_cooldown_active",
"minutes": 1,
"retry_after": 0,
"retry_at": "1970-01-01T00:00:01+00:00",
"level": 1,
"threshold": 1
}Values come from the spec where the spec has them; the rest are type-based placeholders. This is the shape of the event, not a recording of a real one.
.paragraph_regenerate.completed
Echo: .paragraph_regenerate.completed · pusher-js: paragraph_regenerate.completed
Payload fields
Payload example
{
"order_id": "01a0d8c6-86d3-70b5-a86e-5a12b1d860df",
"paragraph_index": 1,
"created_count": 1,
"failed_count": 1
}Values come from the spec where the spec has them; the rest are type-based placeholders. This is the shape of the event, not a recording of a real one.
.created
Echo: .created · pusher-js: created
A new order was created.
Payload fields
orderrequiredA snapshot of the order without the chunk list — it would not fit the WebSocket message size limit. The status here is always created; fetch the chunks from GET /orders/{order}.
object
A snapshot of the order without the chunk list — it would not fit the WebSocket message size limit. The status here is always created; fetch the chunks from GET /orders/{order}.
items_summaryrequiredA summary of the order's chunks instead of the full list.
object
A summary of the order's chunks instead of the full list.
How many chunks are in each status: pending, processing, completed, failed, policy_flagged.
Payload example
{
"order": {
"id": 1024,
"uuid": "<uuid>",
"user_id": 7,
"status": "created",
"task_type": "string",
"total_amount": 12.5,
"created_at": "<date-time>",
"template": {}
},
"items_summary": {
"total": 12,
"by_status": {
"pending": 12
}
}
}Values come from the spec where the spec has them; the rest are type-based placeholders. This is the shape of the event, not a recording of a real one.
.progress
Echo: .progress · pusher-js: progress
The order's overall progress was updated.
Progress across the order's original chunks. Retries and regenerations are not counted.
Payload fields
Payload example
{
"order_id": "019bb198-78f5-7082-8550-fee362917f2e",
"completed": 3,
"total": 7,
"percent": 43
}Values come from the spec where the spec has them; the rest are type-based placeholders. This is the shape of the event, not a recording of a real one.
.voice_search.queue.updated
Echo: .voice_search.queue.updated · pusher-js: voice_search.queue.updated
Payload fields
Payload example
{
"order_id": "example",
"queue_position": 1,
"queue_wait_seconds": 1
}Values come from the spec where the spec has them; the rest are type-based placeholders. This is the shape of the event, not a recording of a real one.
.bulk_retry.completed
Echo: .bulk_retry.completed · pusher-js: bulk_retry.completed
Payload fields
Payload example
{
"order_id": "01a0d8c6-86b5-706a-958a-a626ddb3ba3d",
"created_count": 1,
"failed_count": 1
}Values come from the spec where the spec has them; the rest are type-based placeholders. This is the shape of the event, not a recording of a real one.
.renamed
Echo: .renamed · pusher-js: renamed
Payload fields
orderrequiredobject
templaterequiredobject
May arrive as null.
May arrive as null.
currency_assetrequiredobject
May arrive as null.
May arrive as null.
May arrive as null.
May arrive as null.
May arrive as null.
May arrive as null.
May arrive as null.
May arrive as null.
May arrive as null.
May arrive as null.
retentionrequiredobject
chunksrequiredobject
May arrive as null.
filesrequiredobject
May arrive as null.
May arrive as null.
May arrive as null.
May arrive as null.
May arrive as null.
Payload example
{
"order": {
"id": "01a12b4f-ddef-71a8-ae98-c8ec656c2886",
"user_id": 70,
"name": "example",
"template": {
"id": "01a12b4f-dded-706a-91d6-0f86a632230d",
"user_id": 71,
"slug": "a80eab29-6508-36cb-b8e8-3e85029e97b3",
"name": "consequatur",
"service_key": "example",
"service": "string",
"config": [],
"is_public": false,
"folder_id": "string",
"created_at": "2026-10-11T14:13:36+00:00",
"updated_at": "2026-10-11T14:13:36+00:00"
},
"template_id": "01a12b4f-dded-706a-91d6-0f86a632230d",
"task_type": "tts",
"status": "created",
"price_units": 97.05,
"price_formatted": 0.97,
"currency_asset": {
"id": "string",
"code": "LUMC",
"kind": "string",
"precision": 2,
"name": "string",
"deleted_at": "<date-time>",
"created_at": "<date-time>",
"updated_at": "<date-time>"
},
"total_tokens": "string",
"total_duration_ms": "string",
"tokens_from_quota": "string",
"tokens_from_payg": "string",
"tokens_spent": "string",
"task_data": "string",
"result": "string",
"created_at": "2026-10-11T14:13:36+00:00",
"updated_at": "2026-10-11T14:13:36+00:00",
"files_expire_at": "<date-time>",
"files_expired": false,
"retention": {
"chunks": {
"expires_at": "<date-time>",
"expired": false,
"expires_early": false,
"reason": "string"
},
"files": {
"expires_at": "<date-time>",
"expired": false
}
},
"eta_seconds": "string",
"eta_at": "<date-time>",
"completed_chunks": "string",
"total_chunks": "string",
"progress_percent": "string",
"stitching": false,
"paragraphs": "string"
}
}Values come from the spec where the spec has them; the rest are type-based placeholders. This is the shape of the event, not a recording of a real one.
.status.changed
Echo: .status.changed · pusher-js: status.changed
The order changed status.
Payload fields
A snapshot of the order without the chunk list — per-chunk changes arrive as separate item.status.changed events.
items_summaryrequiredA summary of the order's chunks instead of the full list.
object
A summary of the order's chunks instead of the full list.
How many chunks are in each status: pending, processing, completed, failed, policy_flagged.
Payload example
{
"order": {},
"items_summary": {
"total": 12,
"by_status": {
"completed": 10,
"failed": 2
}
},
"previous_status": "created",
"new_status": "created"
}Values come from the spec where the spec has them; the rest are type-based placeholders. This is the shape of the event, not a recording of a real one.
.archive.ready
Echo: .archive.ready · pusher-js: archive.ready
The ZIP archive is assembled and ready to download. Sent only for large orders built in the background.
Payload fields
A ready-to-use ZIP link. Fetch it with a plain GET, no authorization headers, from storage rather than the API.
Archive size in bytes; null when storage did not report it.
When the link stops working (ISO 8601) — no later than a day after it was built. Request the archive again afterwards.
Payload example
{
"order_id": "019bb198-78f5-7082-8550-fee362917f2e",
"archive_id": "019bb1a0-2c41-71f2-9f0b-6a3d0e8c4b17",
"url": "https://s3.example.com/archives/1/019bb1a0.zip?X-Amz-Signature=...",
"size": 104857600,
"expires_at": "2026-07-30T12:00:00+00:00"
}Values come from the spec where the spec has them; the rest are type-based placeholders. This is the shape of the event, not a recording of a real one.
.item.status.changed
Echo: .item.status.changed · pusher-js: item.status.changed
An order chunk changed status.
Payload fields
itemrequiredThe chunk index, its status, the result file path and the audio duration.
object
The chunk index, its status, the result file path and the audio duration.
Whether the order's audio is being stitched. The last finished chunk of a multi-chunk order means stitching has started, not that the order is done: while true the result is not final.
Payload example
{
"item": {
"id": "<uuid>",
"chunk_index": 3,
"status": "pending",
"result_file": {},
"duration_ms": 12480
},
"previous_status": "string",
"new_status": "string",
"completed_chunks": 3,
"total_chunks": 7,
"progress_percent": 43,
"stitching": false
}Values come from the spec where the spec has them; the rest are type-based placeholders. This is the shape of the event, not a recording of a real one.
.policy_cooldown.cleared
Echo: .policy_cooldown.cleared · pusher-js: policy_cooldown.cleared
Payload fields
Payload example
{
"was_blocked": true,
"strikes": 0,
"level": 0
}Values come from the spec where the spec has them; the rest are type-based placeholders. This is the shape of the event, not a recording of a real one.
.archive.failed
Echo: .archive.failed · pusher-js: archive.failed
Background ZIP assembly failed. This event is terminal: neither progress nor ready will arrive for that archive_id again, so dismiss the progress indicator on it — otherwise it stays on screen forever.
Payload fields
A machine-readable reason code — pick the user-facing wording on your side.
Payload example
{
"order_id": "019bb198-78f5-7082-8550-fee362917f2e",
"archive_id": "019bb1a0-2c41-71f2-9f0b-6a3d0e8c4b17",
"reason": "build_failed"
}Values come from the spec where the spec has them; the rest are type-based placeholders. This is the shape of the event, not a recording of a real one.
.stitch.changed
Echo: .stitch.changed · pusher-js: stitch.changed
Payload fields
stitchrequiredobject
May arrive as null.
Payload example
{
"order_id": "01a12b4f-d2ba-70ef-b1a8-14aff97d1da2",
"order_status": "created",
"stitching": false,
"stitch": {
"id": "01a12b4f-d2bc-7117-83c6-a16f11eac8f4",
"status": "pending",
"paragraph_index": "string",
"restitch": false
}
}Values come from the spec where the spec has them; the rest are type-based placeholders. This is the shape of the event, not a recording of a real one.
.archive.progress
Echo: .archive.progress · pusher-js: archive.progress
Progress of a background ZIP assembly. Sent only for large orders (mode=job); a small archive is returned synchronously and produces no events. Values arrive in steps of roughly 20% — do not expect every percent; the last frame has files_done equal to files_total.
Payload fields
The same archive_id returned when the archive was requested — match events to your UI card by it.
Payload example
{
"order_id": "019bb198-78f5-7082-8550-fee362917f2e",
"archive_id": "019bb1a0-2c41-71f2-9f0b-6a3d0e8c4b17",
"percent": 40,
"files_done": 8,
"files_total": 20
}Values come from the spec where the spec has them; the rest are type-based placeholders. This is the shape of the event, not a recording of a real one.
All channels and connection parameters·POST /broadcasting/auth
Feed this page to an AI
spec 0.0.1