API রেফারেন্স
এই ডকুমেন্টটি Express অ্যাপের আচরণের সাথে মেলে যা api/app.js এবং রুট হ্যান্ডলারগুলি api/routes/ এর অধীনে।
সীমা এবং আচরণ
| আইটেম | মান |
|---|---|
| JSON বডির আকার | সর্বোচ্চ 2 এমবি (express.json({ limit: '2mb' })) |
| প্রতি অনুরোধ লক্ষ্য | 1–36 ভাষার কোড |
| ব্যাচ আইটেম | প্রতি ব্যাচ অনুরোধে 1–100 আইটেম |
| মডেল | standard (ডিফল্ট) অথবা advanced (শুধুমাত্র পেইড টিয়ার; নিচে দেখুন) |
মাসিক টোকেন বরাদ্দ (ফ্রি টিয়ার): মডেল কল করার আগে, API আনুমানিক টোকেন হিসাব করে ceil(content_length / 4) × (number_of_targets + 1) এবং শুধুমাত্র free টিয়ারের জন্য, যদি অনুমান বাকি মাসিক বরাদ্দ (FREE_TIER_MONTHLY_TOKENS, ডিফল্ট 100000) ছাড়িয়ে যায় তাহলে 429 / token_limit_reached দিয়ে অনুরোধ প্রত্যাখ্যান করে। পেইড টিয়ারগুলি এই প্রি-চেক দ্বারা ব্লক হয় না enforceTokenCap; ব্যবহার এখনও লগ হয়।
রেট লিমিট: যখন Upstash Redis কনফিগার করা থাকে (UPSTASH_REDIS_REST_URL / UPSTASH_REDIS_REST_TOKEN, এবং URL-এ প্লেসহোল্ডার your-instance নেই), প্রতি মিনিটের সীমা টিয়ার অনুযায়ী প্রযোজ্য: ফ্রি 5, স্টার্টার 30, গ্রোথ 60, স্কেল 120, এন্টারপ্রাইজ সীমাহীন। সীমা পৌঁছালে, রেসপন্স হয় 429 এবং error: "rate_limit_reached"। যদি Redis কনফিগার না করা থাকে, রেট লিমিটিং বাদ দেওয়া হয় (দেখুন rateLimit.js)।
সফল রেট-লিমিটেড রেসপন্সে থাকতে পারে X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset।
GET /health
কোনো প্রমাণীকরণ নেই।
রেসপন্স 200
{
"status": "ok",
"timestamp": "2025-03-23T12:00:00.000Z"
}
GET /languages
কোনো প্রমাণীকরণ নেই।
সমর্থিত ভাষাগুলির ক্যানোনিকাল তালিকা (কোড, প্রদর্শন নাম, RTL ফ্ল্যাগ) ফেরত দেয়। মোট 36 এন্ট্রি আছে; কোডগুলোই targets এ অনুবাদ এন্ডপয়েন্টে গ্রহণযোগ্য একমাত্র মান।
রেসপন্স 200
{
"languages": [
{ "code": "en", "name": "English", "rtl": false },
{ "code": "ar", "name": "Arabic", "rtl": true }
]
}
উৎস: api/utils/languages.js।
POST /translate
প্রয়োজন Authorization: Bearer <api_key>।
একটি content স্ট্রিংকে targets এ তালিকাভুক্ত প্রতিটি ভাষায় অনুবাদ করে। মডেল একটি একক JSON অবজেক্ট রিটার্ন করে যার কী গুলো ঠিক অনুরোধকৃত ভাষার কোড এবং মানগুলো অনূদিত স্ট্রিং (দেখুন formatPrompts.js)।
অনুরোধ বডি
| ফিল্ড | টাইপ | প্রয়োজনীয় | বর্ণনা |
|---|---|---|---|
content | স্ট্রিং | হ্যাঁ | অনুবাদের জন্য খালি নয় এমন স্ট্রিং। |
targets | স্ট্রিং[] | হ্যাঁ | বৈধ ভাষার কোডের খালি নয় এমন অ্যারে (সর্বোচ্চ 36)। |
format | স্ট্রিং | না | plain, markdown, json, html এর মধ্যে একটি। বাদ দিলে, content থেকে স্বয়ংক্রিয় সনাক্তকরণ হয়। |
source | স্ট্রিং | না | মডেলের জন্য উৎস ভাষার ইঙ্গিত; ঐচ্ছিক। |
model | স্ট্রিং | না | 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 | অ্যারে | হ্যাঁ | প্রতিটি উপাদান: id (স্ট্রিং), content (স্ট্রিং), ঐচ্ছিক format। |
targets | স্ট্রিং[] | হ্যাঁ | /translate এর মতো নিয়ম। |
source | স্ট্রিং | না | ঐচ্ছিক উৎস ভাষার ইঙ্গিত। |
model | স্ট্রিং | না | 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 টাইমআউটের ঝুঁকি নেই। ফলাফল পেতে GET /jobs/:id পোল করুন।
বড় ডকুমেন্ট (দীর্ঘ Markdown, অনেক লক্ষ্য ভাষা) অনুবাদের জন্য এই এন্ডপয়েন্ট ব্যবহার করুন যেখানে অনুরোধের সময়কাল আপনার HTTP ক্লায়েন্ট বা প্রক্সি টাইমআউট ছাড়িয়ে যেতে পারে।
অনুরোধ বডি
| ফিল্ড | টাইপ | প্রয়োজনীয় | বর্ণনা |
|---|---|---|---|
content | স্ট্রিং | হ্যাঁ | অনুবাদের জন্য খালি নয় এমন স্ট্রিং। |
targets | স্ট্রিং[] | হ্যাঁ | বৈধ ভাষার কোডের খালি নয় এমন অ্যারে (সর্বোচ্চ 36)। |
format | স্ট্রিং | না | plain, markdown, json, html এর মধ্যে একটি। বাদ দিলে স্বয়ংক্রিয় সনাক্তকরণ। |
source | স্ট্রিং | না | উৎস ভাষার ইঙ্গিত; ঐচ্ছিক। |
model | স্ট্রিং | না | standard (ডিফল্ট) অথবা advanced |
রেসপন্স 202
{
"job_id": "a1b2c3d4-...",
"status": "pending",
"created_at": "2025-03-23T12:00:00.000Z"
}
GET /jobs/:id
প্রয়োজন Authorization: Bearer <api_key>।
POST /jobs এর মাধ্যমে জমা দেওয়া কাজের অবস্থা পোল করে। প্রতি 5–10 সেকেন্ডে পোল করুন। কাজগুলো জমা দেওয়া ব্যবহারকারীর মালিকানাধীন — অন্য ব্যবহারকারীরা 404 পায়।
রেসপন্স (পেন্ডিং / প্রসেসিং)
{
"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 (ওয়ার্কার অপেক্ষায়) অথবা processing (ওয়ার্কার গ্রহণ করেছে)। queue_position (১-ভিত্তিক) কতগুলো পেন্ডিং বা প্রসেসিং কাজ এইটির আগে তৈরি হয়েছে তা নির্দেশ করে — প্রগ্রেস UI এর জন্য ব্যবহার করুন। গণনা কোয়েরি ব্যর্থ হলে বাদ দেওয়া হয়।
রেসপন্স (সম্পন্ন)
{
"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"
}
}
রেসপন্স (ব্যর্থ)
{
"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. পোল
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 ১-ভিত্তিক, কিউ না থাকলে বাদ দেওয়া হয়)
if (job.queue_position != null) console.log(`Queue position: ${job.queue_position}`)
}
GET /usage
প্রয়োজন Authorization: Bearer <api_key> (স্ট্যান্ডার্ড কী লুকআপ — অভ্যন্তরীণ বাইপাস-শুধু পথ নয়)।
প্রমাণীকৃত ব্যবহারকারীর জন্য বর্তমান ক্যালেন্ডার মাসের টোকেন ব্যবহার ফেরত দেয়।
রেসপন্স 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 enterprise এর জন্য null (রিপোর্টিং-এ সীমাহীন বরাদ্দ)।
কন্টেন্ট ফরম্যাট
সমর্থিত format মান: plain, markdown, json, html।
| ফরম্যাট | সংরক্ষিত | অনূদিত |
|---|---|---|
plain | লাইন ব্রেক / প্যারাগ্রাফ | সব দৃশ্যমান টেক্সট |
markdown | সিনট্যাক্স, লিঙ্ক (URL অপরিবর্তিত), ফেন্সড কোড (অক্ষরশব্দ) | গদ্য এবং লিঙ্ক টেক্সট |
json | কী, স্ট্রাকচার, নন-স্ট্রিং টাইপ | শুধুমাত্র স্ট্রিং মান |
html | ট্যাগ এবং অ্যাট্রিবিউট | টেক্সট নোড এবং উপযুক্ত অ্যাট্রিবিউট (দেখুন প্রম্পট) |
RTL এবং আপনার অ্যাপে দিকনির্দেশ
plain এবং markdown আউটপুটের জন্য, API শুধুমাত্র অনূদিত টেক্সট ফেরত দেয় — এটি dir="rtl" বা র্যাপার উপাদান যোগ করে না। আরবি, হিব্রু বা ফার্সি প্রদর্শনের সময় আপনার UI-তে টেক্সট দিকনির্দেশ (CSS direction, প্যারেন্ট উপাদানের dir অ্যাট্রিবিউট, অথবা আপনার ফ্রেমওয়ার্কের i18n লেআউট) সেট করুন।
html ফরম্যাটের জন্য, অনূদিত মার্কআপে প্রয়োজনীয় ক্ষেত্রে RTL লক্ষ্যের জন্য dir="rtl" থাকতে পারে; দেখুন formatPrompts.js এবং HTML টেস্টগুলি scripts/test-translation.js।
ত্রুটি প্রতিক্রিয়া
সম্ভব হলে ত্রুটিগুলো 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 কোয়েরি ব্যর্থ হয়।
অন্তর্নিহিত মডেল (তথ্যগত)
API শুধুমাত্র standard এবং advanced প্রকাশ করে। প্রকৃত OpenAI মডেল আইডি গুলো api/utils/modelRouter.js এ কনফিগার করা হয় এবং API রেসপন্সে ফেরত দেওয়া হয় না।