Platform API Reference
Complete reference for the MSJ Oratio platform REST API — every endpoint, request/response schema, parameter, and error code from the actual implementations.
Create an account
Sign up free to get started
Get your API key
Generate a key in API Keys
Make your first call
POST to /api/tts with text & voiceId
All platform API requests use this base URL. The standalone Voice API uses https://api.msjoratio.com — see Voice API docs.
Most endpoints require authentication. Include your API key using either header format:
orat_. Create keys in API Keys.| Plan | Characters / month | Max per request | Voice qualities | API rate |
|---|---|---|---|---|
| Free | 1,000 | 500 | Standard only | 10 req/min |
| Pro ($29/mo) | 500,000 | 5,000 | Standard, Premium, Ultra | 100 req/min |
POST /api/tts returns 429 with remaining balance details.curl -X POST https://msjoratio.com/api/tts \
-H "Authorization: Bearer orat_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "Hello from MSJ Oratio!",
"voiceId": "aria"
}'const response = await fetch("https://msjoratio.com/api/tts", {
method: "POST",
headers: {
"Authorization": "Bearer orat_YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
text: "Hello from MSJ Oratio!",
voiceId: "aria",
}),
});
const { generation, credits } = await response.json();
console.log(generation.audioUrl); // "/api/tts/audio/clx1abc..."
console.log(credits.remaining); // 499870import requests
response = requests.post(
"https://msjoratio.com/api/tts",
headers={"Authorization": "Bearer orat_YOUR_API_KEY"},
json={
"text": "Hello from MSJ Oratio!",
"voiceId": "aria",
},
)
data = response.json()
print(data["generation"]["audioUrl"])
print(data["credits"]["remaining"])Speech Generation
/api/tts Auth RequiredConvert text to speech using a selected voice. Deducts credits based on character count. Audio is generated and stored server-side.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| text | string | Required | Text to convert to speech. Max 500 chars (Free) or 5,000 chars (Pro). |
| voiceId | string | Required | Voice identifier from the catalog (e.g. "aria", "marcus", "luna"). |
| style | string | Optional | Override the voice default style. Falls back to the voice built-in style. |
Request Body
{
"text": "Hello, welcome to MSJ Oratio.",
"voiceId": "aria",
"style": "Warm & Expressive"
}Response
{
"generation": {
"id": "clx1abc...",
"text": "Hello, welcome to MSJ Oratio.",
"voiceName": "Aria",
"style": "Warm & Expressive",
"characterCount": 30,
"duration": 2.0,
"quality": 96.3,
"status": "completed",
"audioUrl": "/api/tts/audio/clx1abc...",
"createdAt": "2026-03-18T10:00:00Z"
},
"credits": {
"used": 130,
"limit": 500000,
"remaining": 499870
}
}Error Codes
/api/ttsPublicReturns the platform voice catalog with metadata. No authentication required. Returns the 5 built-in platform voices with quality tier, accent, gender, and category.
Response
{
"voices": [
{
"id": "aria",
"name": "Aria",
"accent": "American English",
"gender": "Female",
"quality": "Ultra",
"style": "Warm & Expressive",
"category": "Professional",
"languages": ["English"]
},
{
"id": "marcus",
"name": "Marcus",
"accent": "British English",
"gender": "Male",
"quality": "Premium",
"style": "Authoritative",
"category": "Professional",
"languages": ["English"]
},
{
"id": "luna",
"name": "Luna",
"accent": "Australian English",
"gender": "Female",
"quality": "Premium",
"style": "Calm",
"category": "Creative",
"languages": ["English"]
},
{
"id": "kai",
"name": "Kai",
"accent": "American English",
"gender": "Non-binary",
"quality": "Premium",
"style": "Dynamic",
"category": "Creative",
"languages": ["English"]
},
{
"id": "elena",
"name": "Elena",
"accent": "Spanish (ES)",
"gender": "Female",
"quality": "Premium",
"style": "Passionate",
"category": "Multilingual",
"languages": ["Spanish", "English"]
}
]
}Generations & Dashboard
/api/generations Auth RequiredRetrieve all past voice generations for the authenticated user, ordered by most recent first.
Response
{
"generations": [
{
"id": "clx1abc...",
"text": "Hello world",
"voiceName": "Aria",
"style": "Warm & Expressive",
"duration": 1.3,
"status": "completed",
"quality": 94.2,
"createdAt": "2026-03-18T10:00:00Z"
}
]
}Error Codes
/api/generations/:id Auth RequiredPermanently delete a specific generation by ID. Only the owner can delete their own generations.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | Required | Generation ID (path parameter) |
Response
{ "success": true }Error Codes
/api/dashboard Auth RequiredGet real-time credit usage, subscription status, aggregate stats, weekly activity chart data, and the 5 most recent generations.
Response
{
"user": { "name": "John", "email": "john@example.com" },
"credits": {
"used": 1250,
"limit": 500000,
"remaining": 498750,
"resetAt": "2026-03-01T00:00:00Z",
"percentUsed": 0
},
"subscription": {
"plan": "pro",
"isActive": true,
"periodEnd": "2026-04-18T00:00:00Z"
},
"stats": {
"totalGenerations": 47,
"thisMonthGenerations": 12,
"totalMinutes": 23.4,
"avgQuality": 93.7
},
"weeklyUsage": [
{ "day": "Mon", "count": 3, "characters": 450 }
],
"recentGenerations": [...]
}Error Codes
API Keys
/api/keys Auth RequiredRetrieve all API keys for the authenticated user, ordered by most recently created.
Response
{
"keys": [
{
"id": "clx2def...",
"name": "Production",
"key": "orat_a1b2c3d4e5...",
"createdAt": "2026-03-18T10:00:00Z"
}
]
}Error Codes
/api/keys Auth RequiredGenerate a new API key with a descriptive name. Keys are prefixed with orat_ and are 48 hex characters long.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | Required | Descriptive label for the key (max 100 characters) |
Request Body
{
"name": "Production Backend"
}Response
{
"key": {
"id": "clx2def...",
"name": "Production Backend",
"key": "orat_a1b2c3d4e5f6...",
"createdAt": "2026-03-18T10:00:00Z"
}
}Error Codes
/api/keys/:id Auth RequiredPermanently revoke and delete an API key. Only the key owner can delete.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | Required | API key ID (path parameter) |
Response
{ "deleted": true }Error Codes
Billing & Subscription
/api/stripe/checkout Auth RequiredInitiate a Stripe checkout session for the Pro plan. If the user already has an active subscription, returns a billing portal URL instead.
Response
{ "url": "https://checkout.stripe.com/c/pay_..." }Error Codes
/api/stripe/portal Auth RequiredCreate a Stripe billing portal session for managing subscription, payment methods, and invoices.
Response
{ "url": "https://billing.stripe.com/p/session/..." }Error Codes
Authentication
/api/registerPublicCreate a new user account with email and password. Password is hashed with bcrypt (12 rounds). Returns a clean user object without the password hash.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | Optional | User display name |
| string | Required | Unique email address | |
| password | string | Required | Password (minimum 8 characters) |
Request Body
{
"name": "John Doe",
"email": "john@example.com",
"password": "secureP@ss123"
}Response
{
"user": {
"id": "clx3ghi...",
"email": "john@example.com",
"name": "John Doe"
}
}Error Codes
12 built-in voices across 3 quality tiers. Free plan has access to Standard quality only; Pro unlocks Premium and Ultra.
| ID | Name | Quality | Accent | Category |
|---|---|---|---|---|
| aria | Aria | Ultra | American English | Professional |
| marcus | Marcus | Premium | British English | Professional |
| luna | Luna | Ultra | Australian English | Creative |
| kai | Kai | Premium | American English | Creative |
| elena | Elena | Premium | Spanish | Multilingual |
| omar | Omar | Premium | Middle Eastern | Creative |
| yuki | Yuki | Premium | Japanese | Multilingual |
| hans | Hans | Standard | German | Professional |
| sofia | Sofia | Premium | Italian | Creative |
| chen | Chen Wei | Premium | Mandarin | Multilingual |
| priya | Priya | Premium | Indian English | Professional |
| rafael | Rafael | Standard | Brazilian Portuguese | Creative |