Developer

API

Trulience API reference for token generation and avatar management

Overview

All endpoints use JSON. Authentication is via the x-api-key header.

Generate JWT Token

Generate a JWT token for avatar authentication.

Endpoint: POST https://trulience.com/auth/generate-token

Request Headers

x-api-key: tru_live_***
Content-Type: application/json

Request Body

{
  "avatar_id": "4386676996480451678",
  "expire_at": 300
}
FieldTypeRequiredDescription
avatar_idstringYesAvatar ID to generate token for
expire_atintegerNoToken expiry in seconds. Default: 120. Range: 60-3600

Success Response (200 OK)

{
  "jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expires_in": 300,
  "avatar_id": "4386676996480451678"
}
FieldTypeDescription
jwtstringJWT token for avatar authentication
expires_inintegerToken expiry in seconds
avatar_idstringAvatar ID the token is valid for

Error Responses

400 Bad Request - Invalid expire_at range

{
  "error": {
    "code": 19,
    "message": "expire_at must be between 60 and 3600 seconds"
  }
}

401 Unauthorized - Invalid API Key

{
  "error": {
    "code": 16,
    "message": "Invalid API Key"
  }
}

403 Forbidden - Missing Scope

{
  "error": {
    "code": 34,
    "message": "API key lacks required scope"
  }
}

403 Forbidden - Avatar Not Allowed

{
  "error": {
    "code": 33,
    "message": "API key is not authorized for this avatar"
  }
}

403 Forbidden - Origin Not Allowed

{
  "error": {
    "code": 35,
    "message": "Origin is not allowed for this API key"
  }
}

429 Rate Limited

{
  "error": {
    "code": 36,
    "message": "Too many requests. Please slow down."
  }
}

500 Internal Server Error

{
  "error": {
    "code": 45,
    "message": "Internal server error occurred"
  }
}

Notes

  • Tokens are single-use and cannot be refreshed
  • Generate a new token for each user session
  • Requires API key scope: generate_tokens

List Avatars

Retrieve a paginated list of avatars for your account.

Endpoint: GET /avatars

Request Headers

x-api-key: tru_live_***

Query Parameters

GET /avatars?page=0&size=20
ParameterTypeRequiredDescription
pageintegerNoPage number (0-indexed). Default: 0
sizeintegerNoResults per page. Default: 20. Max: 100

Success Response (200 OK)

{
  "avatars": [
    {
      "id": "4386676996481151678",
      "name": "Amanda"
    },
    {
      "id": "993237220279768598",
      "name": "Amanda - Trulience"
    }
  ],
  "pagination": {
    "page": 0,
    "size": 20,
    "total": 82,
    "total_pages": 5,
    "has_next": true
  }
}
FieldTypeDescription
avatarsarrayArray of avatar objects
avatars[].idstringAvatar unique identifier
avatars[].namestringAvatar display name
pagination.pageintegerCurrent page number (0-indexed)
pagination.sizeintegerResults per page
pagination.totalintegerTotal number of avatars
pagination.total_pagesintegerTotal number of pages
pagination.has_nextbooleanWhether more pages are available

Error Responses

401 Unauthorized - Invalid API Key

{
  "error": {
    "code": 16,
    "message": "Invalid API Key"
  }
}

403 Forbidden - Missing Scope

{
  "error": {
    "code": 34,
    "message": "API key lacks required scope"
  }
}

429 Rate Limited

{
  "error": {
    "code": 36,
    "message": "Too many requests. Please slow down."
  }
}

500 Internal Server Error

{
  "error": {
    "code": 45,
    "message": "Internal server error occurred"
  }
}

Notes

  • Avatars are sorted alphabetically by name
  • Requires API key scope: read_avatars

Query Session State

Look up the current state of a live avatar session — avatar status, avatar ID, user ID, and last-activity time — by sessionId. Use this from your backend to poll session status without needing your own client-side event plumbing.

Endpoint: GET https://trulience.com/session/query

Creating a key with query permission

  1. Sign in to the Trulience Dashboard with an account that has access to your organization’s avatars
  2. Open Developer → API Keys
  3. Select Create New Key and give it a descriptive name (e.g. “Backend — session status polling”)
  4. Turn on the Read Session State permission. Keys without it are rejected by this endpoint
  5. Save, then copy the key immediately — it is shown only once and cannot be retrieved afterwards
  6. Store the key on your server only. Treat it like a password; never put it in client-side code

If the key is restricted to specific avatars (a per-avatar allowlist), it can only query sessions for those avatars — see error 33 below.

Request Headers

x-api-key: tru_live_***

Query Parameters

GET /session/query?sessionId=sess_9f2a7c1e&fields=avatarStatus,avatarId,userId,lastActivityAt
ParameterTypeRequiredDescription
sessionIdstringYesThe session to query. Max 128 characters.
fieldsstring (comma-separated)YesWhich fields to return: one or more of avatarStatus, avatarId, userId, lastActivityAt. No default — there is no “return everything” shortcut, so name every field you need.

Success Response (200 OK)

{
  "status": "OK",
  "failReason": 0,
  "sessionId": "sess_9f2a7c1e",
  "state": {
    "avatarStatus": "TALKING",
    "avatarId": 456,
    "userId": 789,
    "lastActivityAt": 1769784000123
  }
}

state contains only the fields you listed in fields — request a subset to get a smaller response. A field with no recorded value is still present, as null, rather than omitted.

FieldTypeDescription
state.avatarStatusstring | nullOne of IDLE, LOADED, UNLOADED, LISTENING, THINKING, TALKING
state.avatarIdnumberAvatar ID for this session
state.userIdnumberUser ID for this session
state.lastActivityAtnumber | nullEpoch milliseconds of the most recent activity (ping or message). null if none has been recorded yet

Failure Response

Failures use the same shape plus a message:

{
  "status": "FAIL",
  "failReason": 34,
  "message": "API key lacks required scope"
}

Querying a session that has already ended is not a failure on your part — it simply returns error 65 below.

Error Reference

HTTPCodeMessageWhat it means & what to do
2000OKSuccess — no action needed
40130API key is requiredMissing x-api-key header
40129Invalid API key formatMalformed key — check for copy/paste truncation
40131API key not found in databaseKey doesn’t exist — confirm account/deletion
40116Invalid API KeyKey doesn’t validate — issue a new one if persistent
40332This API key has been disabledRe-enable it or use a different key
42936Too many requests. Please slow down.Back off and retry; avoid tight loops
40334API key lacks required scopeEnable “Read Session State” on the key
4007InvalidOrMissingParamssessionId is missing/over 128 characters, or fields is missing/blank/contains an unrecognized name
40465Session not foundAlready ended, or never existed — usually nothing to do
40324Avatar does not belong to your accountSession belongs to a different account
40333API key is not authorized for this avatarKey’s avatar allowlist doesn’t include this one
50045Internal server error occurredRetry; contact support if persistent

Rate Limiting

This endpoint enforces rate limits at two layers, each with different numbers:

  • Per API key — 100 requests burst, refilling at 50 requests/second by default. Shared with your key’s usage of the other endpoints on this page. Exceeding it returns the 429 JSON shown above (failReason: 36).
  • Per source IP address, at the network edge~60 requests/second sustained, with a burst of 120. It’s set above the per-key ceiling so it won’t bind for legitimate traffic — the per-key limit above is the actual source of truth for your quota. Because this is rejected before the request reaches the application, the response is a bare HTTP 429 without the usual {"status":"FAIL",...} JSON body — check the status code, not the response body, when handling throttling on this endpoint. This applies per source IP regardless of which key (or no key) is used, so if you send /session/query traffic for many different API keys through one shared outbound IP (e.g. a corporate proxy or NAT), that IP is throttled as a whole.

No Retry-After header is returned by either layer — back off and retry (e.g. with exponential backoff) rather than retrying in a tight loop.

Need a higher per-key limit? Contact support.

Notes

  • Requires API key permission: Read Session State
  • fields is required — any single unrecognized field name fails the whole request with a 400 rather than silently returning a truncated response
  • This is a point-in-time lookup, not a subscription — poll it if you need updates over time

Disconnect a Session

End an in-flight avatar session on demand by session_id. Use this to terminate sessions from your backend — for example, call moderation — in addition to the natural exit paths (client hangup, transport failure, max_session_duration).

Endpoint: POST https://trulience.com/sessions/disconnect

Creating a key with disconnect permission

  1. Sign in to the Trulience Dashboard with an account that has access to your organization’s avatars
  2. Open Developer → API Keys
  3. Select Create New Key and give it a descriptive name (e.g. “Backend — call moderation”)
  4. Turn on the Disconnect Sessions permission. Keys without it are rejected by this endpoint
  5. Save, then copy the key immediately — it is shown only once and cannot be retrieved afterwards
  6. Store the key on your server only. Treat it like a password; never put it in client-side code

If the key is restricted to specific avatars (a per-avatar allowlist), it can only disconnect sessions for those avatars — see error 33 below.

Request Headers

x-api-key: your-api-key
Content-Type: application/json

Request Body

{
  "session_id": "sess_9f2a7c1e"
}
FieldTypeRequiredDescription
session_idstringYesThe session to disconnect

Success Response (200 OK)

{
  "status": "OK",
  "failReason": 0
}

Failure Response

Failures use the same shape plus a message:

{
  "status": "FAIL",
  "failReason": 34,
  "message": "API key lacks required scope"
}

The call is safe to retry — disconnecting an already-ended session simply returns error 65, which is not a failure on your part.

Error Reference

HTTPCodeMessageWhat it means & what to do
2000OKSuccess — no action needed
40130API key is requiredMissing x-api-key header
40129Invalid API key formatMalformed key — check for copy/paste truncation
40131API key not found in databaseKey doesn’t exist — confirm account/deletion
40116Invalid API KeyKey doesn’t validate — issue a new one if persistent
40332This API key has been disabledRe-enable it or use a different key
42936Too many requests. Please slow down.Back off and retry; avoid tight loops
40334API key lacks required scopeEnable “Disconnect Sessions” on the key
4007InvalidOrMissingParamsMissing session_id in the body
40465Session not foundAlready ended — usually nothing to do
40324Avatar does not belong to your accountSession belongs to a different account
40333API key is not authorized for this avatarKey’s avatar allowlist doesn’t include this one
50045Internal server error occurredRetry; contact support if persistent

Notes

  • Requires API key permission: Disconnect Sessions
  • Safe to call more than once — an already-ended session returns error 65