Entwickeln / Anleitungen

Audio & Bilder

Wie Sie Audio transkribieren, Text vorlesen lassen und Bilder erzeugen, und welche Grenzen das Gateway dabei prüft.

Drei Endpunkte verarbeiten Audio und Bilder. Alle drei nutzen dieselbe Basis-URL und denselben Schlüssel wie Chat. Die Modell-ID muss zur Familie des Endpunkts passen; welche Modelle Ihr Schlüssel erreicht, zeigt GET /v1/models. Die IDs in den Beispielen stammen aus dem Katalog und können sich ändern.

Audio transkribieren

POST /v1/audio/transcriptions erwartet multipart/form-data mit den Feldern file und model.

  • Die Anfrage darf höchstens 26 MB groß sein. Größere Anfragen lehnt das Gateway mit 413 request_too_large ab.
  • Audio gilt als Dateiinhalt. Ist Dateiinhalte zulassen unter Models → Datenschutz aus, antwortet das Gateway mit 403 file_content_not_allowed.
  • Streaming gibt es hier nicht. stream=true führt zu 400 streaming_not_supported_for_endpoint.

Das Gateway rechnet nach der Dauer der Aufnahme ab.

Shell
curl https://api.noirdoc.de/v1/audio/transcriptions \
  -H "Authorization: Bearer $NOIRDOC_API_KEY" \
  -F model="whisper" \
  -F file="@diktat.mp3"
Python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.noirdoc.de/v1",
    api_key=os.environ["NOIRDOC_API_KEY"],
)

with open("diktat.mp3", "rb") as audio:
    transcript = client.audio.transcriptions.create(
        model="whisper", file=audio
    )
print(transcript.text)
TypeScript
import fs from "node:fs";
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.noirdoc.de/v1",
  apiKey: process.env.NOIRDOC_API_KEY,
});

const transcript = await client.audio.transcriptions.create({
  model: "whisper",
  file: fs.createReadStream("diktat.mp3"),
});
console.log(transcript.text);

Text vorlesen lassen

POST /v1/audio/speech erwartet JSON und antwortet mit Audiodaten statt JSON. Speichern Sie die Antwort als Datei.

  • input ist Pflicht und hat höchstens 4.096 Zeichen.
  • voice ist Pflicht. Welche Stimmen ein Modell kennt, legt der Anbieter fest.
  • Verstöße beantwortet das Gateway mit 400 invalid_tts_request.
  • Streaming gibt es hier nicht.

Das Gateway rechnet nach der Zahl der Zeichen in input ab.

Shell
curl https://api.noirdoc.de/v1/audio/speech \
  -H "Authorization: Bearer $NOIRDOC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "tts",
    "voice": "<stimme>",
    "response_format": "mp3",
    "input": "Ihr Termin ist am Dienstag um 10 Uhr."
  }' \
  --output termin.mp3
Python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.noirdoc.de/v1",
    api_key=os.environ["NOIRDOC_API_KEY"],
)

speech = client.audio.speech.create(
    model="tts",
    voice="<stimme>",
    response_format="mp3",
    input="Ihr Termin ist am Dienstag um 10 Uhr.",
)
speech.write_to_file("termin.mp3")
TypeScript
import fs from "node:fs";
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.noirdoc.de/v1",
  apiKey: process.env.NOIRDOC_API_KEY,
});

const speech = await client.audio.speech.create({
  model: "tts",
  voice: "<stimme>",
  response_format: "mp3",
  input: "Ihr Termin ist am Dienstag um 10 Uhr.",
});
const audio = Buffer.from(await speech.arrayBuffer());
fs.writeFileSync("termin.mp3", audio);

Bilder erzeugen

POST /v1/images/generations erzeugt Bilder aus einem Prompt. Das Gateway prüft vor dem Weiterleiten:

FeldGrenze
promptPflicht, nicht leer
nganze Zahl von 1 bis 10, Standard 1
sizeBREITExHÖHE, jede Seite höchstens 2048
gesamthöchstens 16 Megapixel je Anfrage

Die Megapixel zählt das Gateway je Bild in angefangenen Einheiten von 1024 × 1024 Pixeln, mal n. Ohne size rechnet es mit 1024x1024. Verstöße beantwortet es mit 400 invalid_image_request, auch "size": "auto". Welche Größen und wie viele Bilder ein Modell annimmt, legt zusätzlich der Anbieter fest.

Bilder bearbeiten (/v1/images/edits) unterstützt das Gateway nicht. Streaming gibt es hier nicht.

Bei den angebundenen Bildmodellen stehen die Bilder Base64-kodiert in data[].b64_json. Das Gateway rechnet je nach Modell pro Bild oder pro Megapixel ab.

Shell
curl https://api.noirdoc.de/v1/images/generations \
  -H "Authorization: Bearer $NOIRDOC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "black-forest-labs/FLUX.1-schnell",
    "prompt": "Ein Leuchtturm an der Nordsee bei Sonnenaufgang",
    "size": "1024x1024",
    "n": 1
  }' \
  | jq -r '.data[0].b64_json' | base64 --decode > leuchtturm.png
Python
import base64
import os

from openai import OpenAI

client = OpenAI(
    base_url="https://api.noirdoc.de/v1",
    api_key=os.environ["NOIRDOC_API_KEY"],
)

image = client.images.generate(
    model="black-forest-labs/FLUX.1-schnell",
    prompt="Ein Leuchtturm an der Nordsee bei Sonnenaufgang",
    size="1024x1024",
    n=1,
)
with open("leuchtturm.png", "wb") as f:
    f.write(base64.b64decode(image.data[0].b64_json))
TypeScript
import fs from "node:fs";
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.noirdoc.de/v1",
  apiKey: process.env.NOIRDOC_API_KEY,
});

const image = await client.images.generate({
  model: "black-forest-labs/FLUX.1-schnell",
  prompt: "Ein Leuchtturm an der Nordsee bei Sonnenaufgang",
  size: "1024x1024",
  n: 1,
});
const png = Buffer.from(image.data![0].b64_json!, "base64");
fs.writeFileSync("leuchtturm.png", png);

Anbieter aus der Antwort lesen

Auch Audio- und Bildantworten tragen den Header X-Noirdoc-Provider. Er nennt den Anbieter, der die Anfrage beantwortet hat. Details zu Feldern und Unterrouten stehen unter Audio und Bilder.

Fehler

StatusCodeBedeutung
400wrong_endpoint_for_modelDas Modell gehört zu einer anderen Endpunkt-Familie oder einem anderen API-Format als der aufgerufene Endpunkt.
400streaming_not_supported_for_endpointDie Anfrage verlangt Streaming, der Endpunkt unterstützt es aber nicht.
400invalid_image_requestprompt, n oder size liegt außerhalb der Grenzen des Gateways; message nennt den Parameter.
400invalid_tts_requestinput oder voice fehlt oder ist leer, oder input ist zu lang.
400invalid_multipart_bodyDer Body ist kein gültiges multipart/form-data, oder model, stream bzw. response_format kommt mehrfach vor.
403masking_not_supported_for_endpointDer Endpunkt kann nicht maskieren, aber die Maskierungsrichtlinie ist enforced oder die Anfrage sendet X-Noirdoc-Mask: on.
403file_content_not_allowedDie Anfrage enthält Dateien, Bilder oder Audio, und die Organisation lässt keine Dateiinhalte zu.
405method_not_allowedDer Endpunkt nimmt nur POST an.
413request_too_largeDer Body überschreitet das Größenlimit des Endpunkts.