ElevenLabs’ text-to-speech is the one most real-time agents, dubbing tools and audiobook pipelines reach for first — the output holds up as natural speech rather than reading like synthesized text. NativePort proxies the generation surface of ElevenLabs’ REST API; this guide covers the one call that surface exists for: turning a string of text into an audio file.
What you’ll need
- A NativePort API key. Sign up to get a key and $5 in credits.
curl, or Python 3 (standard library only — nopip install) if you’d rather write the response to a file in code.- Your key exported as an environment variable, never hardcoded:
export NATIVEPORT_API_KEY="np_..."
What’s admitted
ElevenLabs’ full REST surface covers a lot more than audio generation — account details, usage, workspace management, API-key minting, conversation history. All of that reads or mutates the shared company account the gateway authenticates every request with, so none of it is reachable through NativePort. What’s admitted is narrower and default-deny:
- POST
/v1/text-to-speech/{voice_id}(and its/streamvariant) — the endpoint this guide covers. - POST
/v1/speech-to-text,/v1/sound-generation,/v1/voice-changer,/v1/text-to-dialogue,/v1/audio-isolation— the rest of ElevenLabs’ generation surface. - GET
/v1/voices,/v2/voices,/v1/shared-voices,/v1/models— read-only discovery. - GET
/v1/convai/conversation/get-signed-url— the documented way to obtain a short-lived credential for opening a realtime WebSocket session directly against ElevenLabs, without ever handing out the shared key.
Notably absent: creating, editing or deleting a voice (only the read side of /v1/voices is admitted — there’s no route to POST /v1/voices/add a cloned voice), and everything account-scoped (/v1/user, /v1/usage/*, /v1/workspace/*, /v1/convai/secrets, /v1/history). GET /v1/user in particular is blocked because its response body echoes the master API key back — not something any client should ever see. Only GET/POST are mounted at all, so the mutating PATCH/DELETE verbs can’t reach ElevenLabs regardless of path. Anything outside this list 404s before it reaches ElevenLabs.
Find a voice to use
Every ElevenLabs account ships with a set of premade voices. List them rather than hardcoding an id, since which ones are available can vary:
curl https://api.nativeport.ai/elevenlabs/v1/voices \
-H "Authorization: Bearer $NATIVEPORT_API_KEY"
{
"voices": [
{"voice_id": "21m00Tcm4TlvDq8ikWAM", "name": "Rachel", "category": "premade"}
]
}
Generate speech
curl -X POST "https://api.nativeport.ai/elevenlabs/v1/text-to-speech/21m00Tcm4TlvDq8ikWAM" \
-H "Authorization: Bearer $NATIVEPORT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text": "This audio was generated through NativePort."}' \
--output speech.mp3
The one required field is text; voice_id travels in the path, not the body. model_id defaults to eleven_multilingual_v2 if omitted — check GET /v1/models for the current full list before pinning a different one, since ElevenLabs adds and retires model ids independently of this gateway. An optional voice_settings object (stability, similarity_boost, style, use_speaker_boost, speed) tunes delivery further; omit it to use the voice’s own defaults.
The response is not JSON — it’s the audio file itself (mp3_44100_128 by default; the output_format query parameter switches to wav, pcm, opus or other rates ElevenLabs documents). curl --output writes it straight to disk. In Python, the equivalent is reading the response body as bytes and writing it out, not parsing it as JSON:
import os
import urllib.request
req = urllib.request.Request(
"https://api.nativeport.ai/elevenlabs/v1/text-to-speech/21m00Tcm4TlvDq8ikWAM",
data=b'{"text": "This audio was generated through NativePort."}',
method="POST",
)
req.add_header("Authorization", f"Bearer {os.environ['NATIVEPORT_API_KEY']}")
req.add_header("Content-Type", "application/json")
req.add_header("User-Agent", "nativeport-python-guide/1.0")
with urllib.request.urlopen(req, timeout=60) as resp, open("speech.mp3", "wb") as f:
f.write(resp.read())
The /stream variant (POST /v1/text-to-speech/{voice_id}/stream) takes the identical body and returns the same audio chunked over the connection instead of as one buffered response — worth it once generation latency matters more than simplicity, not before.
Errors you’ll actually hit
402 Payment Required: the NativePort balance is at $0. Every request answers this deterministically rather than degrading, so top up and retry.401 Unauthorized: theAuthorization: Bearer <NATIVEPORT_API_KEY>header is missing, malformed, or doesn’t resolve to an account.403 Forbidden: the key is valid but the account isn’t active.404on/v1/user,/v1/usage/*,/v1/workspace/*,/v1/history, aPATCH/DELETEverb, or a voice-creation call: none of these are admitted — see “What’s admitted” above, not a transient failure to retry.404on avoice_idthat looks valid: the id belongs to a voice that doesn’t exist on the shared account behind this gateway, or was mistyped —GET /v1/voicesis the source of truth for what’s actually available, not any id you’ve seen in ElevenLabs’ own docs or dashboard.
Security
Treat NATIVEPORT_API_KEY like any other credential: environment variable or secret store, never a literal string in source, never logged. ElevenLabs’ own xi-api-key never reaches your process — the gateway injects it server-side, and the endpoint that would expose it back (GET /v1/user) is one of the ones blocked above.
What this costs
Usage here is metered as a flat rate per call rather than by character count the way ElevenLabs’ own plans price it — a short line and a long paragraph currently cost the same at the gateway. Check the ElevenLabs provider page for the current per-call rate. A zero balance answers every request with 402 instead of returning partial or degraded audio. Adding credit carries a flat 5.5% fee on top-ups between $10 and $5,000 — never on the calls themselves. Full breakdown: pricing.
Where to go next
- ElevenLabs provider page: current pricing and what else the gateway admits (speech-to-text, sound generation, voice changer).
- Pricing: the full billing model.
- How this native ElevenLabs call compares to a normalized text-to-speech schema: NativePort vs. Eden AI.