private-chunks.preview.{userId}
The result of a background chunk-preview split calculation. Arrives for large texts submitted to POST /orders/chunks/preview.
Spec fixes · 1
Chunk preview is available with an API key
The machine-readable
llm.md§12 claims chunk preview is a web-cabinet endpoint that returns401for API keys. That is wrong: all three preview operations are part of the public surface and require theorders.readscope — as described by both the OpenAPI document and §7.1 of the very samellm.md. If an AI assistant cites §12, it is mistaken.
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-chunks.preview.{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-chunks.preview.{userId}');
channel.bind('ready', (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('chunks.preview.{userId}')
// the leading dot is for Laravel Echo; pusher-js has none
.listen('.ready', (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-chunks.preview.{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-chunks.preview.{userId}
This is an example from the spec. There is no connection and none is simulated: subscribing for real needs your API key.
.ready
{
"status": "ready",
"preview_id": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
"summary": {
"chunks_count": 342,
"total_effective_length": 680000,
"total_price_units": 680000,
"pause_count": 12,
"total_pause_seconds": 30,
"caps_ok": true,
"caps_exceeded": null,
"paragraphs_count": null,
"paragraphs": [
{
"paragraph_index": 0,
"chunks_count": 3,
"first_chunk_index": 0,
"text_length": 2400,
"effective_length": 2380,
"price_units": 2380
}
]
},
"page": {
"current_page": 1,
"per_page": 100,
"total": 342,
"has_more": true
}
}Channel events: 1
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.
.ready
Echo: .ready · pusher-js: ready
The async preview is ready — a limited notification: totals for the whole text (summary) and the first page's meta (page). The chunks themselves are not part of this event — fetch them separately via GET /orders/chunks/preview/{previewId}?page=1.
Payload fields
A content-based preview id (sha256 of text+template+mode). Use it for pagination (GET .../{previewId}) and repeat preflight lookups.
summaryrequiredTotals for the whole text — not just the current page of chunks.
object
Totals for the whole text — not just the current page of chunks.
Total billable length across all chunks, in characters (pauses are excluded).
Number of paragraphs, or null outside paragraph mode.
paragraphsoptionalA per-paragraph aggregate. null means either "the preview is not paragraph-mode" or "there are more paragraphs than the broadcast payload cap" — in the second case paragraphs_count stays a number, and you fetch the full list via GET /orders/chunks/preview/{previewId}.
array<object> | null
A per-paragraph aggregate. null means either "the preview is not paragraph-mode" or "there are more paragraphs than the broadcast payload cap" — in the second case paragraphs_count stays a number, and you fetch the full list via GET /orders/chunks/preview/{previewId}.
The cross-text index of the paragraph's first chunk — use it to locate the paragraph within the paginated chunk list.
pagerequiredMeta for the first page of chunks. Fetch the chunks themselves with a separate paginated GET request keyed by preview_id.
object
Meta for the first page of chunks. Fetch the chunks themselves with a separate paginated GET request keyed by preview_id.
Total chunks in the split (across all pages).
Payload example
{
"status": "ready",
"preview_id": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
"summary": {
"chunks_count": 342,
"total_effective_length": 680000,
"total_price_units": 680000,
"pause_count": 12,
"total_pause_seconds": 30,
"caps_ok": true,
"caps_exceeded": null,
"paragraphs_count": null,
"paragraphs": [
{
"paragraph_index": 0,
"chunks_count": 3,
"first_chunk_index": 0,
"text_length": 2400,
"effective_length": 2380,
"price_units": 2380
}
]
},
"page": {
"current_page": 1,
"per_page": 100,
"total": 342,
"has_more": true
}
}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