Loading...
Loading...
Session tokens authenticate Profile-specific requests to the Connector and GraphQL API. Issue them server-side, use them client-side.
POSThttps://auth.quiltt.io/v1/users/sessionsCopy endpoint URL to clipboardRequired headers:
Authorization: Bearer <API_SECRET_KEY>
Content-Type: application/json
Rate Limits: 10/hour, 20/day per Profile
Each issuance creates a NEW token counting toward limits. To avoid 429 errors:
Server-to-server? Use Basic Auth instead—no rate limits.
Provide the Profile ID in the request body:
curl --request POST \
--url 'https://auth.quiltt.io/v1/users/sessions' \
--header 'Authorization: Bearer <API_SECRET_KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
"userId": "p_11ewrVkEnd7LIvSVAmt8XL5"
}'
{
"token": "eyJhbGciOiJIUzUxMiJ9.eyJuYmYiOjE2NzE4MjI5MTIsImlhdCI6MTY3MTgyMjkxMiwianRpIjoiNDU1MWNhNDktYzAwMi00ZDliLTkyZWMtNDY1MDE4ZTI4ZmRjIiwiaXNzIjoiYXV0aC5xdWlsdHQuaW8iLCJhdWQiOiJhcGkucXVpbHR0LmlvIiwiZXhwIjoxNjcxOTA5MzEyLCJ2ZXIiOjIsImRpZCI6ImFwaV8xN05PRXdWR2N2eU9xcGxuUWREMjdnWSIsInVpZCI6InBfMTFld3JWa0VuZDdMSXZTVkFtdDhYTDUifQ.5tYTjr_k0GKG6LsaAEt3V0RAiJe9UU59USUAASJTXf5e1923njb4UqYUozAVm34fARXT-SRvlE1-_J4wdiVNwg",
"userId": "p_11ewrVkEnd7LIvSVAmt8XL5",
"environmentId": "env_1Bx4omNvZgKao2OqGshImD",
"expiration": 1718944186,
"expiresAt": "2024-06-21T04:29:46Z"
}
Create a Profile and issue a token in one request. Optionally provide Profile attributes or your own UUID:
curl --request POST \
--url 'https://auth.quiltt.io/v1/users/sessions' \
--header 'Authorization: Bearer <API_SECRET_KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
"metadata": {
"firebaseId": "Xk3D12aB4zO7QW5z8s9Y"
}
}'
{
"token": "eyJhbGciOiJIUzUxMiJ9.eyJuYmYiOjE2NzE4MjI5MTIsImlhdCI6MTY3MTgyMjkxMiwianRpIjoiNDU1MWNhNDktYzAwMi00ZDliLTkyZWMtNDY1MDE4ZTI4ZmRjIiwiaXNzIjoiYXV0aC5xdWlsdHQuaW8iLCJhdWQiOiJhcGkucXVpbHR0LmlvIiwiZXhwIjoxNjcxOTA5MzEyLCJ2ZXIiOjIsImRpZCI6ImFwaV8xN05PRXdWR2N2eU9xcGxuUWREMjdnWSIsInVpZCI6InBfMTFld3JWa0VuZDdMSXZTVkFtdDhYTDUifQ.5tYTjr_k0GKG6LsaAEt3V0RAiJe9UU59USUAASJTXf5e1923njb4UqYUozAVm34fARXT-SRvlE1-_J4wdiVNwg",
"userId": "p_11ewrVkEnd7LIvSVAmt8XL5",
"environmentId": "env_1Bx4omNvZgKao2OqGshImD",
"expiration": 1718944186,
"expiresAt": "2024-06-21T04:29:46Z"
}
Store the returned userId to re-authenticate this Profile later (unless providing your own UUIDs).
Session tokens last 24 hours. Cache client-side to avoid rate limits:
function useQuilttSessionToken(profileId: string) {
const [token, setToken] = useState<string | null>(null)
const [loading, setLoading] = useState(true)
useEffect(() => {
async function loadSession() {
// Check cache first
const cached = localStorage.getItem(`quiltt_session_${profileId}`)
if (cached) {
const { token, expiresAt } = JSON.parse(cached)
if (new Date(expiresAt) > new Date()) {
setToken(token)
setLoading(false)
return
}
}
// Fetch new token
const response = await fetch('/api/quiltt-session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ userId: profileId })
})
const session = await response.json()
localStorage.setItem(`quiltt_session_${profileId}`, JSON.stringify({
token: session.token,
expiresAt: session.expiresAt
}))
setToken(session.token)
setLoading(false)
}
loadSession()
}, [profileId])
return { token, loading }
}
async function getOrCreateSession(profileId: string): Promise<string> {
// Check for cached token
const cached = localStorage.getItem(`quiltt_session_${profileId}`)
if (cached) {
const { token, expiresAt } = JSON.parse(cached)
// Verify token hasn't expired
if (new Date(expiresAt) > new Date()) {
return token
}
}
// Issue new token if no valid cached token
const response = await fetch('https://auth.quiltt.io/v1/users/sessions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_SECRET_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ userId: profileId })
})
const session = await response.json()
// Cache the token
localStorage.setItem(`quiltt_session_${profileId}`, JSON.stringify({
token: session.token,
expiresAt: session.expiresAt
}))
return session.token
}
Revoke tokens at logout to free rate limit quota:
import { useCallback } from 'react'
import { useQuilttSession } from '@quiltt/react'
function LogoutButton() {
const { revokeSession } = useQuilttSession()
const handleLogout = useCallback(async () => {
// Revokes token on server and clears from local storage
await revokeSession()
// Redirect to login
window.location.href = '/login'
}, [revokeSession])
return <button onClick={handleLogout}>Log Out</button>
}
import { useCallback } from 'react'
import { useQuilttSession } from '@quiltt/react-native'
function LogoutButton() {
const { revokeSession } = useQuilttSession()
const handleLogout = useCallback(async () => {
// Revokes token on server and clears from storage
await revokeSession()
// Navigate to login
navigation.navigate('Login')
}, [revokeSession])
return <Button title="Log Out" onPress={handleLogout} />
}
import { AuthAPI } from '@quiltt/core'
async function logout(token: string, profileId: string) {
const auth = new AuthAPI()
// Revoke the token
await auth.revoke(token)
// Clear from cache
localStorage.removeItem(`quiltt_session_${profileId}`)
}
Provide optional attributes when issuing tokens for existing or new Profiles:
curl --request POST \
--url 'https://auth.quiltt.io/v1/users/sessions' \
--header 'Authorization: Bearer <API_SECRET_KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
"email": "quiltty@quiltt.io",
"metadata": {
"favoriteColor": "Purple"
}
}'
{
"token": "eyJhbGciOiJIUzUxMiJ9.eyJuYmYiOjE2NzE4MjI5MTIsImlhdCI6MTY3MTgyMjkxMiwianRpIjoiNDU1MWNhNDktYzAwMi00ZDliLTkyZWMtNDY1MDE4ZTI4ZmRjIiwiaXNzIjoiYXV0aC5xdWlsdHQuaW8iLCJhdWQiOiJhcGkucXVpbHR0LmlvIiwiZXhwIjoxNjcxOTA5MzEyLCJ2ZXIiOjIsImRpZCI6ImFwaV8xN05PRXdWR2N2eU9xcGxuUWREMjdnWSIsInVpZCI6InBfMTFld3JWa0VuZDdMSXZTVkFtdDhYTDUifQ.5tYTjr_k0GKG6LsaAEt3V0RAiJe9UU59USUAASJTXf5e1923njb4UqYUozAVm34fARXT-SRvlE1-_J4wdiVNwg",
"userId": "p_11ewrVkEnd7LIvSVAmt8XL5",
"environmentId": "env_1Bx4omNvZgKao2OqGshImD",
"expiration": 1718944186,
"expiresAt": "2024-06-21T04:29:46Z"
}
The supplied email and metadata will be persisted to the Profile for future use.
See the API reference for all supported attributes.
Provide your own UUID for new Profiles to maintain referential integrity with external systems:
curl --request POST \
--url 'https://auth.quiltt.io/v1/users/sessions' \
--header 'Authorization: Bearer <API_SECRET_KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
"uuid": "885d9f06-7e1a-49f2-bc94-6b9e6a2c1c96"
}'
{
"token": "eyJhbGciOiJIUzUxMiJ9.eyJuYmYiOjE2NzE4MjI5MTIsImlhdCI6MTY3MTgyMjkxMiwianRpIjoiNDU1MWNhNDktYzAwMi00ZDliLTkyZWMtNDY1MDE4ZTI4ZmRjIiwiaXNzIjoiYXV0aC5xdWlsdHQuaW8iLCJhdWQiOiJhcGkucXVpbHR0LmlvIiwiZXhwIjoxNjcxOTA5MzEyLCJ2ZXIiOjIsImRpZCI6ImFwaV8xN05PRXdWR2N2eU9xcGxuUWREMjdnWSIsInVpZCI6InBfMTFld3JWa0VuZDdMSXZTVkFtdDhYTDUifQ.5tYTjr_k0GKG6LsaAEt3V0RAiJe9UU59USUAASJTXf5e1923njb4UqYUozAVm34fARXT-SRvlE1-_J4wdiVNwg",
"userId": "p_11ewrVkEnd7LIvSVAmt8XL5",
"environmentId": "env_1Bx4omNvZgKao2OqGshImD",
"expiration": 1718944186,
"expiresAt": "2024-06-21T04:29:46Z"
}
Or create Profiles directly via the REST Profiles API.
Issue Session tokens on your server without calling the Auth API. Contact us to request a signing secret.
Hit the rate limit (10/hour or 20/day per Profile). Common causes:
Fix: