beatrice
GraphQL API for LLM-powered smart-novel features. The service is model-provider-agnostic — configure it against any OpenAI-compatible endpoint via env vars.
See the repo for setup and self-hosting instructions.
API Endpoints
<<url is missing>>
Endpoint
All operations are served at POST /graphql on the deployed instance.
Queries
audioVoices
Description
Voice names available for TTS synthesis, from the configured default provider. Cached for the process lifetime after the first call. English text only for now — this limitation will be addressed later.
Response
Returns [String!]!
Example
Query
query audioVoices {
audioVoices
}
Response
{"data": {"audioVoices": ["xyz789"]}}
healthcheck
Description
Healthcheck API which returns basic info about the service and if it is running.
Response
Returns a HealthCheck!
Example
Query
query healthcheck {
healthcheck {
isRunning
model
version
}
}
Response
{
"data": {
"healthcheck": {
"isRunning": true,
"model": "qwen2.5:3b",
"version": "1.0.1"
}
}
}
Mutations
explainWord
Description
Return a structured explanation of a word as it is used in the given context.
Response
Returns a WordExplanationType!
Example
Query
mutation explainWord(
$word: String!,
$context: String!
) {
explainWord(
word: $word,
context: $context
) {
meaning
simplifiedExplanation
synonyms
antonyms
}
}
Variables
{
"word": "impulse",
"context": "She acted on impulse and booked a flight home the same night."
}
Response
{
"data": {
"explainWord": {
"meaning": "A sudden strong urge to do something impulsive.",
"simplifiedExplanation": "A quick feeling that makes you want to do something without thinking.",
"synonyms": ["urge", "whim", "impulse", "instinct"],
"antonyms": ["hesitation", "deliberation", "restraint"]
}
}
}
generateAudio
Description
Queue a TTS synthesis job. Publishes to RabbitMQ and returns immediately (HTTP 202) with a jobId — actual synthesis and upload happen asynchronously; progress and completion are reported via statusCallbackUrl.
Response
Returns a GenerateAudioResult!
Arguments
| Name | Description |
|---|---|
text - String!
|
Text to synthesize. Length is capped by the GENERATE_AUDIO__MAX_TEXT_LENGTH env var. |
voice - String!
|
Voice name — must be one returned by audioVoices. |
genUploadUrl - String!
|
Callback Beatrice POSTs to when it needs a presigned upload URL. Host must be in the GENERATE_AUDIO__CALLBACK__ALLOWED_HOSTS allow-list. |
statusCallbackUrl - String!
|
Callback Beatrice POSTs progress/state updates to. Host must be in the GENERATE_AUDIO__CALLBACK__ALLOWED_HOSTS allow-list. |
instruct - String
|
Qwen3-TTS-only. A style guide applied to the whole call, e.g. 'A male narrator with a clear voice. Treat bracketed words like [dramatic] as emotion cues, not literal text.' text is never parsed or stripped by Beatrice — any inline tags in it are passed through verbatim for the model to interpret per this guide. Rejected when the configured provider isn't Qwen3-TTS. Default = null |
Example
Query
mutation generateAudio(
$text: String!,
$voice: String!,
$genUploadUrl: String!,
$statusCallbackUrl: String!,
$instruct: String
) {
generateAudio(
text: $text,
voice: $voice,
genUploadUrl: $genUploadUrl,
statusCallbackUrl: $statusCallbackUrl,
instruct: $instruct
) {
jobId
}
}
Variables
{
"text": "The graffiti was ephemeral.",
"voice": "abc123",
"genUploadUrl": "xyz789",
"statusCallbackUrl": "abc123",
"instruct": null
}
Response
{"data": {"generateAudio": {"jobId": "550e8400-e29b-41d4-a716-446655440000"}}}
normalizeTextForTts
Description
Return an LLM-normalised version of the given text suitable for TTS.
Response
Returns a String!
Arguments
| Name | Description |
|---|---|
text - String!
|
Raw text to be normalised for TTS — numbers, acronyms, symbols, and dates are rewritten into the form a speech engine can read aloud naturally. Must be 1..4000 characters. |
Example
Query
mutation normalizeTextForTts($text: String!) {
normalizeTextForTts(text: $text)
}
Variables
{"text": "Dr. Smith met with 3 clients at 9am on 12/03/2024."}
Response
{"data": {"normalizeTextForTts": "xyz789"}}
Types
Boolean
Description
The Boolean scalar type represents true or false.
GenerateAudioResult
Description
Result of queuing a generateAudio job.
Fields
| Field Name | Description |
|---|---|
jobId - String!
|
UUID identifying this synthesis job. Use it to correlate statusCallbackUrl updates. |
Example
{"jobId": "550e8400-e29b-41d4-a716-446655440000"}
HealthCheck
Description
Snapshot of service liveness and configured model.
Example
{"isRunning": true, "model": "qwen2.5:3b", "version": "1.0.1"}
String
Description
The String scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
Example
"xyz789"
WordExplanationType
Description
Structured explanation of one word as it is used in a specific context.
Fields
| Field Name | Description |
|---|---|
meaning - String!
|
Concise dictionary-style definition of the word as used in context. |
simplifiedExplanation - String!
|
Same idea expressed for a younger or non-native reader. |
synonyms - [String!]!
|
Up to five words meaning roughly the same thing. |
antonyms - [String!]!
|
Up to five words meaning roughly the opposite. |
Example
{
"meaning": "A sudden strong urge to do something impulsive.",
"simplifiedExplanation": "A quick feeling that makes you want to do something without thinking.",
"synonyms": ["urge", "whim", "impulse", "instinct"],
"antonyms": ["hesitation", "deliberation", "restraint"]
}