npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

otranslator-cli

v0.1.2

Published

Unofficial TypeScript SDK and CLI for the OTranslator API — AI document/text translation for 50+ formats and 100+ languages

Readme

otranslator-cli

npm version Downloads CI Node License: MIT TypeScript

Unofficial Node.js SDK and CLI for the OTranslator API. Document, subtitle, audio, and plain text translation across 100+ languages with the original layout preserved.

Not affiliated with OTranslator. Reverse-engineered from the public developer docs at https://otranslator.com/en/developer and verified against the live API. Every endpoint, request shape, and response shape documented here was exercised by the e2e suite under test/e2e/ on 2026-05-03.

First run

npm install -g otranslator-cli   # adds `otcli` to your $PATH
otcli login                      # interactive prompt, validates against /v1/me
otcli whoami                     # → { "source": "config", "balance": <credits> }
otcli translate "Hello, world." --from English --to Spanish

Prefer not to install globally? npx otranslator-cli <command> works the same.

Install

npm install otranslator-cli      # as a dependency in your project
# or
npm install -g otranslator-cli   # as a system-wide CLI

The npm package is otranslator-cli. It installs a single CLI binary on your $PATH called otcli. All examples in this README use otcli.

Node 20+ required. The SDK uses built-in fetch, FormData, and File, so it also works in browsers without polyfills.

How translation works

OTranslator follows a preview-then-pay model. You upload a document, the API generates a free preview of roughly the first 2,000 words, and only when you're happy with the preview do you pay credits to translate the rest.

The full flow:

  1. createTask uploads the file. Set preview: true for a sample, or preview: false to translate everything immediately (deducts credits up front).
  2. queryTask returns status, progress, and — once CompletedtranslatedFileUrl plus a price field showing what a full translation would cost.
  3. restartTask with payWithCredits: true and a model from one of the paid tiers converts the preview into a full translation.

Free preview credits replenish whenever you complete a paid full translation, so the cost model rewards finishing what you start.

Model tiers

The product UI groups the eleven models from /v1/models into three tiers. Pricing applies to document full translation (the restartTask step). Synchronous translateTexts costs 2 credits regardless of tier — at least on the short strings we measured.

  • Basic: gpt-5-mini, claude-4.5-haiku, gemini-3.1-flash, deepseek-3.2
  • Advanced: gpt-5.4, claude-4.6-sonnet, gemini-3.1-pro, deepseek-3.2-thinking
  • Inference / Thinking: gpt-5.4-thinking, claude-4.6-sonnet-thinking, gemini-3.1-thinking

The API takes a raw model id — the SDK doesn't gate which tier you can use. Run node --env-file=.env --import tsx scripts/verify-models.ts to probe one model per tier and see live credit costs.

Authentication

Three ways to provide your key, resolved in this order:

  1. --api-key <key> flag on any command
  2. OTRANSLATOR_API_KEY environment variable
  3. The stored config file written by otcli login at ~/.config/otranslator-cli/config.json (mode 0600)

The interactive flow mirrors gh, stripe, vercel, and friends:

otcli login         # prompts for the key, hides echo, validates against /v1/me, persists on success
otcli whoami        # shows which source the active key comes from + current balance
otcli logout        # deletes the stored config file

whoami is also handy when handing the CLI to another agent — it confirms the key is wired up before any real work starts.

CLI quick start

otcli login                  # one-time setup; or `export OTRANSLATOR_API_KEY=sk-…`

# Discover the surface
otcli filetypes
otcli languages
otcli models
otcli me                     # → { "balance": 421 }

# Synchronous text translation
otcli translate "Hello, world." --from English --to Spanish

# Document workflow — preview → wait → download
otcli create -f contract.pdf --from English --to French --preview
otcli wait <taskId>                              # blocks until Completed
otcli download <taskId> -o translated.pdf        # writes the file to disk

# Or in one chained call
TASK=$(otcli create -f contract.pdf --from English --to French --preview | jq -r .taskId)
otcli download "$TASK" --wait -o translated.pdf

# Pay credits to convert a preview into a full document translation
otcli start <taskId> --pay-with-credits --model gpt-5.4

Every command prints JSON to stdout and exits non-zero on failure with the API's error body on stderr. Pipe into jq to filter, or chain commands together.

SDK quick start

import { OTranslatorClient } from 'otranslator-cli';
import { readFile, writeFile } from 'node:fs/promises';

const client = new OTranslatorClient({
  apiKey: process.env.OTRANSLATOR_API_KEY!,
});

// Upload, get a preview, wait for completion
const buffer = await readFile('contract.pdf');
const file = new File([buffer], 'contract.pdf');

const { taskId } = await client.createTask({
  file,
  fromLang: 'English',
  toLang: 'French',
  preview: true,
});

// Wait for the preview to finish, then download it
const task = await client.waitForTask(taskId);
const { blob, filename } = await client.downloadTranslated(taskId);
await writeFile(filename, Buffer.from(await blob.arrayBuffer()));
console.log(`saved ${filename} — costs ${task.price} credits to convert to a full translation`);

// Convert preview → full translation
if (task.price !== undefined) {
  await client.restartTask({ taskId, payWithCredits: true, model: 'gpt-5.4' });
}

What's covered

15 raw endpoints (one SDK method each, all exercised against the live API) plus two composed helpers — waitForTask and downloadTranslated — that turn the preview-then-pay flow into one call each.

| SDK method | HTTP | Notes | | ---------------- | ------------------------------------- | -------------------------------------------------------------------------------------------- | | createTask | POST /v1/translation/create | multipart/form-data. Returns { taskId }. | | queryTask | POST /v1/translation/query | Returns the full task object — status, progress, file URLs, credit costs, model used. | | deleteTask | POST /v1/translation/delete | Returns { success: true }. | | restartTask | POST /v1/translation/start | { taskId, payWithCredits?, model? }{ success: true }. | | queryTexts | POST /v1/translation/queryTexts | Returns { texts: { [src]: tgt }, revisedTexts: { [src]: tgt } }. Source string is the key. | | updateTexts | POST /v1/translation/updateTexts | Submit a { [sourceSegment]: revisedTranslation } map. Returns { success: true }. | | translateTexts | POST /v1/translation/translateTexts | Synchronous. Returns { translatedTexts, price, usedCredits }. | | createGlossary | POST /v1/glossary/create | Returns { glossaryId }. | | queryGlossary | POST /v1/glossary/query | SDK parses keys and translated from JSON-encoded strings to native types. | | updateGlossary | POST /v1/glossary/update | Same parsing as queryGlossary. | | deleteGlossary | POST /v1/glossary/delete | Returns { success: true }. | | filetypes | POST /v1/filetypes | 60+ formats: pdf, docx, epub, srt, mp3, cbz, etc. | | languages | POST /v1/languages | 80+ languages including Any Language as a wildcard. | | models | POST /v1/models | Returns 11 model ids (see Model tiers above). | | me | POST /v1/me | Returns { balance: number } — credit balance and nothing else. |

Composed helpers (no extra endpoints — built on top of the rows above):

| SDK method | What it does | | -------------------- | ------------------------------------------------------------------------------------------------------------------------ | | waitForTask | Polls queryTask until Completed / Terminated / Cancelled. Configurable intervalMs and maxMs. | | downloadTranslated | Queries the task, fetches the pre-signed GCS URL, returns { blob, filename, contentType, task }. Supports bilingual. |

For full request and response shapes, look at the generated TypeScript types in dist/index.d.ts or open openapi.json.

Behavioural notes from real responses

A few things worth flagging because the official docs don't mention them:

  • Auth. The Authorization header takes the raw secret key. No Bearer prefix. This is the single most common stumbling block when porting from another translation API.
  • Preview is normally free. Each account ships with a pool of free preview credits, and the pool refills every time you complete a paid full translation. The 2-credit cost the docs mention only kicks in after the pool runs out.
  • Glossary keys and translated are doubly encoded on the wire. Both fields are sent as JSON-encoded strings inside the JSON request body, and they come back the same way. The SDK encodes on the way out and parses on the way in, so your code works with native arrays and objects.
  • TranslationTask returns more fields than documented. fileTitle, fileUrl, wordNums, forceOCR, and an errorMsg that may be null are all present. The SDK types include them.
  • Default model. When createTask omits model, the server picks gpt-4.1-mini for previews. That id is not in the /v1/models list, so don't hard-code your model lookups against it.
  • Status transitions. The state machine we observed: Waiting → Processing → Completed. Terminated and Cancelled exist in the type but only show up on errors or explicit deletes.

Configuration

| Env var | CLI flag | Default | | ------------------------ | ------------ | ----------------------------- | | OTRANSLATOR_API_KEY | --api-key | (required) | | OTRANSLATOR_BASE_URL | --base-url | https://otranslator.com/api | | OTRANSLATOR_TIMEOUT_MS | --timeout | 60000 |

Tests

Two suites.

npm test runs unit tests with a mocked fetch. Fast, no network, no key needed.

npm run test:e2e hits the real API. It loads OTRANSLATOR_API_KEY from .env via dotenv and auto-skips when the key is missing. The default e2e suite is free to run. It covers languages, filetypes, models, me, and the full glossary create-query-update-delete lifecycle.

The paid suite is opt-in:

npm run test:e2e:paid

That run exercises translateTexts, createTask in preview mode against test/fixtures/sample.md, queryTask polling, queryTexts, updateTexts, restartTask with payWithCredits: true, and deleteTask cleanup. With the bundled 351-byte fixture it costs around 2 credits per run because price for the doc itself is 0. To test against a larger document, point at it:

OTRANSLATOR_E2E_FIXTURE="/path/to/your/document.md" npm run test:e2e:paid

The e2e tests also log every response we found undocumented (/me, /models, /glossary/query, /translation/queryTexts, etc.) so future API changes show up as test diffs.

Errors

The SDK throws OTranslatorError for everything that isn't a 2xx with a JSON body. Inspect code to branch:

import { OTranslatorError } from 'otranslator-cli/errors';

try {
  await client.me();
} catch (err) {
  if (err instanceof OTranslatorError && err.code === 'HTTP_ERROR' && err.status === 401) {
    // bad API key — re-prompt the user
  }
  throw err;
}

code values: MISSING_API_KEY, INVALID_INPUT, NETWORK_ERROR, TIMEOUT, HTTP_ERROR, INVALID_RESPONSE.

Development

npm install
npm run typecheck
npm test
npm run build      # tsup → dist/ (ESM + CJS + .d.ts)

Run the CLI against the source directly without rebuilding:

npm run cli -- task <taskId>

Releasing

The first publish is manual and does not include provenance — OIDC tokens can only be minted inside GitHub Actions, not on a laptop. Every subsequent release is published from CI on tag push, with provenance signed against the source commit.

# One-time first publish
npm login
npm publish --access public

# Then on https://www.npmjs.com/package/otranslator-cli →
#   Settings → Trusted Publishers → Add Publisher
#   - Repository: mrkhachaturov/otranslator-cli
#   - Workflow:   publish.yml
#   - Environment: (leave blank)

# Subsequent releases
# 1. Bump version in package.json
# 2. Add a new [X.Y.Z] - <date> heading in CHANGELOG.md (move items from
#    [Unreleased]). Keep a Changelog format.
# 3. Commit, tag, push
git commit -am 'release: v0.1.1'
git tag v0.1.1
git push --follow-tags
# Actions publishes to npm with provenance and creates a GitHub Release whose
# body is the matching CHANGELOG section.

Verifying provenance

Once a release is published from CI, anyone can verify the build trail:

# Visual: https://www.npmjs.com/package/otranslator-cli shows a Provenance badge
# Programmatic:
npm view otranslator-cli --json | jq '.dist.attestations'
npm install otranslator-cli && npm audit signatures

Cryptographic verification independent of npm uses Sigstore's transparency log — see https://search.sigstore.dev for the public Rekor entries.

License

MIT. See LICENSE.