API & Embed

Build with Charafy API

Integrate AI character conversations, text-to-speech, video avatars, and real-time voice chat into your app.

Authentication

All API requests require an API key passed via the x-api-key header.

Include your API key in every request header:

x-api-key: YOUR_API_KEY

Get your API key from the Developer Dashboard. Keep it secret — do not expose it in client-side code.

Credits & Pricing

Charafy API uses a credit-based pricing model. Buy credits and use them across all endpoints. 1 credit = $0.01.

EndpointCreditsCost (USD)
Text-to-Speech/v1/tts1/ 100 chars (min 1)$0.01
Conversationaudio-only/v1/conversation/token5/ minute$0.05
Conversationvideo/v1/conversation/token8/ minute$0.08
Avatar Generation/v1/characters/:id/avatar8/ request$0.08
Video Generation/v1/video6/ second (min 6)$0.06
Voice Clone/v1/voice/clone100/ request$1.00

Quick Start

Get started in minutes. List your characters, generate speech, create videos, and start real-time conversations.

# 1. List your characters
curl https://charafy.ai/api/v1/characters \
  -H "x-api-key: YOUR_API_KEY"

# 2. Generate speech from text
curl -X POST https://charafy.ai/api/v1/tts \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"character_id": "CHAR_ID", "text": "Hello!"}' \
  --output speech.mp3

# 3. Generate a talking-head video
curl -X POST https://charafy.ai/api/v1/video \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"character_id": "CHAR_ID", "text": "Hello!"}'

# 4. Start a real-time conversation
curl -X POST https://charafy.ai/api/v1/conversation/token \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"character_id": "CHAR_ID", "mode": "audio-only"}'

API Endpoints

Characters

GET/v1/characters

Returns a list of all characters owned by the authenticated user, including embed URLs and avatar status.

Request

curl https://charafy.ai/api/v1/characters \
  -H "x-api-key: YOUR_API_KEY"

Response 200

{
  "characters": [
    {
      "character_id": "uuid",
      "name": "Sakura",
      "language": "ja",
      "voice_id": "uuid",
      "photo_url": "https://...",
      "embed_enabled": true,
      "avatar_type": "motion",
      "embed_url": "https://charafy.ai/embed/uuid"
    }
  ]
}
POST/v1/characters

Create a new AI character. Optionally generate an avatar (costs 39 credits). Image can be a base64 data URI or a public URL.

Request

curl -X POST https://charafy.ai/api/v1/characters \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Sakura",
    "image": "https://example.com/photo.jpg",
    "voice_id": "VOICE_UUID",
    "language": "ja",
    "avatar_type": "motion"
  }'

Request Body

ParameterTypeDescription
namestringreqCharacter display name (1-100 chars)
imagestringreqBase64 data URI (data:image/png;base64,...) or public image URL
voice_idstring (uuid)reqUUID of the voice to use (from GET /v1/voices)
language"ja" | "en"optCharacter language. Default: "ja"
avatar_type"sprite" | "motion" | "none"optAvatar type to generate. Default: "none" (no avatar). "motion" or "sprite" costs 39 credits
system_promptstringoptCustom system prompt for personality (max 10,000 chars)

Response 200

{
  "character_id": "uuid",
  "embed_url": "https://charafy.ai/embed/uuid",
  "avatars": {
    "sprite": false,
    "motion": true
  },
  "credits_used": 8,
  "credits_remaining": 992
}
PUT/v1/characters/:id/avatar

Generate or regenerate an avatar for an existing character. The character must have a photo.

Request

curl -X PUT https://charafy.ai/api/v1/characters/CHAR_ID/avatar \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"avatar_type": "motion"}'

Request Body

ParameterTypeDescription
avatar_type"sprite" | "motion"req"sprite" for animated sprite sheet, "motion" for AI-generated motion video

Response 200

{
  "character_id": "uuid",
  "sprite_ready": false,
  "motion_ready": true,
  "credits_used": 8,
  "credits_remaining": 992
}
PUT/v1/characters/:id/embed

Update embed settings for a character. Enable/disable embedding, configure allowed origins, and set usage limits.

Request

curl -X PUT https://charafy.ai/api/v1/characters/CHAR_ID/embed \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "embed_enabled": true,
    "allowed_origins": ["https://example.com"],
    "embed_session_limit_seconds": 300,
    "embed_daily_limit_seconds": 3600
  }'

Request Body

ParameterTypeDescription
embed_enabledbooleanoptEnable or disable embed for this character
allowed_originsstring[]optArray of allowed https:// origins (max 20). Empty array = allow all
embed_session_limit_secondsnumberoptMax seconds per embed session (60-3600)
embed_daily_limit_secondsnumberoptMax total embed seconds per day (60-86400)
embed_monthly_limit_secondsnumberoptMax total embed seconds per month (3600-2592000)
embed_max_concurrentnumberoptMax simultaneous embed sessions (1-100)

Response 200

{
  "character_id": "uuid",
  "embed_enabled": true,
  "allowed_origins": [
    "https://example.com"
  ],
  "embed_session_limit_seconds": 300,
  "embed_daily_limit_seconds": 3600,
  "embed_monthly_limit_seconds": null,
  "embed_max_concurrent": null,
  "embed_url": "https://charafy.ai/embed/uuid"
}

Voice

GET/v1/voices

Returns all voices available to the user, including preset voices and user-created clones.

Request

curl https://charafy.ai/api/v1/voices \
  -H "x-api-key: YOUR_API_KEY"

Response 200

{
  "voices": [
    {
      "voice_id": "uuid",
      "name": "Gentle Female",
      "language": "ja",
      "is_preset": true,
      "sample_url": "https://..."
    }
  ]
}
POST/v1/voice/clone

Clone a voice from an audio file. Upload audio (5-30 seconds recommended, max 10 MB) as multipart/form-data.

Requestmultipart/form-data

curl -X POST https://charafy.ai/api/v1/voice/clone \
  -H "x-api-key: YOUR_API_KEY" \
  -F "audio=@voice-sample.mp3" \
  -F "name=My Voice" \
  -F "language=ja"

Request Body

ParameterTypeDescription
audioFilereqAudio file (WAV, MP3, WebM, etc.). Max 10 MB
namestringreqName for the cloned voice (1-100 chars)
language"ja" | "en"optVoice language. Default: "ja"

Response 200

{
  "voice_id": "uuid",
  "name": "My Voice",
  "sample_url": "https://...",
  "credits_used": 100,
  "credits_remaining": 900
}

Text-to-Speech

POST/v1/tts

Generate speech audio from text using a character's voice. Returns binary audio/mpeg data.

Request

curl -X POST https://charafy.ai/api/v1/tts \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"character_id": "CHAR_ID", "text": "Hello!"}' \
  --output speech.mp3

Request Body

ParameterTypeDescription
character_idstring (uuid)reqUUID of the character to use
textstringreqText to convert to speech (1-5,000 chars)

Response 200

Binary audio data (audio/mpeg)

Video

POST/v1/video

Generate a talking-head video. Returns immediately with a job ID — poll GET /v1/video/:id for status.

Request

curl -X POST https://charafy.ai/api/v1/video \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "character_id": "CHAR_ID",
    "text": "Hello, world!"
  }'

Request Body

ParameterTypeDescription
character_idstring (uuid)reqUUID of the character (must have a photo)
textstringreqText for the character to speak (1-5,000 chars)
avatar_type"sprite" | "motion"optAvatar type. Default: "motion". "sprite" is not yet supported

Response 200

{
  "video_id": "uuid",
  "status": "processing",
  "poll_url": "https://charafy.ai/api/v1/video/uuid",
  "credits_used": 84,
  "credits_remaining": 916
}
GET/v1/video/:id

Check the status of a video generation job. Poll until status is "completed" or "failed".

Request

curl https://charafy.ai/api/v1/video/VIDEO_ID \
  -H "x-api-key: YOUR_API_KEY"

Response 200

{
  "video_id": "uuid",
  "status": "completed",
  "output_url": "https://...",
  "created_at": "2025-01-01T00:00:00Z",
  "completed_at": "2025-01-01T00:01:00Z"
}

Conversation

POST/v1/conversation/token

Get a session token to start a real-time voice/video conversation with a character. Use the returned token to connect via WebRTC.

Request

curl -X POST https://charafy.ai/api/v1/conversation/token \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "character_id": "CHAR_ID",
    "mode": "audio-only"
  }'

Request Body

ParameterTypeDescription
character_idstring (uuid)reqUUID of the character to talk to
mode"video" | "audio-only"optConversation mode. Default: "video". "audio-only" for voice only

Response 200

{
  "token": "eyJ...",
  "conversation_id": "uuid",
  "mode": "audio-only",
  "session_limit_seconds": 600,
  "expires_in": 3600,
  "credits_used": 50,
  "credits_remaining": 950,
  "billing": {
    "rate_credits_per_minute": 5,
    "prepaid_credits": 50,
    "note": "Unused credits are refunded when the session ends."
  }
}

Credits

GET/v1/credits

Check your current credit balance and recent transaction history (last 50 transactions).

Request

curl https://charafy.ai/api/v1/credits \
  -H "x-api-key: YOUR_API_KEY"

Response 200

{
  "credits_remaining": 500,
  "transactions": [
    {
      "id": "uuid",
      "amount": 1000,
      "type": "purchase",
      "description": "Credit purchase",
      "created_at": "2025-01-01T00:00:00Z"
    }
  ]
}

Error Handling

All errors return a JSON object with an "error" field. Common HTTP status codes:

StatusDescription
400Bad Request — Invalid parameters or malformed JSON
401Unauthorized — Missing or invalid API key
402Payment Required — Insufficient credits
403Forbidden — Resource limit reached (e.g., character limit on current plan)
404Not Found — Resource does not exist or is not owned by you
429Too Many Requests — Rate limit exceeded. Retry after a short delay
500Internal Server Error — Something went wrong on our end
502Bad Gateway — Upstream service (voice/video provider) error

Error response format:

{ "error": "Error message describing what went wrong" }

Embed

Embed an interactive AI character on any website with a single iframe tag. Enable embed in your character's settings or via the API.

<iframe
  src="https://charafy.ai/embed/YOUR_CHARACTER_ID"
  width="400"
  height="600"
  frameborder="0"
  allow="microphone"
></iframe>

Requires embed_enabled=true on the character. Configure allowed origins in the Developer Dashboard.

Learn more about widget embedding

See live demos and configuration for floating, overlay, and fullpage modes on the dedicated Embed page.

Ready to build?

Create an account and get your API key to start integrating AI characters into your app.