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

# Best Practices

> Production-grade guidance for using the Ollang platform — API keys, callbacks, retries, pagination, error handling, folder structure, memory, and review gates.

# Best Practices

Recommended patterns for shipping reliable, secure, and consistent
localization workflows on Ollang.

## API Key Hygiene

* **Store keys in environment variables or a secrets manager.** Never
  commit `<your-api-key>` values to source control or paste them in
  shared chats.
* **Use a separate key per environment.** Development, staging, and
  production should each have their own API key. Rotate when team
  members leave or a key is suspected leaked.
* **Pass keys via `X-Api-Key`,** not in the URL or request body. The
  header name is case-sensitive on some HTTP clients.
* **Scope by Folder, not by key.** Folders are how you isolate workflows
  and content (legal vs. marketing vs. internal training). All keys on
  an account can see all folders.

```bash theme={null}
# Recommended
export OLLANG_API_KEY="<your-api-key>"
curl -H "X-Api-Key: $OLLANG_API_KEY" https://api-integration.ollang.com/health
```

## Folder Structure

Folders are the primary organizational unit. Use them to group projects
that share a workflow.

**Recommended folder layout for an enterprise account:**

```text theme={null}
Marketing — Campaigns                 (folder workflow: aiDubbing overdub, Level 0)
Marketing — Brand Videos              (folder workflow: aiDubbing overdub, Level 1)
Product — Training Videos             (folder workflow: subtitle, Level 1)
Product — Help Center                 (folder workflow: document, Level 1)
Legal — Contracts                     (folder workflow: document, Level 1, formal tone)
Accessibility — Audio Description     (folder workflow: aiDubbing audioDescription)
API Uploads                           (default — for ad-hoc / dev usage)
```

**Benefits:**

* Folder-level workflows override Global workflows, so each team gets
  its preferred provider/review-gate setup without touching account
  defaults.
* Folder-level Custom Instructions / Guidelines apply automatically to
  every order created in that folder.
* Folder-level Memory keeps terminology consistent across multiple
  campaigns or product lines.

See [Workflows and Provider Architecture](/workflows-provider-architecture)
and [Memory, Guidelines, and Custom Instructions](/memory-guidelines-custom-instructions).

## Callbacks vs. Polling

Always prefer **callbacks** for production workflows. Fall back to
polling for short-lived scripts or as a safety net.

### Callback handler checklist

* **Idempotent.** Use `orderId` (and optionally `completedAt`) as the
  deduplication key. The same callback may fire more than once on
  retry.
* **Fast acknowledgment.** Return `2xx` within **10 seconds**.
  Process asynchronously (queue, background job) if your handler does
  any real work.
* **Confirm before acting.** Don't trust callback bodies alone. Pair
  with `GET /integration/orders/<order-id>` using your API key before
  performing irreversible actions (publishing content, billing customers).
* **Public URLs only.** Callback URLs must be reachable from the public
  internet. Internal hostnames and IPv6 destinations are blocked at the
  SSRF guard.

```typescript theme={null}
// Example: Express handler
app.post("/webhooks/ollang", async (req, res) => {
  // 1. Ack immediately
  res.sendStatus(200);

  // 2. Process asynchronously
  await queue.add("ollang-order-completed", {
    orderId: req.body.orderId,
    completedAt: req.body.completedAt,
  });
});

// Worker
async function handle(payload) {
  // 3. Re-fetch to verify
  const order = await ollang.orders.getById(payload.orderId);
  if (order.status !== "completed") return; // ignore false positives

  // 4. Use a transactional upsert keyed on orderId
  await db.deliveries.upsert({
    where: { orderId: order.orderId },
    create: { ... },
    update: { status: order.status },
  });
}
```

### Polling pattern

```bash theme={null}
while true; do
  STATUS=$(curl -s "https://api-integration.ollang.com/integration/orders/<order-id>" \
    -H "X-Api-Key: <your-api-key>" | jq -r '.status')
  case "$STATUS" in
    completed|revision) break ;;
    *) sleep 30 ;;
  esac
done
```

Recommended cadence: every 30–60 seconds. AI-only orders typically
complete within minutes; Level 1 orders depend on reviewer availability.

## Retries and Backoff

The Integration API is generally available 99.9%. Network blips happen.

* Retry on `408`, `429`, `500`, `502`, `503`, `504`.
* Use **exponential backoff with jitter** (e.g. 500ms → 1s → 2s → 4s → 8s,
  cap \~30s).
* Treat `429` (rate limit) seriously — slow your overall request rate,
  don't just retry harder.
* **Do not retry** `400`, `401`, `403`, `404` without changing the
  request — they indicate a client-side bug, not a transient failure.
* File uploads can have multi-minute response times. Set HTTP client
  read/write timeouts to **5–10 minutes** for upload requests.

## Choosing `level: 0` vs `level: 1`

| Use `level: 0` (AI only) when…                     | Use `level: 1` (Human Review) when…       |
| -------------------------------------------------- | ----------------------------------------- |
| Internal previews, QA, sample reviews              | External / paid distribution              |
| Volume is high and SLAs are tight                  | Brand-sensitive or legal content          |
| You're iterating on prompts, guidelines, or Memory | First time localizing into a new language |
| Multiple subsequent reruns expected                | Accessibility / compliance deliverables   |

You can always **escalate** a Level 0 order to Level 1 after it
completes via [Request Human Review](/apis/ollang-api-reference/request-human-review),
and **revert** with [Cancel Human Review](/apis/ollang-api-reference/cancel-human-review).
This lets you ship quickly and only pay for review on the languages or
files that need it.

## Memory and Custom Instructions

Memory and Custom Instructions are the strongest levers you have for
quality and consistency:

* **Memory** — approved translations for recurring terms (product
  names, trademarks, legal jargon). Reuse across projects.
* **Custom Instructions** — natural-language guidance to the AI
  ("Always use formal register in French," "Translate 'cookie' as
  'cookie' in cybersecurity contexts, not as the food").
* **Folder Guidelines** override account-wide Custom Instructions for
  specific workflows.

**When introducing Ollang into a new language:**

1. Run a small Level 1 pilot batch.
2. Capture linguist edits into Memory.
3. Run subsequent Level 0 orders with the populated Memory — quality
   tends to converge quickly.

See [Memory, Guidelines, and Custom Instructions](/memory-guidelines-custom-instructions).

## QC and Review Gates

* Enable **`autoQc: true`** on order creation to score every order
  immediately on completion. See [Run QC Evaluation](/apis/ollang-api-reference/run-qc-evaluation).
* Configure **Review Gates** in your Folder workflow to auto-route
  low-scoring orders to human review (Assignment mode) or to a review
  tag (Comment mode). See
  [Workflows and Provider Architecture](/workflows-provider-architecture)
  and the [Review Gate](/glossary#review-gate) entry in the glossary.
* Track QC progression in the Analytics dashboard — declining scores
  are usually a sign of a content/domain shift that needs Memory or
  Custom Instructions updates. See
  [Analytics and QC Monitoring](/analytics-qc-monitoring).

## Bulk and Concurrent Operations

* **Each `targetLanguageConfigs` entry creates one order.** Issue them
  in a single `createOrder` request rather than looping, so you get
  consistent timestamps and a single response array.
* **Parallelize uploads** moderately (start at 3–5 concurrent). Watch
  for `429` and back off.
* **Reuse projects** across orders. One source video can drive multiple
  `cc` + `subtitle` + `aiDubbing` orders without re-uploading.

## Error Handling

The REST API returns standard HTTP status codes with a JSON body:

```json theme={null}
{
  "error": "Invalid file format",
  "message": "Only VTT files are supported",
  "code": "INVALID_FILE_FORMAT"
}
```

**Recommended client logic:**

* `2xx` → success
* `4xx` → log and surface to the user; do not retry without changing
  the request
* `429` → backoff and retry
* `5xx` → backoff and retry (up to N times)

Capture the response `code` and the original request when escalating to
support — see [Troubleshooting](/troubleshooting#what-to-send-support).

## Pagination

List endpoints use one of two query-string styles depending on the
endpoint:

```
# Flat (folders, projects)
?page=1&take=20&search=sample&orderBy=createdAt&orderDirection=desc

# Nested pageOptions[...] (orders)
?pageOptions[page]=1
&pageOptions[take]=20
&pageOptions[search]=sample
&pageOptions[orderBy]=createdAt
&pageOptions[orderDirection]=desc
```

* `take` is the page size (default `10`, max `50`); the API returns a
  `meta` object with `page`, `take`, `itemCount`, `pageCount`,
  `hasPreviousPage`, and `hasNextPage`.
* Iterate until `hasNextPage` is `false`.
* Combine with `filter[name]`, `filter[type]`, or
  `filter[createdAtRange]` for more targeted queries.

See [API Conventions — Pagination](/concepts/api-conventions#pagination),
[Get Orders](/apis/ollang-api-reference/get-orders), and
[Retrieve All Projects](/apis/ollang-api-reference/retrieve-all-projects)
for the canonical examples.

## Security

* Never log API keys, callback bodies containing tokens, or signed URLs.
* Treat `vttUrl` and `orderDocs[].url` as **short-lived, sensitive
  URLs**. Re-fetch via [Get Order by ID](/apis/ollang-api-reference/get-order-by-id)
  before downloading rather than persisting them indefinitely.
* Restrict who has access to your API keys to the smallest team possible.
* If you suspect a key leak, **rotate immediately** in the
  [Olabs Dashboard](https://lab.ollang.com) and update all consumers.

## Versioning and Deprecations

The Integration API is currently stable and non-versioned at the URL
level. Breaking changes (parameter removals, response shape changes)
are announced in the [Changelog](/changelog) ahead of rollout. Additive
changes (new optional fields, new endpoints) ship without notice.

## When to Reach for Each Surface

A quick mental model:

* **REST API** — anything programmatic. Default choice.
* **SDK** — Node.js / TypeScript projects, plus when you want the
  Asset Management UI for i18n strings or CMS capture.
* **MCP** — non-developer team members operating Ollang through an AI
  assistant; ad-hoc / exploratory work; automated agents.
* **Skills** — coding agents (Cursor, Claude Code, Codex, Windsurf,
  Cline) when you want zero infra — just a file-based skill bundle.

See [How It All Connects](/concepts/how-it-all-connects) for the full
comparison.

## See Also

* [Use Cases](/concepts/use-cases) — end-to-end workflow walkthroughs.
* [API Conventions](/concepts/api-conventions) — pagination, errors,
  auth in one reference page.
* [Troubleshooting](/troubleshooting) — diagnostics for common issues.
