Authentication
epilot APIs use bearer tokens for authentication. All requests must include a valid token in the Authorization header:
Authorization: Bearer <your-token>
Getting Startedโ
The recommended way to authenticate with epilot APIs is using Access Tokens โ long-lived, scoped tokens designed for integrations.
- Go to Settings > Access Tokens in the epilot portal
- Create a new token, optionally scoping it to specific roles
- Pass the token as a bearer token in your API requests
import { epilot } from '@epilot/sdk'
epilot.authorize('<your-access-token>')
const { data } = await epilot.entity.createEntity(
{ slug: 'contact' },
{ first_name: 'Example', last_name: 'Contact' },
)
See Access Tokens for full details on creating, scoping and revoking tokens.
SDK Auth Patternsโ
The SDK's authorize() accepts a string or a function. The function form is preferred โ it is called on every request, so tokens stay fresh.
Global authorizationโ
Applies to all clients resolved from the SDK:
import { epilot } from '@epilot/sdk'
epilot.authorize(() => '<my-token>') // function (recommended)
epilot.authorize(async () => await getTokenFromSession()) // async function
epilot.authorize('my-static-api-token') // static string
Per-client authorizationโ
import { authorize } from '@epilot/sdk'
import { getClient } from '@epilot/sdk/entity'
const entityClient = getClient()
authorize(entityClient, () => '<my-token>')
Frontend (epilot360)โ
import { epilot } from '@epilot/sdk'
import { getTokenSync } from '@epilot360/auth-service'
epilot.authorize(() => getTokenSync())
Backend internal callsโ
Pass the caller's headers to downstream APIs for permission checks:
import { getClient } from '@epilot/sdk/entity'
import { getLambdaRunner } from 'openapi-lambda-adapter'
const getEntityClient = (passedHeaders: Headers) => {
const client = getClient()
client.api.registerRunner(getLambdaRunner(process.env.ENTITY_LAMBDA_NAME))
client.defaults.headers.common = {
authorization: passedHeaders['authorization'],
['x-ivy-org-id']: passedHeaders['x-ivy-org-id'],
['x-epilot-org-id']: passedHeaders['x-epilot-org-id'],
['x-epilot-user-id']: passedHeaders['x-epilot-user-id'],
}
return client
}
For admin-privileged internal calls, use @epilot/internal-auth tokens and set x-epilot-org-id (or x-ivy-org-id).
See the SDK documentation for the full SDK reference.
How It Worksโ
epilot authentication is built on OAuth 2.0 with Amazon Cognito User Pools as the identity provider. Each epilot tenant has its own Cognito User Pool.
When a user logs in to the epilot portal, Cognito issues short-lived OAuth tokens (60 min). For API integrations, the Access Token service issues long-lived JWTs with claims compatible with Cognito tokens, so all epilot APIs accept them seamlessly.
All tokens are verified by the API Gateway authorizer using JWKS endpoints before reaching backend services.
Token Typesโ
| Token | Lifetime | Use case |
|---|---|---|
| Access Token | Long-lived | Server-side API integrations, scripts, third-party apps |
| OAuth 2.0 Token | 60 minutes | Interactive user sessions in the epilot portal |
| Publishable Token | Long-lived | Client-side public apps (journeys, portals) |
For most integrations, Access Tokens are the right choice. See Token Types for a full comparison.
See Alsoโ
- Access Tokens โ creating and managing scoped tokens
- Token Types โ comparison of all epilot token types
- Authorization โ how API requests are authorized
- Permissions โ role-based access control and grants
- Multi-Factor Authentication -- TOTP and SMS second factor
- Passwordless Login -- email-based sign-in links
- Passkeys -- phishing-resistant biometric and hardware key authentication
- SSO โ single sign-on with OIDC and SAML