---
title: "Public API content"
description: "Translate selected public API fields through published lookups and budgeted server jobs."
canonical_url: "https://docs.linguana.dev/docs/reference/runtime-content"
markdown_url: "https://docs.linguana.dev/docs/reference/runtime-content.md"
x_farming_labs_generated_preamble: true
agent:
  task: "Localize explicitly selected public API text."
  outcome: "Browser reads published entries; server enqueues within owner-authorized limits."
  prerequisites:
    - "A runtime surface, environment-scoped token, and publishable key."
  files:
    - "The application locale integration and selected public API field allowlist."
  verification:
    - "A miss keeps source text, saving does not publish, and rollback restores the previous release."
  rollback:
    - "Keep the current release and use original source fallback."
  failureModes:
    - symptom: "A translation is missing."
      resolution: "Inspect the saved version and release; keep source text visible. Do not publish without explicit authorization."
---

# Public API content
URL: /docs/reference/runtime-content
LLM index: /llms.txt
Description: Translate selected public API fields through published lookups and budgeted server jobs.

<!-- farming-labs:agent-contract:start -->
## Agent Contract

Task: Localize explicitly selected public API text.
Outcome: Browser reads published entries; server enqueues within owner-authorized limits.

### Prerequisites

- A runtime surface, environment-scoped token, and publishable key.

### Files

- `The application locale integration and selected public API field allowlist.`

### Verification

- A miss keeps source text, saving does not publish, and rollback restores the previous release.

### Rollback

- Keep the current release and use original source fallback.

### Failure Modes

- A translation is missing. — Recovery: Inspect the saved version and release; keep source text visible. Do not publish without explicit authorization.
<!-- farming-labs:agent-contract:end -->

# Public API content

Use runtime content for public product titles, descriptions, and CMS text that does not exist at build time. Static interface copy continues through the compiler. Private customer messages and account-specific text are not supported: a publishable key is a public read credential.

## Create a surface

In **API content**, create a surface such as `products`. Select an environment. An owner can enable paid work with a monthly surface budget and a maximum charge per request. The organization cap also applies. Automatic provisional publication is a separate setting available to owners and admins and is off by default.

The server rollout flag `RUNTIME_TRANSLATION_ENABLED` defaults to `false`. Enable it only after migrating the database, deploying the worker, and passing the runtime verification checks. Published lookups do not require this flag.

## Server integration

Keep the project token on your server. Use an enabled target locale and the same surface, source locale, source text, format, and meaning note on both sides.

```ts
import { createRuntimeServerClient } from "@linguanahq/core/server";

const server = createRuntimeServerClient({
  endpoint: "https://api.linguana.dev",
  projectId: "your-project-id",
  environment: "production",
  surface: "products",
  sourceLocale: "en",
  locale: "de",
  token: process.env.LINGUANA_PROJECT_TOKEN!,
});

const items = [
  { source: product.title, meaning: "Product title" },
  { source: product.description },
];
const estimate = await server.estimateBatch(items);
const queued = await server.enqueueBatch(items, {
  idempotencyKey: `product-${product.id}-${product.version}-de`,
  waitForPublishedMs: 0,
});
```

The server token authorizes lookup, estimates, and enqueue; a publishable key is optional on the server. `RuntimeRequestError` exposes `code`, HTTP `status`, and a `budget_blocked` or `failed` state. Enqueue records an estimate and uses the owner's existing surface authorization. Exact compatible memory matches make no model call and create no charge. A cache miss, cap failure, or provider failure leaves source text available. `waitForPublishedMs` is opt-in and capped at two seconds; completion of generation does not imply publication.

## Browser integration

```ts
import { createRuntimeClient } from "@linguanahq/core/runtime";
import { useRuntimeContent } from "@linguanahq/react";

const client = createRuntimeClient({
  endpoint: "https://api.linguana.dev",
  projectId: "your-project-id",
  environment: "production",
  surface: "products",
  sourceLocale: "en",
  locale: "de",
  publishableKey: "your-publishable-key",
});

function Product({ product }) {
  const { value, fields } = useRuntimeContent(client, product, [
    { field: "title", meaning: "Product title" },
    "description",
  ]);
  return <article><h2>{value.title}</h2><p>{value.description}</p></article>;
}
```

Create a browser client once per scope and dispose it on unmount. `localize` synchronously returns `{ value, fields }`, initially using source text, and schedules one batch lookup. It copies the object and changes only selected top-level string properties. Empty or non-string fields are skipped with a diagnostic. IDs, prices, emails, and unselected fields remain untouched. Browser clients never enqueue translation work.

React and TanStack Start use `useRuntimeContent(client, value, fields)`. Vue uses `useRuntimeContent(client, () => value, fields)`, returning a computed ref. Solid uses the same accessor signature and returns a memo. Svelte uses `runtimeContent(client, value, fields)`, returning a readable store; recreate the store when its input object changes.

`lookupBatch(items, { force?, signal? })` resolves published entries. `setLocale(locale)` clears locale-scoped cache state and aborts pending reads. `refresh()` invalidates freshness and resets bounded polling. `subscribe(listener)` returns an unsubscribe function. `dispose()` aborts requests and clears subscriptions.

Plain text is the default. Braces and tags remain literal characters; render them as text, never with an HTML injection API. Use `{ source, format: "icu", meaning }` only for actual ICU messages. Runtime lookup returns the translated ICU message template; interpolate values locally through an ICU formatter. No user values need to be sent to Linguana.

## Hydration and delivery

On the server, call `lookupBatch` for already published content and serialize `client.hydrate()` through your framework's safe serialization mechanism. Pass that value as `hydrationState` to the browser client. Each SSR request must create its own client. Do not share locale state between users.

Limits are 50 items, 12,000 source code points, and 256 KiB per request. The SDK caches up to 1,000 entries, refreshes successful reads after 60 seconds, and caches misses for five seconds. Browser miss polling stops after 30 seconds. Failed refresh retains matching published wording. A successful missing response returns to source.

## Review and publication

Generated entries are provisional. Saving a reviewed correction creates a version; it does not publish. Publish the saved version with a reason. Context and glossary replacements also remain drafts until explicitly published. Automatic publication fills previously unpublished entries only and cannot replace a human correction.

Release history records actor, reason, policy version, and immutable translation references. Restoring a release creates a new release and pauses automatic publication for that surface/environment. An owner or admin must explicitly resume it.

## HTTP endpoints

All paths are under `/api/v1`. Mutation requests require `Idempotency-Key`.

| Method and path | Authorization | Purpose |
| --- | --- | --- |
| `POST /runtime/lookup` | `X-Linguana-Key` | Published text only |
| `POST /runtime/estimate` | Bearer project token | Estimate new work |
| `POST /runtime/enqueue` | Bearer project token | Reserve and durably queue work |
| `GET /jobs/:id` | Existing scoped job authorization | Inspect job progress |
| `GET /runtime/projects/:project/content?environment=production` | Project viewer | Dashboard content, jobs, policies, releases |
| `POST /runtime/projects/:project/policy` | Owner or admin; owner for budget changes | Append policy version |
| `POST /runtime/projects/:project/review/:translation` | Editor | Save reviewed wording |
| `POST /runtime/projects/:project/releases` | Publish permission | Publish or restore a release |

Lookup, estimate, and enqueue accept `{ projectId, environment, surface, sourceLocale, locale, items }`. Each item contains `source`, optional `format` (`plain` or `icu`), and optional `meaning` (at most 512 code points).

Lookup returns the requested scope and `entries: [{ key, state, text, revision, approval? }]`. Public states are `published` and `missing`; public callers cannot inspect drafts or job failures.

Policy requests include `surfaceId`, `environmentId`, `expectedPolicyVersionId` (null initially), `paidWorkEnabled`, `automaticPublication`, `monthlyBudgetMicros`, and `requestCeilingMicros`. Monetary values are integer strings in millionths of USD. Set `resumeAutomaticPublication: true` to resume after rollback.

Release requests include `environmentId`, `surfaceId`, `locale`, `translationIds`, `expectedRevision`, and `reason`. For rollback, supply `rollbackRevision` and an empty translation list. A stale revision returns a conflict; refresh before retrying.

## Sitemap

See the full [sitemap](/sitemap.md) for all pages.
Docs-scoped sitemap: [/docs/sitemap.md](/docs/sitemap.md).
Well-known sitemap: [/.well-known/sitemap.md](/.well-known/sitemap.md).
