Install
openclaw skills install elevenlabs-apiElevenLabs API integration with managed authentication. AI-powered text-to-speech, voice cloning, sound effects, and audio processing. Use this skill when users want to generate speech from text, clone voices, create sound effects, or process audio. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway).
openclaw skills install elevenlabs-apiAccess the ElevenLabs API with managed authentication. Generate lifelike speech from text, clone voices, create sound effects, and process audio.
# List available voices
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/elevenlabs/v1/voices')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
https://api.maton.ai/elevenlabs/{native-api-path}
Maton proxies requests to api.elevenlabs.io and automatically injects your API key.
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEY
Environment Variable: Set your API key as MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Manage your ElevenLabs connections at https://api.maton.ai.
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=elevenlabs&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'elevenlabs'}).encode()
req = urllib.request.Request('https://api.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"connection": {
"connection_id": "{connection_id}",
"status": "ACTIVE",
"creation_time": "2026-02-12T00:50:40.292363Z",
"last_updated_time": "2026-02-12T00:51:14.547893Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "elevenlabs",
"metadata": {}
}
}
Open the returned url in a browser to complete authorization.
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple ElevenLabs connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/elevenlabs/v1/voices')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple connections, always include this header to ensure requests go to the intended account.
POST /elevenlabs/v1/text-to-speech/{voice_id}
Content-Type: application/json
{
"text": "Hello, this is a test of the ElevenLabs API.",
"model_id": "eleven_multilingual_v2",
"voice_settings": {
"stability": 0.5,
"similarity_boost": 0.75
}
}
Returns audio data (mp3 by default).
Query parameters:
output_format - Audio format (e.g., mp3_44100_128, pcm_16000, pcm_22050)POST /elevenlabs/v1/text-to-speech/{voice_id}/stream
Content-Type: application/json
{
"text": "Hello, this is streamed audio.",
"model_id": "eleven_multilingual_v2"
}
Returns streaming audio data.
POST /elevenlabs/v1/text-to-speech/{voice_id}/with-timestamps
Content-Type: application/json
{
"text": "Hello world",
"model_id": "eleven_multilingual_v2"
}
Returns audio with word-level timestamps.
GET /elevenlabs/v1/voices
Returns all available voices including premade and cloned voices.
GET /elevenlabs/v1/voices/{voice_id}
Returns metadata about a specific voice.
GET /elevenlabs/v1/voices/settings/default
GET /elevenlabs/v1/voices/{voice_id}/settings
POST /elevenlabs/v1/voices/add
Content-Type: multipart/form-data
name: My Cloned Voice
files: [audio_sample.mp3]
description: A custom voice clone
remove_background_noise: false
PATCH /elevenlabs/v1/voices/{voice_id}/edit
Content-Type: multipart/form-data
name: Updated Voice Name
description: Updated description
DELETE /elevenlabs/v1/voices/{voice_id}
GET /elevenlabs/v1/models
Returns available models:
eleven_multilingual_v2 - Latest multilingual modeleleven_turbo_v2_5 - Low-latency modeleleven_monolingual_v1 - Legacy English model (deprecated)GET /elevenlabs/v1/user
GET /elevenlabs/v1/user/subscription
Returns subscription details including character limits and usage.
GET /elevenlabs/v1/history?page_size=100
Query parameters:
page_size - Number of items per page (default: 100, max: 1000)start_after_history_item_id - Cursor for paginationvoice_id - Filter by voiceGET /elevenlabs/v1/history/{history_item_id}
GET /elevenlabs/v1/history/{history_item_id}/audio
Returns the audio file for a history item.
DELETE /elevenlabs/v1/history/{history_item_id}
POST /elevenlabs/v1/history/download
Content-Type: application/json
{
"history_item_ids": ["id1", "id2", "id3"]
}
Returns a zip file with the requested audio files.
POST /elevenlabs/v1/sound-generation
Content-Type: application/json
{
"text": "A thunderstorm with heavy rain and distant thunder",
"duration_seconds": 10.0
}
Query parameters:
output_format - Audio format (e.g., mp3_44100_128)POST /elevenlabs/v1/audio-isolation
Content-Type: multipart/form-data
audio: [audio_file.mp3]
Returns cleaned audio with background noise removed.
POST /elevenlabs/v1/audio-isolation/stream
Content-Type: multipart/form-data
audio: [audio_file.mp3]
POST /elevenlabs/v1/speech-to-text
Content-Type: multipart/form-data
audio: [audio_file.mp3]
model_id: scribe_v1
Returns transcription with optional word-level timestamps.
POST /elevenlabs/v1/speech-to-speech/{voice_id}
Content-Type: multipart/form-data
audio: [source_audio.mp3]
model_id: eleven_multilingual_sts_v2
Transforms audio to use a different voice while preserving intonation.
GET /elevenlabs/v1/projects
GET /elevenlabs/v1/projects/{project_id}
POST /elevenlabs/v1/projects
Content-Type: application/json
{
"name": "My Audiobook Project",
"default_title_voice_id": "voice_id",
"default_paragraph_voice_id": "voice_id"
}
GET /elevenlabs/v1/pronunciation-dictionaries
POST /elevenlabs/v1/pronunciation-dictionaries/add-from-file
Content-Type: multipart/form-data
name: My Dictionary
file: [lexicon.pls]
ElevenLabs API responses include useful headers:
x-character-count - Characters used in the requestrequest-id - Unique request identifierHistory and other list endpoints use cursor-based pagination:
GET /elevenlabs/v1/history?page_size=100&start_after_history_item_id=last_item_id
const response = await fetch(
'https://api.maton.ai/elevenlabs/v1/text-to-speech/JBFqnCBsd6RMkjVDRZzb',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
text: 'Hello world!',
model_id: 'eleven_multilingual_v2'
})
}
);
const audioBuffer = await response.arrayBuffer();
import os
import requests
response = requests.post(
'https://api.maton.ai/elevenlabs/v1/text-to-speech/JBFqnCBsd6RMkjVDRZzb',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'},
json={
'text': 'Hello world!',
'model_id': 'eleven_multilingual_v2'
}
)
audio_data = response.content
with open('output.mp3', 'wb') as f:
f.write(audio_data)
import os
import requests
response = requests.get(
'https://api.maton.ai/elevenlabs/v1/voices',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
)
voices = response.json()
for voice in voices['voices']:
print(f"{voice['name']}: {voice['voice_id']}")
codec_sample_rate_bitrate (e.g., mp3_44100_128)eleven_multilingual_v2 (recommended), eleven_turbo_v2_5 (low latency)curl -g when URLs contain brackets to disable glob parsingjq, environment variables may not expand correctly. Use Python examples instead.| Status | Meaning |
|---|---|
| 400 | Missing ElevenLabs connection or invalid request |
| 401 | Invalid or missing Maton API key |
| 403 | Insufficient permissions or quota exceeded |
| 422 | Invalid parameters |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from ElevenLabs API |
MATON_API_KEY environment variable is set:echo $MATON_API_KEY
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
elevenlabs. For example:https://api.maton.ai/elevenlabs/v1/voiceshttps://api.maton.ai/v1/voices