Authentication
Tanqory uses JWT (RS256) issued by admin-api. All other services validate the same token.
Login Flow
POST https://api.tanqory.com/api/v1/auth/login
Content-Type: application/json
{
"email": "[email protected]",
"password": "SecurePass123!"
}
Response (200):
{
"accessToken": "eyJhbGci...",
"refreshToken": "eyJhbGci...",
"expiresIn": 3600
}
SDK:
// Tokens are stored automatically — all subsequent requests are authenticated
MFA Challenge
If MFA is enabled, login returns requiresMfa: true instead of tokens.
if ('requiresMfa' in result) {
// Prompt user for TOTP code
const session = await tanqory.auth.verifyTotpLogin(result.mfaToken, '123456')
// session.accessToken and session.refreshToken now available
}
OAuth / Social Login
Redirect users to the provider's authorize endpoint, then exchange the code:
GET https://api.tanqory.com/api/v1/auth/social-accounts/connect/google
GET https://api.tanqory.com/api/v1/auth/social-accounts/connect/apple
For mobile apps, exchange a native ID token directly:
const result = await tanqory.auth.nativeLogin('google', googleIdToken)
Token Refresh
Access tokens expire after 1 hour. Use the refresh token to get a new pair:
POST https://api.tanqory.com/api/v1/auth/refresh
{ "refreshToken": "eyJhbGci..." }
SDK: Token refresh is handled automatically. The SDK intercepts 401 responses, refreshes the token, and retries the request.
Cross-origin Token Exchange (SSO)
When the access token is issued at one origin (e.g. admin.tanqory.com) but consumed at another (e.g. store.tanqory.com), the refresh-token cookie is scoped to the issuer. Call auth.exchangeToken(accessToken) on the consumer origin to mint a local httpOnly refresh-token cookie so silent refresh works there too:
// In an OAuth/SSO callback page on the consumer origin:
const token = new URLSearchParams(location.hash.slice(1)).get('token')
await tanqory.auth.exchangeToken(token) // POST /api/v1/auth/exchange
// httpOnly refresh_token cookie is now set at this origin
API: POST /api/v1/auth/exchange — auth via Authorization: Bearer <accessToken> (does not require an existing session).
Session Management
List and revoke active sessions:
const sessions = await tanqory.auth.getSessions()
// [{ id: "sess_1", device: "Chrome / macOS", lastActive: "2026-04-09T..." }]
await tanqory.auth.revokeSession('sess_1') // Revoke one
await tanqory.auth.revokeAllOtherSessions() // Revoke all except current
Using Tokens in Requests
All authenticated API calls require the Authorization header:
Authorization: Bearer {accessToken}
The SDK handles this automatically after login. For raw HTTP clients:
curl -H "Authorization: Bearer eyJhbGci..." \
https://api.tanqory.com/api/v1/auth/me
Token Architecture
admin-api (issuer, RS256) ──JWT──▶ store-api, ai-api, builder-api (validators)
The same JWT is valid across all Tanqory services. You do not need separate tokens per service.