Service accounts
Service account authentication is for backend services that call TIE programmatically — webhooks, cron jobs, internal microservices, or any server-side code. Instead of going through the user sign-in flow, your service authenticates with a shared secret called AUTH_SECRET.
Before You Start
Section titled “Before You Start”| What | Where to get it |
|---|---|
| AUTH_SECRET | Issued by the TIE team. Contact them to request one for your service. |
| TIE AI Gateway URL | The base URL for TIE's API (e.g. https://your-tie-host). |
| User UUID (if acting on behalf of users) | The user.id from TIE Auth responses. Store this in your database when users sign up. |
Authentication Modes
Section titled “Authentication Modes”There are two ways to use service auth, depending on whether your service needs a user context.
| Mode | Headers | Memory & Persona | Use case |
|---|---|---|---|
| Service + user | Authorization: Bearer <AUTH_SECRET> + X-On-Behalf-Of: <user-uuid> | Yes | Backend acting as a specific user |
| Service only | Authorization: Bearer <AUTH_SECRET> | No | Stateless one-shot calls |
Service acting as a user
Section titled “Service acting as a user”Your service calls TIE on behalf of a specific user. TIE loads that user's persona and memory, and records the conversation — the same as if the user called directly. The service does not need to go through Firebase auth; it just needs to know the user's TIE UUID.
Pass AUTH_SECRET as the bearer token and the user's UUID in the X-On-Behalf-Of header:
curl -X POST https://your-tie-host/v1/chat/completions \ -H "Authorization: Bearer $AUTH_SECRET" \ -H "X-On-Behalf-Of: 550e8400-e29b-41d4-a716-446655440000" \ -H "X-App-Id: whatsapp-webhook" \ -H "Content-Type: application/json" \ -d '{"model": "claude-haiku-4-5", "messages": [{"role": "user", "content": "What did we discuss yesterday?"}]}'| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer <AUTH_SECRET> |
X-On-Behalf-Of | Yes | The user's UUID (from user.id in auth responses) |
X-App-Id | Recommended | Identifies the calling app and scopes threads |
Where to get the user UUID
Section titled “Where to get the user UUID”When a user signs up through TIE Auth, the response includes user.id — a deterministic UUID derived from their Firebase UID. Store this in your database alongside the user record. When your backend needs to call TIE on that user's behalf, pass it in X-On-Behalf-Of.
sequenceDiagram
accTitle: Service-as-user authentication flow
accDescr: Shows how a backend service calls TIE on behalf of a user using AUTH_SECRET
participant User
participant App as Your App
participant Backend as Your Backend
participant TIE as TIE AI Gateway
User->>App: Sends message (e.g. WhatsApp)
App->>Backend: Forward message + user identifier
Backend->>Backend: Look up user's TIE UUID from database
Backend->>TIE: POST /v1/chat/completions<br/>Authorization: Bearer AUTH_SECRET<br/>X-On-Behalf-Of: user-uuid
TIE->>TIE: Load user's memory & persona
TIE-->>Backend: AI response
Backend-->>App: Forward response to user
Service only (stateless)
Section titled “Service only (stateless)”Your service makes a call with no user context. No memory, no persona, no turn recording. This is useful for utility tasks like title generation, text summarization, or content classification where there is no meaningful user to attach to.
curl -X POST https://your-tie-host/v1/chat/completions \ -H "Authorization: Bearer $AUTH_SECRET" \ -H "X-App-Id: title-generator" \ -H "Content-Type: application/json" \ -d '{"model": "gemini-2.5-flash", "messages": [{"role": "user", "content": "Generate a title for: ..."}]}'Restrictions in service-only mode:
persona_idis not allowed (returns400)- Memory tools (
memory_search,memory_write) are disabled - No conversation turns are recorded
- Threads still work for multi-turn within the same request chain, but have no user association
Security
Section titled “Security”- Store
AUTH_SECRETin environment variables or a secret manager (e.g. GCP Secret Manager), not in code. - Rotate the secret by coordinating with the TIE team. During rotation, both old and new values can be active briefly.
- If you suspect the secret has been compromised, contact the TIE team immediately to revoke and reissue it.
Error Codes
Section titled “Error Codes”| Code | Status | When |
|---|---|---|
AUTH_TOKEN_MISSING | 401 | No Authorization header provided |
AUTH_TOKEN_INVALID | 401 | AUTH_SECRET value does not match |
AUTH_INVALID_USER_ID | 400 | X-On-Behalf-Of header is not a valid UUID |
VALIDATION_ERROR | 400 | persona_id used in service-only mode (no subject user) |