Αναφορά API
Πλήρης αναφορά για κάθε endpoint, σχήμα αιτήματος και απόκρισης, κωδικό σφάλματος και όριο ρυθμού.
Όρια και συμπεριφορά
| Στοιχείο | Τιμή |
|---|---|
| Μέγεθος σώματος JSON | Έως 2 MB (express.json({ limit: '2mb' })) |
| Στόχοι ανά αίτημα | 1–50 κωδικοί γλωσσών |
| Αντικείμενα παρτίδας | 1–100 αντικείμενα ανά αίτημα παρτίδας |
| Μοντέλα | standard (προεπιλογή) ή advanced (μόνο επί πληρωμή; δείτε παρακάτω) |
Μηνιαίο όριο tokens (δωρεάν επίπεδο): Πριν από την κλήση του μοντέλου, το API εκτιμά τα tokens περίπου ως ceil(content_length / 4) × (number_of_targets + 1) και, μόνο για το free επίπεδο, απορρίπτει το αίτημα με 429 / token_limit_reached αν η εκτίμηση υπερβαίνει το υπόλοιπο μηνιαίο όριο (προεπιλογή 100000). Τα επί πληρωμή επίπεδα δεν μπλοκάρονται από αυτόν τον προέλεγχο· η χρήση καταγράφεται κανονικά.
Όρια ρυθμού: Όταν έχει ρυθμιστεί το Redis, εφαρμόζονται όρια ανά λεπτό ανά επίπεδο: δωρεάν 5, starter 30, growth 60, scale 120, enterprise απεριόριστο. Σε όριο, η απόκριση είναι 429 με error: "rate_limit_reached". Αν το Redis δεν έχει ρυθμιστεί, το όριο ρυθμού παραλείπεται.
Επιτυχείς απαντήσεις με όριο ρυθμού μπορεί να περιλαμβάνουν X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
GET /health
Χωρίς αυθεντικοποίηση.
Απάντηση 200
{
"status": "ok",
"timestamp": "2025-03-23T12:00:00.000Z"
}
GET /languages
Χωρίς αυθεντικοποίηση.
Επιστρέφει την κανονική λίστα υποστηριζόμενων γλωσσών (κωδικός, εμφανιζόμενο όνομα, σημαία RTL). Υπάρχουν 43 εγγραφές — 36 βασικές γλώσσες και 7 περιφερειακές παραλλαγές. Οι περιφερειακές παραλλαγές χρησιμοποιούν BCP-47 υποκωδικούς περιοχής (π.χ. fr-CA, pt-BR, es-MX). Οι κωδικοί από αυτό το endpoint είναι οι μόνοι αποδεκτοί τιμές στο targets στα endpoints μετάφρασης.
Απάντηση 200
{
"languages": [
{ "code": "en", "name": "English", "rtl": false },
{ "code": "ar", "name": "Arabic", "rtl": true }
]
}
Η ζωντανή λίστα είναι επίσης διαθέσιμη μέσω GET /languages — δείτε παρακάτω.
POST /translate
Απαιτεί Authorization: Bearer <api_key>.
Μεταφράζει ένα μόνο string content σε κάθε γλώσσα που αναφέρεται στο targets. Η απόκριση είναι ένα μοναδικό αντικείμενο JSON των οποίων τα κλειδιά είναι ακριβώς οι ζητούμενοι κωδικοί γλωσσών και οι τιμές οι μεταφρασμένες συμβολοσειρές.
Σώμα αιτήματος
| Πεδίο | Τύπος | Υποχρεωτικό | Περιγραφή |
|---|---|---|---|
content | string | Ναι | Μη κενή συμβολοσειρά προς μετάφραση. |
targets | string[] | Ναι | Μη κενός πίνακας έγκυρων κωδικών γλωσσών (μέγ. 36). |
format | string | Όχι | Ένα από plain, markdown, json, html. Αν παραληφθεί, το format ανιχνεύεται αυτόματα από το content. |
source | string | Όχι | Υπόδειξη γλώσσας πηγής για το μοντέλο; προαιρετικό. |
model | string | Όχι | standard (προεπιλογή) ή advanced. Το advanced απαιτεί επί πληρωμή επίπεδο (403 στο δωρεάν). |
Απάντηση 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 και το detection_confidence εμφανίζονται μόνο όταν το format παραλείπεται και εκτελείται αυτόματη ανίχνευση.
Παράδειγμα (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"]
}'
Παράδειγμα (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
Απαιτεί Authorization: Bearer <api_key>.
Επεξεργάζεται κάθε στοιχείο διαδοχικά (μία κλήση μοντέλου ανά στοιχείο). Αν κάποιο στοιχείο αποτύχει, το API επιστρέφει 500 και δεν επιστρέφει μερικά αποτελέσματα για το αίτημα.
Σώμα αιτήματος
| Πεδίο | Τύπος | Υποχρεωτικό | Περιγραφή |
|---|---|---|---|
items | array | Ναι | Κάθε στοιχείο: id (string), content (string), προαιρετικό format. |
targets | string[] | Ναι | Ίδιες κανόνες με /translate. |
source | string | Όχι | Προαιρετική υπόδειξη γλώσσας πηγής. |
model | string | Όχι | standard ή advanced (ίδιοι κανόνες με /translate). |
Απάντηση 200
{
"results": [
{ "id": "welcome", "translations": { "fr": "...", "de": "..." } },
{ "id": "goodbye", "translations": { "fr": "...", "de": "..." } }
],
"usage": {
"total_tokens": 900,
"input_tokens": 400,
"output_tokens": 500,
"model": "standard"
}
}
Παράδειγμα
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
Απαιτεί Authorization: Bearer <api_key>.
Τοποθετεί σε ουρά μια εργασία μετάφρασης και επιστρέφει αμέσως με job_id. Η μετάφραση εκτελείται στο παρασκήνιο — χωρίς κίνδυνο χρονικού ορίου HTTP ανεξάρτητα από το μέγεθος του περιεχομένου. Κάντε polling στο GET /jobs/:id για το αποτέλεσμα.
Χρησιμοποιήστε αυτό το endpoint αντί για POST /translate όταν μεταφράζετε μεγάλα έγγραφα (μεγάλο Markdown, πολλές γλώσσες στόχους) όπου η διάρκεια του αιτήματος μπορεί να υπερβεί το χρονικό όριο του HTTP client ή proxy.
Σώμα αιτήματος
| Πεδίο | Τύπος | Υποχρεωτικό | Περιγραφή |
|---|---|---|---|
content | string | Ναι | Μη κενή συμβολοσειρά προς μετάφραση. |
targets | string[] | Ναι | Μη κενός πίνακας έγκυρων κωδικών γλωσσών (μέγ. 36). |
format | string | Όχι | Ένα από plain, markdown, json, html. Ανιχνεύεται αυτόματα αν παραληφθεί. |
source | string | Όχι | Υπόδειξη γλώσσας πηγής; προαιρετικό. |
model | string | Όχι | standard (προεπιλογή) ή advanced. |
Απάντηση 202
{
"job_id": "a1b2c3d4-...",
"status": "pending",
"created_at": "2025-03-23T12:00:00.000Z"
}
GET /jobs/:id
Απαιτεί Authorization: Bearer <api_key>.
Κάνει polling στην κατάσταση μιας εργασίας που υποβλήθηκε μέσω POST /jobs. Κάντε polling κάθε 5–10 δευτερόλεπτα. Οι εργασίες ανήκουν στον χρήστη που τις υπέβαλε — άλλοι χρήστες λαμβάνουν 404.
Απάντηση (pending / processing)
{
"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 είναι pending (αναμονή για worker) ή processing (worker το έχει αναλάβει). Το queue_position (βάση 1) δείχνει πόσες εργασίες σε κατάσταση pending ή processing δημιουργήθηκαν αυστηρά πριν από αυτήν — χρησιμοποιήστε το για UI προόδου. Παραλείπεται αν η ερώτηση μέτρησης αποτύχει.
Απάντηση (completed)
{
"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"
}
}
Απάντηση (failed)
{
"job_id": "a1b2c3d4-...",
"status": "failed",
"error": "Model returned invalid JSON"
}
Παράδειγμα (JavaScript)
const API = 'https://api.usepolylingo.com/v1'
const headers = {
'Authorization': `Bearer ${process.env.POLYLINGO_API_KEY}`,
'Content-Type': 'application/json',
}
// 1. Υποβολή
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. Poll
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) }
// Προαιρετικό: εμφάνιση προόδου (queue_position είναι βάση 1, παραλείπεται αν δεν είναι σε ουρά)
if (job.queue_position != null) console.log(`Θέση στην ουρά: ${job.queue_position}`)
}
GET /usage
Απαιτεί Authorization: Bearer <api_key> (τυπικός έλεγχος κλειδιού — όχι εσωτερική παράκαμψη).
Επιστρέφει χρήση tokens για τον τρέχοντα ημερολογιακό μήνα για τον αυθεντικοποιημένο χρήστη.
Απάντηση 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 και tokens_remaining είναι null για enterprise (απεριόριστο όριο στην αναφορά).
Μορφές περιεχομένου
Υποστηριζόμενες τιμές format: plain, markdown, json, html.
| Μορφή | Διατηρείται | Μεταφράζεται |
|---|---|---|
plain | Διακοπές γραμμής / παράγραφοι | Όλο το ορατό κείμενο |
markdown | Σύνταξη, σύνδεσμοι (URL αμετάβλητο), fenced code (αυστηρά) | Κείμενο και κείμενο συνδέσμων |
json | Κλειδιά, δομή, μη-συμβολοσειρές τύποι | Μόνο τιμές συμβολοσειρών |
html | Ετικέτες και χαρακτηριστικά | Κείμενο και κατάλληλα χαρακτηριστικά (βλέπε prompts) |
RTL και κατεύθυνση στην εφαρμογή σας
Για plain και markdown έξοδο, το API επιστρέφει μόνο το μεταφρασμένο κείμενο — δεν προσθέτει dir="rtl" ή περιτυλιγμένα στοιχεία. Ορίστε την κατεύθυνση κειμένου στο UI σας (CSS direction, το dir χαρακτηριστικό γονικού στοιχείου ή το i18n layout του framework σας) όταν εμφανίζετε Αραβικά, Εβραϊκά ή Περσικά.
Για τη μορφή html, το μεταφρασμένο markup μπορεί να περιλαμβάνει dir="rtl" όπου είναι κατάλληλο για RTL στόχους.
Απαντήσεις σφαλμάτων
Τα σφάλματα είναι JSON όπου είναι δυνατόν:
{
"error": "invalid_request",
"message": "Ανθρώπινα αναγνώσιμη λεπτομέρεια"
}
| HTTP | error | Πότε |
|---|---|---|
| 400 | invalid_request | Ελλείποντα/μη έγκυρα πεδία σώματος (π.χ. κενό content, κακά targets) |
| 400 | invalid_format | format εκτός υποστηριζόμενου συνόλου |
| 400 | invalid_language | Άγνωστος κωδικός στο targets |
| 401 | invalid_api_key | Ελλείπον/λανθασμένο Authorization, άγνωστο κλειδί, ανακληθέν κλειδί |
| 403 | advanced_not_available | model: "advanced" στο δωρεάν επίπεδο |
| 429 | token_limit_reached | Υπέρβαση μηνιαίου ορίου δωρεάν επιπέδου (προέλεγχος) |
| 429 | rate_limit_reached | Όριο RPM ανά λεπτό (όταν ενεργό Redis) |
| 500 | translation_error | Σφάλμα μοντέλου/δικτύου; ασφαλές για επανάληψη |
| 404 | not_found | GET /jobs/:id — η εργασία δεν υπάρχει ή ανήκει σε άλλον χρήστη |
| 500 | server_error | POST /jobs — αποτυχία τοποθέτησης σε ουρά; ασφαλές για επανάληψη |
Το GET /usage μπορεί να επιστρέψει 500 με γενικό μήνυμα αν αποτύχει το ερώτημα Supabase.