Synthesize speech with file generation and S3 upload support.
When using the "Generate Speech (File)" button (/synthesize endpoint), you can use tags and formatting:
Note: Use natural punctuation and formatting for pacing. Tags cannot be nested - use combined tags instead.
For fine-grained control over pronunciation (e.g., correcting names like "Siquijor"), you can work directly with phonemes:
/phonemize endpoint (see API Docs) to get the default phoneme string for your text and language. Example: GET https://tts.nowarmup.com/phonemize?text=Siquijor&language=en-us /synthesize_phonemes endpoint (see API Docs) to generate audio from your corrected phoneme string. Example POST body: {
"phonemes": "s ɪ k i h ɔr", // Your corrected phonemes for Siquijor (Example only!)
"voice": "af_sarah", "language": "en-us", "speed": 1.0, "format": "mp3", "return_url": true
} Note: Tags like [slow] or [loud] are **not** processed when using the /synthesize_phonemes endpoint. Speed applies to the entire phoneme input via the request parameter.
Enter your API Key above if required. Examples updated for language parameter and new tags.
API_KEY="YOUR_API_KEY_HERE"; API_ENDPOINT="https://tts.nowarmup.com/synthesize"; API_HEADER=""
if [ -n "$API_KEY" ]; then API_HEADER="-H \"X-API-Key: $API_KEY\""; fi
curl -X POST "$API_ENDPOINT" -H "Content-Type: application/json" $API_HEADER \
-d '{
"text": "Normal pace sentence. [slow]Much slower for emphasis.[/slow] Then [fast]faster for excitement![/fast]",
"voice": "af_bella", "language": "en-us", "format": "mp3", "speed": 1.0
# return_url now defaults to true if not specified
}'
Note: Base speed (1.0) will be modified by tags: [slow] = 75%, [fast] = 125% of base speed. Tags only apply to /synthesize.
API_KEY="YOUR_API_KEY_HERE"; API_ENDPOINT="https://tts.nowarmup.com/phonemize"; API_HEADER=""
if [ -n "$API_KEY" ]; then API_HEADER="-H \"X-API-Key: $API_KEY\""; fi
TEXT_TO_PHONEMIZE="Siquijor"; LANGUAGE="en-us"
# Simple encoding (might fail for complex chars):
# curl -G "$API_ENDPOINT" --data-urlencode "text=$TEXT_TO_PHONEMIZE" --data-urlencode "language=$LANGUAGE" $API_HEADER
# More robust encoding with Python (if available):
ENCODED_TEXT=$(python3 -c "import urllib.parse; print(urllib.parse.quote(input()))" <<< "$TEXT_TO_PHONEMIZE")
curl -X GET "$API_ENDPOINT?text=${ENCODED_TEXT}&language=$LANGUAGE" $API_HEADER
API_KEY="YOUR_API_KEY_HERE"; API_ENDPOINT="https://tts.nowarmup.com/synthesize_phonemes"; API_HEADER=""
if [ -n "$API_KEY" ]; then API_HEADER="-H \"X-API-Key: $API_KEY\""; fi
curl -X POST "$API_ENDPOINT" -H "Content-Type: application/json" $API_HEADER \
-d '{
"phonemes": "s ɪ k i h ɔr", "voice": "af_bella", "language": "en-us",
"format": "mp3", "speed": 1.0, "return_url": true
}'
import requests, json, os
API_BASE_URL = "https://tts.nowarmup.com"; SYNTH_ENDPOINT = f"{API_BASE_URL}/synthesize"; API_KEY = os.getenv("TTS_API_KEY")
headers = { "Content-Type": "application/json" }; if API_KEY: headers["X-API-Key"] = API_KEY
data = { "text": "[fastloud]Breaking news![/fastloud]\n\n[slowloud]This is very important:[/slowloud]\n\n[fastquiet]Did you hear about the scarecrow that won an award?[/fastquiet]\n\n[slowquiet]He was outstanding in his field.[/slowquiet]", "voice": "af_heart", "language": "en-us", "format": "mp3", "speed": 1.0 }
try:
response = requests.post(SYNTH_ENDPOINT, headers=headers, json=data); response.raise_for_status()
result = response.json(); print(json.dumps(result, indent=2))
# ... handle results ...
except requests.exceptions.HTTPError as http_err: print(f"HTTP Error: {http_err}\nResponse: {http_err.response.text}")
except Exception as e: print(f"Error: {e}")
import requests, os, json
API_BASE_URL = "https://tts.nowarmup.com"; PHONEMIZE_ENDPOINT = f"{API_BASE_URL}/phonemize"; API_KEY = os.getenv("TTS_API_KEY"); headers = {}
if API_KEY: headers["X-API-Key"] = API_KEY
params = { "text": "Siquijor", "language": "en-us" }
try:
response = requests.get(PHONEMIZE_ENDPOINT, headers=headers, params=params); response.raise_for_status()
result = response.json(); print(json.dumps(result, indent=2))
except requests.exceptions.HTTPError as http_err: print(f"HTTP Error: {http_err}\nResponse: {http_err.response.text}")
except Exception as e: print(f"Error: {e}")
import requests, os, json
API_BASE_URL = "https://tts.nowarmup.com"; SYNTH_PHONEME_ENDPOINT = f"{API_BASE_URL}/synthesize_phonemes"; API_KEY = os.getenv("TTS_API_KEY")
headers = { "Content-Type": "application/json" }; if API_KEY: headers["X-API-Key"] = API_KEY
data = { "phonemes": "s ɪ k i h ɔr", "voice": "af_sarah", "language": "en-us", "format": "mp3", "speed": 1.0 }
try:
response = requests.post(SYNTH_PHONEME_ENDPOINT, headers=headers, json=data); response.raise_for_status()
result = response.json(); print(json.dumps(result, indent=2))
# ... handle results ...
except requests.exceptions.HTTPError as http_err: print(f"HTTP Error: {http_err}\nResponse: {http_err.response.text}")
except Exception as e: print(f"Error: {e}")
// API_BASE_URL, SYNTH_ENDPOINT, API_KEY, headers setup (same as before)
const API_BASE_URL = 'https://tts.nowarmup.com'; const SYNTH_ENDPOINT = `${API_BASE_URL}/synthesize`;
const apiKeyInput = document.getElementById('api_key'); const API_KEY = apiKeyInput ? apiKeyInput.value.trim() : null;
const headers = { 'Content-Type': 'application/json' }; if (API_KEY) headers['X-API-Key'] = API_KEY;
const data = {
text: '[fastloud]Attention please![/fastloud]\n\n[slowloud]This is your captain speaking.[/slowloud]\n\n[fastquiet]We have reached our cruising altitude.[/fastquiet]',
voice: 'af_nicole', language: 'en-us', format: 'mp3', return_url: true
};
fetch(SYNTH_ENDPOINT, { method: 'POST', headers: headers, body: JSON.stringify(data) })
.then(async response => { /* Error handling */ if (!response.ok) { let eD=`HTTP ${response.status}: ${response.statusText}`; try { const e=await response.json(); eD=`Err ${response.status}: ${e.detail||JSON.stringify(e)}`; } catch(e){} throw new Error(eD); } return response.json(); }) // Condensed error check
.then(result => { /* Result handling */ console.log('Result:', result); if (result.audio_url) { const audio = new Audio(result.audio_url); audio.play().catch(e => console.error('Play fail:', e)); } else { alert('No playable URL.'); } })
.catch(error => { console.error('Fetch Error:', error); alert('Request failed: ' + error.message); });
const API_BASE_URL = 'https://tts.nowarmup.com'; const PHONEMIZE_ENDPOINT = `${API_BASE_URL}/phonemize`;
const apiKeyInput = document.getElementById('api_key'); const API_KEY = apiKeyInput ? apiKeyInput.value.trim() : null;
const headers = {}; if (API_KEY) headers['X-API-Key'] = API_KEY;
const text = "Siquijor"; const lang = "en-us";
const url = new URL(PHONEMIZE_ENDPOINT); url.searchParams.append('text', text); url.searchParams.append('language', lang);
fetch(url, { method: 'GET', headers: headers })
.then(async response => { /* Error handling */ if (!response.ok) { let eD=`HTTP ${response.status}`; try{eD+=`: ${(await response.json()).detail||r.statusText}`}catch(e){} throw new Error(eD);} return response.json(); })
.then(result => { console.log('Phonemes:', result); alert(`Phonemes: ${result.phonemes}`); })
.catch(error => { console.error('Fetch Error:', error); alert('Phonemize failed: ' + error.message); });
Use an "HTTP Request" node in n8n:
POSThttps://tts.nowarmup.com/synthesize (or /synthesize_phonemes)Header Auth, select/create credential (Name: `X-API-Key`, Value: Your Key).Content-Type, Value: application/jsonJSON{
"text": "{{ $json.inputText || \"Hello [loud]n8n[/loud]! This is [slow]slow[/slow].\" }}",
"voice": "{{ $json.voiceName || \"am_michael\" }}",
"language": "{{ $json.langCode || \"en-us\" }}",
"format": "mp3",
"speed": 1.0
# return_url defaults to true if not specified
}
(For /synthesize_phonemes, use body: {"phonemes": "{{ $json.phonemeString }}", "voice": "...", ...})
JSON for /synthesize & /synthesize_phonemes.Timeout.To get phonemes first, use another HTTP Request node (Method: GET, URL: https://tts.nowarmup.com/phonemize, Send Query Parameters: `text`={{...}}, `language`={{...}}, Response Format: `JSON`).
Using n8n Credentials (Recommended): Create "Header Auth" credential (Name: `X-API-Key`, Value: Your Key) and select it in the node.
{
"id": "string (uuid)", "voice": "string", "format": "string (mp3|wav|ogg)", "language": "string", "created_at": "string (ISO 8601 UTC)",
"chunks": "integer | null", "synthesis_duration_sec": "number", "audio_duration_sec": "number",
"audio_url": "string | null", "audio_path": "string | null", "error": "string | null"
}