Skip to content

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.

WhatWhere to get it
AUTH_SECRETIssued by the TIE team. Contact them to request one for your service.
TIE AI Gateway URLThe 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.

There are two ways to use service auth, depending on whether your service needs a user context.

ModeHeadersMemory & PersonaUse case
Service + userAuthorization: Bearer <AUTH_SECRET> + X-On-Behalf-Of: <user-uuid>YesBackend acting as a specific user
Service onlyAuthorization: Bearer <AUTH_SECRET>NoStateless one-shot calls

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:

Terminal window
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?"}]}'
HeaderRequiredDescription
AuthorizationYesBearer <AUTH_SECRET>
X-On-Behalf-OfYesThe user's UUID (from user.id in auth responses)
X-App-IdRecommendedIdentifies the calling app and scopes threads

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

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.

Terminal window
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_id is not allowed (returns 400)
  • 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
  • Store AUTH_SECRET in 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.
CodeStatusWhen
AUTH_TOKEN_MISSING401No Authorization header provided
AUTH_TOKEN_INVALID401AUTH_SECRET value does not match
AUTH_INVALID_USER_ID400X-On-Behalf-Of header is not a valid UUID
VALIDATION_ERROR400persona_id used in service-only mode (no subject user)