REST API Reference
The Ava-Twin REST API lets you manage apps, API keys, customizer settings, and mint session tokens from your own backend or any HTTP client.
Authentication
Most endpoints require a Bearer token in the Authorization header. This is the JWT access token you receive after signing in via Supabase Auth.
Authorization: Bearer your-access-token-here
The customizer-token-mint endpoint also supports API key authentication via custom headers, which is the recommended approach for server-to-server calls from your game backend:
x-app-id: your-app-id-here x-api-key: ava_sk_your-api-key-here
For multi-organization accounts, pass the optional x-org-id header to specify which organization context to use.
Base URL
All endpoints are Supabase Edge Functions served at:
https://avcilhftyfvmuqfeetyo.supabase.co/functions/v1/
Each endpoint is a separate function. For example, to list your apps, send a request to: https://avcilhftyfvmuqfeetyo.supabase.co/functions/v1/apps-list
Error Handling
All errors return a JSON object with an error field and an appropriate HTTP status code.
{
"error": "Unauthorized"
}| Status | Meaning |
|---|---|
| 400 | Bad request — missing or invalid parameters |
| 401 | Unauthorized — invalid or missing token |
| 403 | Forbidden — insufficient permissions (e.g. developer role) |
| 404 | Not found — resource does not exist or you lack access |
| 405 | Method not allowed — wrong HTTP method |
| 429 | Too many requests — rate limit exceeded |
| 500 | Server error — unexpected failure |
Successful responses include "success": true alongside the data payload.
Rate Limiting
Most authenticated endpoints are rate-limited to 20 requests per minute per user. Public endpoints (like plans) allow 60 requests per minute per IP.
When rate-limited, responses include these headers:
Retry-After: 60 X-RateLimit-Limit: 20 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1710345600
Apps
Apps represent your game projects. Each app has its own API keys, customizer settings, and usage tracking. Create a separate app for each game or environment (development / production).
/apps-listList all apps in your organization.
No body required. Send an empty POST request.
curl -X POST \ https://avcilhftyfvmuqfeetyo.supabase.co/functions/v1/apps-list \ -H "Authorization: Bearer your-access-token-here" \ -H "Content-Type: application/json"
{
"success": true,
"count": 2,
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"user_id": "user-uuid",
"org_id": "org-uuid",
"name": "My Game",
"description": "Production build",
"created_at": "2026-01-15T10:30:00Z"
}
]
}/apps-createCreate a new app. Requires owner or admin role.
namestringrequireddescriptionstringcurl -X POST \
https://avcilhftyfvmuqfeetyo.supabase.co/functions/v1/apps-create \
-H "Authorization: Bearer your-access-token-here" \
-H "Content-Type: application/json" \
-d '{
"name": "My Unity Game",
"description": "Production environment"
}'{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"user_id": "user-uuid",
"org_id": "org-uuid",
"name": "My Unity Game",
"description": "Production environment",
"created_at": "2026-01-15T10:30:00Z"
}
}/apps-getRetrieve a single app by ID.
idstringrequiredcurl -X POST \
https://avcilhftyfvmuqfeetyo.supabase.co/functions/v1/apps-get \
-H "Authorization: Bearer your-access-token-here" \
-H "Content-Type: application/json" \
-d '{ "id": "550e8400-e29b-41d4-a716-446655440000" }'{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"user_id": "user-uuid",
"org_id": "org-uuid",
"name": "My Unity Game",
"description": "Production environment",
"created_at": "2026-01-15T10:30:00Z"
}
}/apps-updateUpdate an app's name or description. Requires owner or admin role.
idstringrequirednamestringrequireddescriptionstring | nullnull to clear.curl -X PATCH \
https://avcilhftyfvmuqfeetyo.supabase.co/functions/v1/apps-update \
-H "Authorization: Bearer your-access-token-here" \
-H "Content-Type: application/json" \
-d '{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "My Game (Prod)",
"description": "Updated description"
}'{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"user_id": "user-uuid",
"org_id": "org-uuid",
"name": "My Game (Prod)",
"description": "Updated description",
"created_at": "2026-01-15T10:30:00Z"
}
}/apps-deletePermanently delete an app and all associated data. Requires owner or admin role.
idstringrequiredcurl -X DELETE \
https://avcilhftyfvmuqfeetyo.supabase.co/functions/v1/apps-delete \
-H "Authorization: Bearer your-access-token-here" \
-H "Content-Type: application/json" \
-d '{ "id": "550e8400-e29b-41d4-a716-446655440000" }'{
"success": true
}API Keys
API keys authenticate server-to-server requests (e.g. minting customizer tokens from your game backend). Keys are prefixed with ava_sk_ and are shown only once at creation.
/api-keys-listList all API keys for an app. Key values are redacted — only the last 4 characters are shown.
app_idstringrequired{
"success": true,
"count": 1,
"data": [
{
"id": "key-uuid",
"app_id": "app-uuid",
"name": "Production",
"created_at": "2026-01-15T10:30:00Z",
"key_last4": "Ab3x",
"key_prefix": "ava_sk_"
}
]
}/api-keys-createGenerate a new API key for an app. Requires owner or admin role.
app_idstringrequirednamestringrequired{
"success": true,
"data": {
"id": "key-uuid",
"app_id": "app-uuid",
"name": "Production",
"created_at": "2026-01-15T10:30:00Z",
"key_last4": "Ab3x",
"key_prefix": "ava_sk_",
"key": "ava_sk_dGhpcyBpcyBhIHBsYWNlaG9sZGVyIGtleQ"
}
}The full key value is returned only in this response. Store it securely — it cannot be retrieved again. If lost, delete the key and create a new one.
/api-keys-deleteRevoke and permanently delete an API key. Requires owner or admin role. Also accepts DELETE method.
idstringrequired{
"success": true
}Customizer
The customizer is the 3D avatar editor your players use to create their characters. These endpoints manage default settings and mint short-lived session tokens for embedding the customizer in your game.
/customizer-defaults-getGet the default customizer configuration for an app.
app_idstringrequired{
"success": true,
"data": {
"defaults": {
"theme": "dark",
"primaryColor": "#BC75FF",
"slots": ["hair", "face", "body", "outfit"]
}
}
}/customizer-defaults-upsertCreate or update the default customizer configuration for an app. Requires owner or admin role.
app_idstringrequireddefaultsobjectrequiredcurl -X POST \
https://avcilhftyfvmuqfeetyo.supabase.co/functions/v1/customizer-defaults-upsert \
-H "Authorization: Bearer your-access-token-here" \
-H "Content-Type: application/json" \
-d '{
"app_id": "app-uuid",
"defaults": {
"theme": "dark",
"primaryColor": "#BC75FF",
"slots": ["hair", "face", "body"]
}
}'{
"success": true,
"data": {
"app_id": "app-uuid",
"defaults": { ... },
"updated_at": "2026-01-15T10:30:00Z"
}
}/customizer-token-mintMint a short-lived JWT for embedding the avatar customizer. This is the primary endpoint your game backend calls.
Supports two authentication modes:
- Bearer token — for console users (playground mode)
- API key headers — for server-to-server calls (embed mode). Pass
x-app-idandx-api-key.
app_idstringrequiredx-app-id header.mode"embed" | "playground""embed" when using API key auth, "playground" when using Bearer token.player_idstringcurl -X POST \
https://avcilhftyfvmuqfeetyo.supabase.co/functions/v1/customizer-token-mint \
-H "x-app-id: your-app-id-here" \
-H "x-api-key: ava_sk_your-api-key-here" \
-H "Content-Type: application/json" \
-d '{
"player_id": "player-12345",
"mode": "embed"
}'{
"token": "eyJhbGciOiJIUzI1NiIs...",
"expiresIn": 300
}Tokens expire in 5 minutes (300 seconds). Mint a new token for each customizer session. MAU usage is tracked per unique player_id per calendar month.
Plans
Public endpoint for retrieving available plans and pricing. No authentication required.
/plans-public-getRetrieve all active plans and any current promotions. No authentication required.
None required. This is a public endpoint.
curl https://avcilhftyfvmuqfeetyo.supabase.co/functions/v1/plans-public-get
{
"success": true,
"plans": [
{
"name": "free",
"displayName": "Free",
"price": "$0",
"priceYearly": null,
"cadence": "",
"highlight": "Start building for free",
"bullets": ["1 app", "50 MAU", "2 API keys per app", "1 member", "Community support"],
"comparisonFeatures": [...],
"featured": false,
"trialEligible": false,
"trialDays": 0
},
{
"name": "pro",
"displayName": "Pro",
"price": "$49",
"priceYearly": 468,
"cadence": "/ month",
"highlight": "For growing products",
"bullets": ["10 apps", "500 MAU", "5 API keys per app", "10 members", "Email support"],
"comparisonFeatures": [...],
"featured": true,
"trialEligible": true,
"trialDays": 30
}
],
"promotion": null
}The Unity SDK handles avatar loading, caching, animation, and character controls. For most use cases, the SDK is all you need — the REST API is for server-side management and automation.