Installs into .claude/skills of the current project.
Are you the author of Durindoor Tts?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/bloodf-durindoor-tts)
---
name: durindoor-tts
description: Convert text to speech through DurinDoor using a model discovered from /v1/models/tts.
---
# DurinDoor Text-to-Speech
## Discover
```bash
curl -H "Authorization: Bearer $DURINDOOR_KEY" "$DURINDOOR_URL/v1/models/tts" | jq -r '.data[].id'
MODEL_ID="$(curl -s -H "Authorization: Bearer $DURINDOOR_KEY" "$DURINDOOR_URL/v1/models/tts" | jq -r '.data[0].id')"
curl -H "Authorization: Bearer $DURINDOOR_KEY" "$DURINDOOR_URL/v1/models/info?id=$MODEL_ID"
```
Some providers expose voices separately:
```bash
curl -H "Authorization: Bearer $DURINDOOR_KEY" "$DURINDOOR_URL/v1/audio/voices?provider=edge-tts" | jq -r '.data[].model'
```
Use the exact model or voice ID returned by discovery. Do not add a provider prefix unless the response includes it.
## Generate audio
```bash
curl -X POST "$DURINDOOR_URL/v1/audio/speech" \
-H "Authorization: Bearer $DURINDOOR_KEY" \
-H "Content-Type: application/json" \
-d "{\"model\":\"$MODEL_ID\",\"input\":\"Hello world\"}" \
--output speech.mp3
```
The default response is raw audio. Use `?response_format=json` for base64 JSON when supported.
## Use the default route
Leave out `model` and DurinDoor uses the text-to-speech route set in **Dashboard → Media Routes**: the default model first, then its fallbacks.
```bash
curl -X POST "$DURINDOOR_URL/v1/audio/speech" \
-H "Authorization: Bearer $DURINDOOR_KEY" \
-H "Content-Type: application/json" \
-d '{"input":"Hello world"}' \
--output speech.mp3
```
If no connected provider serves this endpoint, the response is HTTP 400 with `error.code` set to `no_provider_for_kind`. Connect a provider, or pass `model`.
Reference: https://github.com/bloodf/durindoor/blob/main/docs/reference/api.mdx