Reference

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 header
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:

API key authentication
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 response
{
  "error": "Unauthorized"
}
StatusMeaning
400Bad request — missing or invalid parameters
401Unauthorized — invalid or missing token
403Forbidden — insufficient permissions (e.g. developer role)
404Not found — resource does not exist or you lack access
405Method not allowed — wrong HTTP method
429Too many requests — rate limit exceeded
500Server 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:

Rate limit 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).

POST/apps-list

List all apps in your organization.

Request body

No body required. Send an empty POST request.

Example
Request
curl -X POST \
  https://avcilhftyfvmuqfeetyo.supabase.co/functions/v1/apps-list \
  -H "Authorization: Bearer your-access-token-here" \
  -H "Content-Type: application/json"
Response
{
  "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"
    }
  ]
}
POST/apps-create

Create a new app. Requires owner or admin role.

Request body
namestringrequired
App name (max 100 characters).
descriptionstring
Optional description (max 500 characters).
Example
Request
curl -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"
  }'
Response
{
  "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"
  }
}
POST/apps-get

Retrieve a single app by ID.

Request body
idstringrequired
The app ID (UUID).
Example
Request
curl -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" }'
Response
{
  "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"
  }
}
PATCH/apps-update

Update an app's name or description. Requires owner or admin role.

Request body
idstringrequired
The app ID (UUID).
namestringrequired
New app name.
descriptionstring | null
New description, or null to clear.
Example
Request
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"
  }'
Response
{
  "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"
  }
}
DELETE/apps-delete

Permanently delete an app and all associated data. Requires owner or admin role.

Request body
idstringrequired
The app ID (UUID).
Example
Request
curl -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" }'
Response
{
  "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.

POST/api-keys-list

List all API keys for an app. Key values are redacted — only the last 4 characters are shown.

Request body
app_idstringrequired
The app ID (UUID).
Example
Response
{
  "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_"
    }
  ]
}
POST/api-keys-create

Generate a new API key for an app. Requires owner or admin role.

Request body
app_idstringrequired
The app ID (UUID).
namestringrequired
A label for this key (e.g. "Production", "Dev").
Example
Response
{
  "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.

POST/api-keys-delete

Revoke and permanently delete an API key. Requires owner or admin role. Also accepts DELETE method.

Request body
idstringrequired
The API key ID (UUID) — not the key value itself.
Example
Response
{
  "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.

POST/customizer-defaults-get

Get the default customizer configuration for an app.

Request body
app_idstringrequired
The app ID (UUID).
Example
Response
{
  "success": true,
  "data": {
    "defaults": {
      "theme": "dark",
      "primaryColor": "#BC75FF",
      "slots": ["hair", "face", "body", "outfit"]
    }
  }
}
POST/customizer-defaults-upsert

Create or update the default customizer configuration for an app. Requires owner or admin role.

Request body
app_idstringrequired
The app ID (UUID).
defaultsobjectrequired
A JSON object containing the customizer configuration (colors, slots, presets, etc.).
Example
Request
curl -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"]
    }
  }'
Response
{
  "success": true,
  "data": {
    "app_id": "app-uuid",
    "defaults": { ... },
    "updated_at": "2026-01-15T10:30:00Z"
  }
}
POST/customizer-token-mint

Mint a short-lived JWT for embedding the avatar customizer. This is the primary endpoint your game backend calls.

Authentication

Supports two authentication modes:

  • Bearer token — for console users (playground mode)
  • API key headers — for server-to-server calls (embed mode). Pass x-app-id and x-api-key.
Request body
app_idstringrequired
The app ID. Can also be passed via x-app-id header.
mode"embed" | "playground"
Token mode. Defaults to "embed" when using API key auth, "playground" when using Bearer token.
player_idstring
Your game's unique player identifier. Required for MAU tracking in embed mode.
Example (API key auth)
Request
curl -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"
  }'
Response
{
  "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.

GET/plans-public-get

Retrieve all active plans and any current promotions. No authentication required.

Authentication

None required. This is a public endpoint.

Example
Request
curl https://avcilhftyfvmuqfeetyo.supabase.co/functions/v1/plans-public-get
Response
{
  "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
}
Looking to integrate avatars into your Unity game?

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.