Node.js SDK (polylingo)

Official TypeScript client for the PolyLingo REST API. It uses the runtime fetch (Node.js 18+), ships as ESM and CJS, and has no runtime dependencies beyond Node.

For raw HTTP details, see API reference.


Installation

npm install polylingo

Node.js: >= 18


Constructor

import PolyLingo from 'polylingo'

const client = new PolyLingo({
  apiKey: process.env.POLYLINGO_API_KEY!, // required
  baseURL: 'https://api.usepolylingo.com/v1', // optional; this is the default
  timeout: 120_000, // optional; request timeout in milliseconds (default 120_000)
})
OptionTypeRequiredDescription
apiKeystringYesAPI key (Authorization: Bearer …).
baseURLstringNoAPI prefix including /v1. Default https://api.usepolylingo.com/v1.
timeoutnumberNoPer-request timeout in ms. Default 120_000.

Methods

client.health()

GET /health. No auth required on the server; the client still sends the Authorization header if configured.

Returns { status, timestamp }.

const h = await client.health()

client.languages()

GET /languages. Returns the supported language list.

const { languages } = await client.languages()

client.translate(params)

POST /translate

const r = await client.translate({
  content: '# Hello',
  targets: ['es', 'fr'],
  format: 'markdown', // optional; omit to let the API auto-detect
  source: 'en',       // optional hint
  model: 'standard',  // optional: 'standard' | 'advanced'
})

r.translations.es // string
r.usage.total_tokens
r.usage.input_tokens
r.usage.output_tokens

client.batch(params)

POST /translate/batch

const b = await client.batch({
  items: [
    { id: 'a', content: 'Hello' },
    { id: 'b', content: '## Title', format: 'markdown' },
  ],
  targets: ['de'],
  source: 'en',    // optional
  model: 'standard', // optional
})

b.results[0].translations.de
b.usage.total_tokens

client.usage()

GET /usage. Returns plan usage for the authenticated key.

const u = await client.usage()

Jobs (client.jobs)

client.jobs.create(params)

POST /jobs. Enqueues async work and resolves with the 202 JSON body (job_id, status, created_at, …).

const job = await client.jobs.create({
  content: longMarkdown,
  targets: ['de', 'fr'],
  format: 'markdown',
})
console.log(job.job_id)

client.jobs.get(jobId)

GET /jobs/:id. Polls status. When status === 'completed', the API returns translations and usage at the top level of the JSON object (not nested under result).

const status = await client.jobs.get(job.job_id)

client.jobs.translate(params) (convenience)

Submits a job, then polls until completed or failed, or until the timeout is reached.

const done = await client.jobs.translate({
  content: longMarkdown,
  targets: ['de', 'fr', 'es'],
  format: 'markdown',
  pollInterval: 10_000, // ms between polls; default 5_000
  timeout: 600_000,     // **total** ms budget for polling; default 20 minutes
  onProgress: (pos) => console.log(`Queue position: ${pos}`), // optional; called while queued/processing
})

done.translations.de
done.usage.total_tokens

Job lifecycle on the API uses statuses pending, processing, completed, and failed.


Error handling

All failures from the SDK (except bugs) extend PolyLingoError:

ClassWhen
PolyLingoErrorBase. Has status, error (API code string), message.
AuthErrorHTTP 401.
RateLimitErrorHTTP 429. Optional retryAfter (seconds) from JSON retry_after or Retry-After header.
JobFailedErrorPolling helper: job status === 'failed', or missing result on completed, or polling timeout. Has jobId.
import PolyLingo, {
  PolyLingoError,
  AuthError,
  RateLimitError,
  JobFailedError,
} from 'polylingo'

try {
  await client.translate({ content: 'Hi', targets: ['es'] })
} catch (e) {
  if (e instanceof AuthError) { /* invalid key */ }
  else if (e instanceof RateLimitError) { /* e.retryAfter */ }
  else if (e instanceof JobFailedError) { /* e.jobId */ }
  else if (e instanceof PolyLingoError) { /* e.status, e.error */ }
}

Async jobs pattern (summary)

  1. Fire-and-forget polling: jobs.create → your worker calls jobs.get on an interval until completed or failed.
  2. Built-in polling: jobs.translate. Same semantics, with pollInterval, timeout, and onProgress.

Large payloads and long-running translations should prefer jobs over synchronous translate to avoid HTTP timeouts.


TypeScript

The package exports types for options, results, and errors. Import named types from polylingo as needed (see published dist/index.d.ts).


Changelog

0.1.2

  • Maintenance: default API base URL is https://api.usepolylingo.com/v1.

0.1.0

  • Initial release: health, languages, translate, batch, usage, jobs.create, jobs.get, jobs.translate.
<!-- i18n workflow trigger bump -->
Node.js SDK | PolyLingo docs | PolyLingo