RPM Studio logo

Technical documentation

Voice bank API – v1 documentation

The API follows a REST architecture and returns JSON. All requests use GET over HTTPS. Base URL:

https://rpm.pl/api/public/v1

1. Authentication

Every request requires an API key passed in theX-API-Key header. We also support theAuthorization: Bearer <key> header. Keys look likerpm_live_… and are assigned to a single company.

curl "https://rpm.pl/api/public/v1/voices?lang=polski&gender=f&limit=10" \
  -H "X-API-Key: rpm_live_xxxxxxxxxxxxxxxxxxxxxxxx"
  • Store the key on the server side (environment variable, backend config) and query the API from your own backend.
  • If you must query the API from the browser, tell us the domains the requests will come from – we'll whitelist them for your key.
  • You can rotate the key at any time: the old one stops working immediately once a new one is generated.

2. Language list

GET/v1/languages

Returns all voice-bank languages with the number of available voice talents. The slug field is the language identifier used in the other endpoints.

{
  "data": [
    { "slug": "polski", "label": "Polish", "voices_count": 126 },
    { "slug": "angielski-brytyjski", "label": "English (British)", "voices_count": 31 }
  ],
  "meta": { "total": 45 }
}

3. Voice talent list

GET/v1/voices

Returns a list of voice talents together with audio samples. Without thelang parameter, voices from every language are returned – in that case we recommend pagination.

ParameterTypeDefaultDescription
langstringallLanguage slug, e.g. polski, niemiecki, czeski.
genderm | fVoice talent's gender.
qstringName fragment (search).
expresstrue | falseOnly Express-mode voices.
exclusivetrue | falseOnly voices exclusive to RPM.
limit1–20050Number of records in the response.
offset0–100000Offset – pagination.
{
  "data": [
    {
      "slug": "anna-k",
      "name": "Anna K",
      "language": "polski",
      "language_label": "Polish",
      "gender": "f",
      "price_level": 2,
      "express": true,
      "exclusive": false,
      "availability": "available, turnaround up to 24 h",
      "image_url": "https://media.rpm.pl/voices/polski/anna-k.webp",
      "samples": [
        { "label": "A", "url": "https://media.rpm.pl/audio/polski/anna-k-a.mp3" },
        { "label": "B", "url": "https://media.rpm.pl/audio/polski/anna-k-b.mp3" }
      ],
      "page_url": "https://rpm.pl/bank-glosow/polski"
    }
  ],
  "meta": { "total": 126, "limit": 10, "offset": 0, "count": 10 }
}
FieldDescription
slugVoice talent identifier within the language.
nameName shown in the voice bank.
language / language_labelLanguage slug and its English label.
genderm (male) or f (female).
price_levelPrice tier 1–5, matching the partner price list.
expressAvailable in express mode.
exclusiveAvailable exclusively at RPM Studio.
availabilityAvailability and turnaround description.
image_urlVoice talent's photo (WebP) or null.
samplesList of MP3 demos: label and url.
page_urlThe corresponding voice-bank page on rpm.pl.

The API doesn't expose RPM Studio's internal categorisation tags. Instead of raw tags we return normalised express and exclusivefields that you can use directly as filters or badges in your UI.

4. Voice talent details

GET/v1/voices/{lang}/{slug}

Returns a single voice talent in the same structure as the list, inside thedata field. Useful for a "voice talent card" subpage on your site.

curl "https://rpm.pl/api/public/v1/voices/polski/anna-k" \
  -H "X-API-Key: rpm_live_xxxxxxxxxxxxxxxxxxxxxxxx"

5. Integration examples

Node.js / JavaScript

// Note: keep the key on your server, not in browser code.
const res = await fetch(
  "https://rpm.pl/api/public/v1/voices?lang=polski&gender=m",
  { headers: { "X-API-Key": process.env.RPM_API_KEY } }
);
const { data, meta } = await res.json();

data.forEach((voice) => {
  console.log(voice.name, voice.samples[0]?.url);
});

PHP

<?php
$ch = curl_init("https://rpm.pl/api/public/v1/voices?lang=polski");
curl_setopt($ch, CURLOPT_HTTPHEADER, ["X-API-Key: " . getenv("RPM_API_KEY")]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$voices = json_decode(curl_exec($ch), true)["data"];

6. Rate limits and caching

  • The standard limit is 1000 requests per hour per key; for larger deployments we agree limits individually.
  • Once the limit is exceeded the API returns status 429 with a Retry-After header.
  • We recommend caching responses on your side (5–15 minutes) and fetching the voice list every few minutes rather than on every user visit.
  • MP3 files and images are served from a CDN – you can link them directly, no need to copy them to your own server.

7. Error handling

Errors are returned in a consistent structure, with a machine-readable code and a developer-friendly description.

{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Exceeded the limit of 1000 requests per hour."
  }
}
StatusCodeMeaning
400invalid_queryInvalid query parameters.
401missing_api_keyMissing key header.
401invalid_api_keyThe key doesn't exist.
403api_key_disabledThe key has been disabled.
403origin_not_allowedDomain not assigned to the key.
404unknown_languageUnknown language slug.
404voice_not_foundVoice talent not found.
429rate_limit_exceededRate limit exceeded.

8. Usage rules

  • Audio samples are for presenting voices to the end client – they may not be used on air or in finished productions.
  • You order the actual recording at RPM Studio; we then provide production files and usage-rights documentation.
  • API data is provided solely to the company named in the agreement – the key must not be shared further.
  • Field scope and endpoints of v1 are stable; we will notify you by email in advance of any changes.