API-viite
Tämä dokumentti vastaa Express-sovelluksen käyttäytymistä tiedostossa api/app.js ja reitinkäsittelijöitä kansiossa api/routes/.
Rajat ja käyttäytyminen
| Kohde | Arvo |
|---|---|
| JSON-rungon koko | Jopa 2 MB (express.json({ limit: '2mb' })) |
| Kohteet per pyyntö | 1–36 kielikoodia |
| Eräkohtaiset kohteet | 1–100 kohdetta per eräpyyntö |
| Mallit | standard (oletus) tai advanced (vain maksullisissa tasoissa; katso alla) |
Kuukausittainen token-rajoitus (ilmainen taso): Ennen mallin kutsumista API arvioi tokenit likimain kaavalla ceil(content_length / 4) × (number_of_targets + 1) ja vain free-tasolla hylkää pyynnön koodilla 429 / token_limit_reached, jos arvio ylittäisi jäljellä olevan kuukausittaisen määrän (FREE_TIER_MONTHLY_TOKENS, oletus 100000). Maksullisia tasoja ei estetä tällä esitarkistuksella enforceTokenCap -tiedostossa; käyttö kirjataan kuitenkin.
Nopeusrajoitukset: Kun Upstash Redis on konfiguroitu (UPSTASH_REDIS_REST_URL / UPSTASH_REDIS_REST_TOKEN, ja URL ei sisällä paikkamerkkiä your-instance), sovelletaan tasokohtaisia minuutin rajoituksia: ilmainen 5, starter 30, growth 60, scale 120, enterprise rajoittamaton. Rajoituksen ylittyessä vastaus on 429 ja virhe rate_limit_reached. Jos Redis ei ole konfiguroitu, nopeusrajoitus ohitetaan (katso rateLimit.js).
Onnistuneissa rajoitetuissa vastauksissa voi olla otsikot X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
GET /health
Ei autentikointia.
Vastaus 200
{
"status": "ok",
"timestamp": "2025-03-23T12:00:00.000Z"
}
GET /languages
Ei autentikointia.
Palauttaa kanonisen listan tuetuista kielistä (koodi, näyttönimi, RTL-lippu). Merkintöjä on 36; koodit ovat ainoat hyväksytyt arvot targets-kentässä käännöspäätepisteissä.
Vastaus 200
{
"languages": [
{ "code": "en", "name": "English", "rtl": false },
{ "code": "ar", "name": "Arabic", "rtl": true }
]
}
Lähde: api/utils/languages.js.
POST /translate
Vaatii Authorization: Bearer <api_key>.
Kääntää yksittäisen content-merkkijonon jokaiselle targets-listassa olevalle kielelle. Malli palauttaa yhden JSON-objektin, jonka avaimet ovat täsmälleen pyydetyt kielikoodit ja arvot käännettyjä merkkijonoja (katso formatPrompts.js).
Pyyntörunko
| Kenttä | Tyyppi | Pakollinen | Kuvaus |
|---|---|---|---|
content | string | Kyllä | Ei-tyhjä käännettävä merkkijono. |
targets | string[] | Kyllä | Ei-tyhjä taulukko kelvollisia kielikoodeja (max 36). |
format | string | Ei | Yksi arvoista plain, markdown, json, html. Jos jätetään pois, formaatti tunnistetaan automaattisesti content-kentästä. |
source | string | Ei | Mallille annettava lähdekielen vihje; valinnainen. |
model | string | Ei | standard (oletus) tai advanced. advanced vaatii maksullisen tason (403 ilmaisella). |
Vastaus 200
{
"translations": {
"es": "...",
"fr": "..."
},
"usage": {
"input_tokens": 120,
"output_tokens": 340,
"total_tokens": 460,
"model": "standard",
"detected_format": "markdown",
"detection_confidence": 0.95
}
}
detected_format ja detection_confidence näkyvät vain, kun format jätettiin pois ja automaattinen tunnistus suoritettiin.
Esimerkki (cURL)
curl -sS -X POST "https://api.usepolylingo.com/v1/translate" \
-H "Authorization: Bearer $POLYLINGO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "{\"title\":\"Hello\"}",
"format": "json",
"targets": ["fr", "de"]
}'
Esimerkki (Python 3)
pip install requests
import os, requests
url = "https://api.usepolylingo.com/v1/translate"
headers = {
"Authorization": f"Bearer {os.environ['POLYLINGO_API_KEY']}",
"Content-Type": "application/json",
}
r = requests.post(url, json={
"content": "<p>Hello <strong>world</strong></p>",
"format": "html",
"targets": ["es"],
}, timeout=120)
r.raise_for_status()
print(r.json()["translations"]["es"])
POST /translate/batch
Vaatii Authorization: Bearer <api_key>.
Käsittelee jokaisen kohteen peräkkäin (yksi mallikutsu per kohde). Jos jokin kohde epäonnistuu, API palauttaa 500 eikä palauta osittaisia tuloksia kyseiselle pyynnölle.
Pyyntörunko
| Kenttä | Tyyppi | Pakollinen | Kuvaus |
|---|---|---|---|
items | array | Kyllä | Jokainen elementti: id (string), content (string), valinnainen format. |
targets | string[] | Kyllä | Samat säännöt kuin /translate. |
source | string | Ei | Valinnainen lähdekielen vihje. |
model | string | Ei | standard tai advanced (samat säännöt kuin /translate). |
Vastaus 200
{
"results": [
{ "id": "welcome", "translations": { "fr": "...", "de": "..." } },
{ "id": "goodbye", "translations": { "fr": "...", "de": "..." } }
],
"usage": {
"total_tokens": 900,
"input_tokens": 400,
"output_tokens": 500,
"model": "standard"
}
}
Esimerkki
curl -sS -X POST "https://api.usepolylingo.com/v1/translate/batch" \
-H "Authorization: Bearer $POLYLINGO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{ "id": "a", "content": "Hello", "format": "plain" },
{ "id": "b", "content": "## Title", "format": "markdown" }
],
"targets": ["es", "it"]
}'
POST /jobs
Vaatii Authorization: Bearer <api_key>.
Lisää käännöstehtävän jonoon ja palauttaa välittömästi job_id:n. Käännös suoritetaan taustalla — ei HTTP-aikarajaa sisällön koosta riippumatta. Kysy tulosta GET /jobs/:id -päätepisteestä.
Käytä tätä päätepistettä POST /translate sijaan, kun käännät suuria dokumentteja (pitkä Markdown, monta kohdekieltä), joissa pyynnön kesto saattaa ylittää HTTP-asiakkaasi tai välityspalvelimesi aikarajan.
Pyyntörunko
| Kenttä | Tyyppi | Pakollinen | Kuvaus |
|---|---|---|---|
content | string | Kyllä | Ei-tyhjä käännettävä merkkijono. |
targets | string[] | Kyllä | Ei-tyhjä taulukko kelvollisia kielikoodeja (max 36). |
format | string | Ei | Yksi arvoista plain, markdown, json, html. Tunnistetaan automaattisesti, jos jätetään pois. |
source | string | Ei | Lähdekielen vihje; valinnainen. |
model | string | Ei | standard (oletus) tai advanced. |
Vastaus 202
{
"job_id": "a1b2c3d4-...",
"status": "pending",
"created_at": "2025-03-23T12:00:00.000Z"
}
GET /jobs/:id
Vaatii Authorization: Bearer <api_key>.
Kysyy tilaa POST /jobs -päätepisteellä lähetetylle työlle. Kysy 5–10 sekunnin välein. Työt kuuluvat lähettäneelle käyttäjälle — muut käyttäjät saavat 404.
Vastaus (odottaa / käsittelyssä)
{
"job_id": "a1b2c3d4-...",
"status": "pending",
"created_at": "2025-03-23T12:00:00.000Z",
"updated_at": "2025-03-23T12:00:00.000Z",
"completed_at": null,
"queue_position": 3
}
status on pending (odottaa työntekijää) tai processing (työntekijä on ottanut työn). queue_position (1-pohjainen) kertoo, kuinka monta odottavaa tai käsittelevää työtä on luotu tätä ennen — käytä sitä etenemisen näyttämiseen käyttöliittymässä. Jos laskentakysely epäonnistuu, arvo jätetään pois.
Vastaus (valmis)
{
"job_id": "a1b2c3d4-...",
"status": "completed",
"created_at": "2025-03-23T12:00:00.000Z",
"updated_at": "2025-03-23T12:00:02.000Z",
"completed_at": "2025-03-23T12:00:02.000Z",
"translations": {
"es": "...",
"fr": "..."
},
"usage": {
"input_tokens": 120,
"output_tokens": 340,
"total_tokens": 460,
"model": "standard"
}
}
Vastaus (epäonnistui)
{
"job_id": "a1b2c3d4-...",
"status": "failed",
"error": "Model returned invalid JSON"
}
Esimerkki (JavaScript)
const API = 'https://api.usepolylingo.com/v1'
const headers = {
'Authorization': `Bearer ${process.env.POLYLINGO_API_KEY}`,
'Content-Type': 'application/json',
}
// 1. Lähetä
const submit = await fetch(`${API}/jobs`, {
method: 'POST',
headers,
body: JSON.stringify({ content: longMarkdown, format: 'markdown', targets: ['de', 'fr'] }),
})
const { job_id } = await submit.json()
// 2. Kysy
while (true) {
await new Promise(r => setTimeout(r, 10_000))
const poll = await fetch(`${API}/jobs/${job_id}`, { headers })
const job = await poll.json()
if (job.status === 'completed') { console.log(job.translations); break }
if (job.status === 'failed') { throw new Error(job.error) }
// Valinnainen: näytä eteneminen (queue_position on 1-pohjainen, jätetään pois jos ei jonossa)
if (job.queue_position != null) console.log(`Queue position: ${job.queue_position}`)
}
GET /usage
Vaatii Authorization: Bearer <api_key> (tavallinen avaimen haku — ei sisäinen ohituspolku).
Palauttaa token-käytön kuluvan kalenterikuukauden ajalta todennetulle käyttäjälle.
Vastaus 200
{
"period_start": "2025-03-01T00:00:00.000Z",
"period_end": "2025-03-31T23:59:59.000Z",
"tokens_used": 12000,
"tokens_included": 100000,
"tokens_remaining": 88000,
"overage_tokens": 0,
"tier": "free"
}
tokens_included ja tokens_remaining ovat null tasolla enterprise (rajoittamaton käyttö raportoinnissa).
Sisältöformaatit
Tuetut format-arvot: plain, markdown, json, html.
| Formaatti | Säilytetään | Käännetään |
|---|---|---|
plain | Rivinvaihdot / kappaleet | Kaikki näkyvä teksti |
markdown | Syntaksi, linkit (URL muuttumaton), koodilohkot (kirjaimellisesti) | Proosa ja linkkiteksti |
json | Avaimet, rakenne, ei-merkkijonotyyppiset arvot | Vain merkkijonojen arvot |
html | Tagit ja attribuutit | Tekstisolmut ja sopivat attribuutit (katso kehotteet) |
RTL ja suunta sovelluksessasi
plain- ja markdown-muodossa API palauttaa vain käännetyn tekstin — se ei lisää dir="rtl"-attribuuttia tai kääre-elementtejä. Aseta tekstin suunta käyttöliittymässäsi (CSS:n direction, vanhemman elementin dir-attribuutti tai kehyskirjastosi i18n-asettelu) kun näytät arabiaa, hepreaa tai persiaa.
html-muodossa käännetty merkintä voi sisältää dir="rtl"-attribuutin, kun se on sopivaa RTL-kohteille; katso formatPrompts.js ja HTML-testit tiedostossa scripts/test-translation.js.
Virhevastaukset
Virheet ovat JSON-muodossa, kun mahdollista:
{
"error": "invalid_request",
"message": "Ihmisen luettava yksityiskohta"
}
| HTTP | error | Milloin |
|---|---|---|
| 400 | invalid_request | Puuttuvat/virheelliset runkokentät (esim. tyhjä content, virheelliset targets) |
| 400 | invalid_format | format ei ole tuetuissa arvoissa |
| 400 | invalid_language | Tuntematon koodi targets-kentässä |
| 401 | invalid_api_key | Puuttuva/virheellinen Authorization, tuntematon avain, peruutettu avain |
| 403 | advanced_not_available | model: "advanced" ilmaisella tasolla |
| 429 | token_limit_reached | Kuukausittainen ilmainen raja ylittyisi (esitarkistus) |
| 429 | rate_limit_reached | Minuuttikohtainen RPM-raja (kun Redis käytössä) |
| 500 | translation_error | Malli/verkkovirhe; turvallista yrittää uudelleen |
| 404 | not_found | GET /jobs/:id — työ ei ole olemassa tai kuuluu toiselle käyttäjälle |
| 500 | server_error | POST /jobs — epäonnistui jonoon lisäämisessä; turvallista yrittää uudelleen |
GET /usage voi palauttaa 500 yleisellä viestillä, jos Supabase-kysely epäonnistuu.
Taustalla olevat mallit (tiedoksi)
API tarjoaa vain standard ja advanced. Todelliset OpenAI-mallien tunnisteet on määritelty tiedostossa api/utils/modelRouter.js eikä niitä palauteta API-vastauksissa.