> ## Documentation Index
> Fetch the complete documentation index at: https://docs.corsair.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Yandex Translate plugin

> Translation with Yandex Cloud - translate passages between languages, detect the language of text, and list the supported languages.

Use **Yandex Translate** through Corsair: one client, typed API calls.

This plugin wraps **Yandex Translate**, part of Yandex Cloud. Create a service account with the `ai.translate.user` role, then make an API key for it; the key goes in `Authorization: Api-Key`.

* **"Yandex" is a family, and this is the Translate API.** Yandex publishes many unrelated APIs (Metrica, Search, Cloud); this plugin covers the translator, at `https://translate.api.cloud.yandex.net`. The other services have their own credentials and contracts and are not part of this package.
* **Two credential kinds are accepted.** A service-account **API key** is sent as `Authorization: Api-Key <key>` and is long-lived, which is what a server integration wants. An **IAM token** is sent as `Bearer` and expires, so the plugin passes through a key that already names its scheme — write `Bearer …` explicitly to use one.
* **A folder scopes a cloud resource.** A service account's API key or IAM token already implies its folder, so leave `folderId` out with one. A user account's IAM token needs `folderId` on every call, even when the account reaches only one folder; the plugin sends it as the `folderId` body field, as the API reference documents.
* **Every call is a POST, including the reads.** `translate`, `detect` and `languages` all take a JSON body, which is unusual but what the gRPC-to-JSON mapping produces.
* **Errors are gRPC statuses, not HTTP ones.** The body is `{ code, message, details }` where `code` is a gRPC status — 3 is an invalid argument, 5 not found, 7 permission denied, 8 resource exhausted, 16 unauthenticated. The HTTP status follows the gRPC code (3 answers 400, 7 answers 403, 8 answers 429, 16 answers 401), and the plugin reads `code` itself, since it names the cause more precisely than the status. A bad key answers HTTP 401 with `16` and `Unknown api key '****'`.
* **The `requestId` is kept.** It sits inside the `details` array, and it is what Yandex support asks for.
* **10,000 characters per call, across 1,000 passages.** The plugin checks the total before sending, because the API's own refusal is a `3` that does not say which limit was hit.
* **Omitting `sourceLanguageCode` asks for detection.** Sending it empty would be an unknown language code, so the plugin leaves it out entirely when it is not set.
* **`format: HTML` preserves markup.** The default is `PLAIN_TEXT`, which treats tags as text to translate.
* **Text never reaches the event log.** Only the character count and the language codes are logged, since the passage is the caller's own content. A failed call's `YandexAPIError` keeps the underlying HTTP error as its `cause`, which includes the request body, so do not log error causes in full if the text is sensitive.

**What you get:**

* 3 typed API operations

## Setup

**1. Install**

```bash npm theme={null}
npm install corsair @corsair-dev/yandex better-sqlite3
npm install --save-dev @types/better-sqlite3
```

```bash yarn theme={null}
yarn add corsair @corsair-dev/yandex better-sqlite3
yarn add --dev @types/better-sqlite3
```

```bash pnpm theme={null}
pnpm install corsair @corsair-dev/yandex better-sqlite3
pnpm install --save-dev @types/better-sqlite3
```

```bash bun theme={null}
bun add corsair @corsair-dev/yandex better-sqlite3
bun add --dev @types/better-sqlite3
```

**2. Add the plugin**

```ts corsair.ts theme={null}
import Database from 'better-sqlite3';
import { createCorsair } from 'corsair';
import { yandex } from '@corsair-dev/yandex';

export const corsair = createCorsair({
	plugins: [
		yandex(),
	],
	database: new Database('corsair.db'),
	kek: process.env.CORSAIR_KEK!,
	multiTenancy: true,
	hub: {
		projectApiKey: process.env.CORSAIR_API_KEY!,
		signingSecret: process.env.CORSAIR_SIGNING_SECRET!,
	},
});
```

With `multiTenancy: true`, scope calls with `corsair.withTenant(id)`. See [Quick start](https://docs.corsair.dev/quick-start.md) for KEK + Hub keys, and [Multi-tenancy](https://docs.corsair.dev/concepts/multi-tenancy.md) for account isolation.

**3. Choose authentication**

> [tab] API Key (Recommended)
>
> No setup required yet. When you make your first request as a tenant, Corsair prompts for the API key.
>
> ```ts theme={null}
> yandex()
> ```
>
> More: [API Key](https://docs.corsair.dev/concepts/api-key)

**4. Connect a tenant**

Mint a connect link and send the tenant to it. Hub hosts the page and delivers the result to your app — see [Connect / OAuth](https://docs.corsair.dev/management/connect).

```ts theme={null}
const { connectUrl } = await corsair.manage.connect.createLink({
	plugin: 'yandex',
	tenantId: 'acme',
});
// redirect the user's browser to connectUrl
```

## Example API calls

**List the supported languages**

```ts theme={null}
const tenant = corsair.withTenant('acme');
await tenant.yandex.api.listLanguages.run({});
```

**Translate into Russian**

```ts theme={null}
const tenant = corsair.withTenant('acme');
await tenant.yandex.api.translate.text({
	targetLanguageCode: 'ru',
	texts: ['Hello'],
});
```

See the full list on the [API](https://docs.corsair.dev/plugins/yandex/api.md) page.

## What's next

> [card] [API reference](https://docs.corsair.dev/plugins/yandex/api.md)
>
> Every `yandex.api.*` operation with input and output types.

> [card] [Connect / OAuth](https://docs.corsair.dev/management/connect)
>
> createLink, Hub delivery, and tenant connect flows.

> [card] [Use with agents](https://docs.corsair.dev/mcp-adapters/mcp-adapters)
>
> Expose this plugin's operations as MCP tools.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.