Full developer E2E path
This is the full “first real integration” path. Use it when your app needs more than a smoke-test character:
- upload authored voice, persona, style anchors, and identity image;
- optionally migrate prior chat from another companion app;
- publish playable-character and NPC relationship graphs;
- start or reuse the committed session;
- send a message and render the reply from session events;
- read public-safe relationship evidence and opt-in scores.
For the shortest possible chat loop, start with
Quickstart. For this full path, keep every call server-side and
use only /v1/*.
What This Proves
When this path works, your app has proven that a user can bring a planned character plus existing relationship history into LoreOS and get back:
API Sequence
1. Create The Import
Use mode: "hybrid" when you have both an authored character bundle and prior
chat history.
identity_image.source_url must be a direct, publicly fetchable https image
URL. If the image fetch fails, the character can still publish, but
data.identity_image will contain a safe error and no portrait is registered.
2. Poll The Import
Background extraction runs through Temporal by default. The create response
contains data.temporal_workflow_id and data.temporal_task_queue.
Poll:
Wait for data.status to become ready. While it runs, check:
last_heartbeat_at should keep advancing during long extractor stages. After
ready, inspect:
Look for staged ledger counts such as world_model_claims,
character_counterpart_beliefs, and relational_state_rows.
3. Commit The Import
Important fields:
For authoring_only, data.commit.session_id is null; create a session
yourself with POST /v1/sessions. For hybrid, use the committed session_id
because it carries the imported relationship state.
4. Publish Relationship Graphs
Playable characters use the app-roster graph:
NPCs and supporting cast use the character graph:
Always validate, import, then publish. Published character graphs materialize NPC rows, which you can inspect with:
5. Send And Render A Reply
POST /messages returns a cursor, not the reply.
Render when you see:
Do not wait for a separate delivered status before showing text that is
already committed to the event log. Delivery status is for webhook or managed
channel push attempts.
6. Read Relationship Evidence
Start with:
Then use narrower endpoints as needed:
These are public-safe projections. They do not expose raw prompts, raw world-model rows, private Story Room plans, raw extractor traces, or provider payloads.
7. Opt In To Scores
Numeric relationship scores are redacted by default.
Default response:
Opt in per app:
After opt-in, dating schemas include final 0..1 values such as
affection_toward_user, romantic_interest, trust_level, comfort_level,
and boundary_level.
The score endpoint never exposes raw extractor deltas, patch history, signal
events, critic reasoning, or prompt text. It may list those names under
omitted_fields to make the privacy boundary explicit.
Implementation Notes For Agents
- Use
response.data, not top-level response fields. - Persist
data.cursorfromPOST /messagesand poll withsince=cursor. - Treat unknown event types as additive.
- Use
Idempotency-KeyonPOST /messages. - Use the committed
session_idfrom a hybrid import; it is the session that contains imported relationship state. - Use direct, fetchable image URLs for import identity images.
- Do not generate against
https://api.loreos.app/openapi.json; usehttps://api.loreos.app/v1/openapi.json.