API structure
The API is organized around two product-facing resources, both under /v1:
| Resource | Prefix | What it's for |
|---|---|---|
| Identities | /v1/identities | Create and manage avatars |
| Sessions | /v1/sessions | Open a live conversation for an identity |
Base URL
https://api.lookalike.com
Authentication
Send your API key on every request, either as a bearer token or in the X-API-Key header — both are accepted:
# Bearer token (recommended)
curl https://api.lookalike.com/v1/identities \
-H "Authorization: Bearer $LOOKALIKE_API_KEY"
# or the X-API-Key header
curl https://api.lookalike.com/v1/identities \
-H "X-API-Key: $LOOKALIKE_API_KEY"
Keys start with lk_. Each key is scoped to one account; every identity and session you create belongs to that account, and you can only read back your own. Keep keys server-side — a leaked key can spend your credits. A missing or invalid key returns 401.
Errors
Errors come back as JSON with a detail field and the matching HTTP status:
{ "detail": "Identity not found" }
Validation errors (422) put a list of field-level problems in detail instead.
| Status | Meaning |
|---|---|
400 / 422 | The request was malformed or failed validation. |
401 | Missing or invalid API key. |
402 | Insufficient credits. |
404 | The resource doesn't exist (or isn't yours). |
409 | The resource isn't in a state that allows this — e.g. the identity isn't trained yet, or the session has ended. |
415 | An uploaded file is an unsupported media type. |
5xx | Something went wrong on our side — retry shortly. |
Identity API
Create and manage avatars.
| Method | Path | Purpose |
|---|---|---|
GET | /v1/identities | List your identities. |
POST | /v1/identities | Create an identity (multipart upload). |
GET | /v1/identities/{identity_id} | Fetch one identity. |
PATCH | /v1/identities/{identity_id} | Rename an identity and/or retrain it (multipart upload). |
GET | /v1/identities/{identity_id}/status | Check onboarding status. |
Creating an identity uploads reference media, so POST /v1/identities takes multipart/form-data (not JSON). name, prompt and an image to train on are required; audio is optional. There is one image and one audio clip per identity — no other media fields.
PATCH takes the same multipart form with every field optional. Sending name alone renames and returns 200; sending reference uploads retrains, which requires prompt alongside them and returns 202 — poll the status endpoint from there.
curl -X PATCH https://api.lookalike.com/v1/identities/id_3f9a2b7c4d1e8a05f6b3 \
-H "Authorization: Bearer $LOOKALIKE_API_KEY" \
-F "name=Ada"
curl -X POST https://api.lookalike.com/v1/identities \
-H "Authorization: Bearer $LOOKALIKE_API_KEY" \
-F "name=Ada" \
-F "prompt=You are Ada, a warm and curious guide." \
-F "image=@ada-face.jpg" \
-F "audio=@ada-voice.wav"
Because the request includes a visual reference, the identity trains inline and the create call returns it already ready:
{
"identity_id": "id_8f2c10ab",
"name": "Ada",
"status": "ready",
"created_at": "2026-06-25T10:30:00+00:00"
}
You can re-check state any time with GET /v1/identities/{id}/status:
curl https://api.lookalike.com/v1/identities/id_8f2c10ab/status \
-H "Authorization: Bearer $LOOKALIKE_API_KEY"
# → { "identity_id": "id_8f2c10ab", "status": "ready", "detail": null, ... }
An identity moves through created → training → ready; with a visual reference this happens inline, so create returns a ready identity. Only a ready identity can open a session. List your identities with GET /v1/identities:
[
{ "identity_id": "id_8f2c10ab", "name": "Ada", "status": "ready", "updated_at": "2026-06-25T10:35:00+00:00" }
]
Session API
A session is a live conversation for one ready identity.
| Method | Path | Purpose |
|---|---|---|
POST | /v1/sessions/start | Start a realtime session and join over LiveKit. See the Realtime API. |
POST | /v1/sessions/{session_id}/end | End a session explicitly, without waiting for the client to disconnect. |
POST /v1/sessions/start needs only an identity_id and returns everything your app needs to join the LiveKit room — a room name, an access token, and the server URL. To end the session, either disconnect from the LiveKit room or call POST /v1/sessions/{session_id}/end. See the Realtime API for the full request and response.