Docs

Ship your translations into any app.

Every project issues a read-only API key. Point your app, or your CI, at the export endpoint and you get back one JSON document of strings per language — the same shape on every platform. Or connect an AI assistant over MCP to search and add keys for you.

Overview

Glotra holds your keys as the source of truth. To get them into a running app there are two paths: download per-platform files from the dashboard, or fetch them at build or run time from the /sdk/export endpoint with a project API key. This page covers the endpoint.

  1. Create a key in Settings → API Keys (owner or admin). It is shown once; store it as a secret.
  2. Call GET /sdk/export?platform=… with the key in the X-API-Key header.
  3. Read the strings per language from the JSON it returns.

Concepts

A quick map of the pieces you will see across the dashboard, the export and the MCP tools.

Project
Holds a set of keys, a base language and its target languages. Each organization's projects live in their own database.
Key
A named string such as checkout.pay_button. Carries the platforms it ships to, optional tags and a description for translators.
Base language
The source language you author in (for example English). Every other language is translated from it.
Target languages
The languages a project is translated into. Filled by machine translation or by a translator, per key.
Platforms
ios, android, web, flutter or other. A key only appears in the bundle for the platforms it belongs to.
Plurals
Per-language plural forms (one, other, and any others a language needs), kept separate from simple strings.
History & roles
Every value keeps its author, source and timestamp. Owners and admins manage the org; editor and viewer grants scope access per project.

Authentication

Pass the project API key in the X-API-Key header. Keys are bound to one project and are read-only — they can only export, never change data — so they are safe to ship inside a build or CI. Rotate or revoke a key any time from Settings → API Keys; a revoked key stops working immediately.

http
GET https://api.glotra.yaxbi.com/sdk/export?platform=web
X-API-Key: glt_xxxxxxxxxxxxxxxxxxxxxxxx

platform is one of web, ios, android, flutter or other. Each key carries the platforms it belongs to, so an iOS-only string never lands in the web bundle.

Response shape

The endpoint always returns JSON, the same shape for every platform. Each language has a simple map of plain strings and a plural map of keys to their plural forms (one, other, and the rest a language needs).

json
{
  "platform": "web",
  "languages": {
    "en": {
      "simple": { "auth.login.title": "Sign in" },
      "plural": {
        "cart.items": { "one": "1 item", "other": "{count} items" }
      }
    },
    "ar": {
      "simple": { "auth.login.title": "تسجيل الدخول" },
      "plural": {
        "cart.items": { "one": "عنصر واحد", "other": "{count} عناصر" }
      }
    }
  }
}

Web & React

Fetch once per build (or cache on your server) and hand the map to your i18n library.

typescript
// GLOTRA_API_KEY is your project API key. Never ship a write token —
// SDK keys are read-only and only return this project's strings.
const BASE = "https://api.glotra.yaxbi.com";

export async function loadMessages(platform = "web") {
  const res = await fetch(`${BASE}/sdk/export?platform=${platform}`, {
    headers: { "X-API-Key": process.env.GLOTRA_API_KEY! },
    // Cache in your build or a short-lived server cache; strings change rarely.
    next: { revalidate: 3600 },
  });
  if (!res.ok) throw new Error(`Glotra export failed: ${res.status}`);
  const { languages } = await res.json();
  return languages; // languages["en"].simple["auth.login.title"] -> "Sign in"
}
typescript
// Flatten one language into the "dotted key -> string" map most i18n
// libraries expect (next-intl, i18next, react-intl, …).
const lang = languages["en"];
const messages = {
  ...lang.simple,
  // Plurals as ICU, keyed on "count":
  ...Object.fromEntries(
    Object.entries(lang.plural).map(([key, forms]) => [
      key,
      `{count, plural, ${Object.entries(forms)
        .map(([f, text]) => `${f === "other" ? "other" : f} {${text}}`)
        .join(" ")}}`,
    ]),
  ),
};

iOS · Swift

Decode straight into a struct with URLSession — no dependencies.

swift
struct GlotraExport: Decodable {
  let languages: [String: Language]
  struct Language: Decodable {
    let simple: [String: String]
    let plural: [String: [String: String]]
  }
}

func fetchStrings(apiKey: String) async throws -> GlotraExport {
  var req = URLRequest(url: URL(string:
    "https://api.glotra.yaxbi.com/sdk/export?platform=ios")!)
  req.setValue(apiKey, forHTTPHeaderField: "X-API-Key")
  let (data, _) = try await URLSession.shared.data(for: req)
  return try JSONDecoder().decode(GlotraExport.self, from: data)
}

// let export = try await fetchStrings(apiKey: key)
// export.languages["en"]?.simple["auth.login.title"]  // "Sign in"

Android · Kotlin

Any JSON parser works; this uses Gson over a plain HttpURLConnection.

kotlin
data class Export(val languages: Map<String, Language>)
data class Language(
  val simple: Map<String, String>,
  val plural: Map<String, Map<String, String>>,
)

suspend fun fetchStrings(apiKey: String): Export = withContext(Dispatchers.IO) {
  val url = URL("https://api.glotra.yaxbi.com/sdk/export?platform=android")
  val conn = (url.openConnection() as HttpURLConnection).apply {
    setRequestProperty("X-API-Key", apiKey)
  }
  conn.inputStream.bufferedReader().use { reader ->
    Gson().fromJson(reader, Export::class.java)
  }
}

// val export = fetchStrings(key)
// export.languages["en"]?.simple?.get("auth.login.title")  // "Sign in"

Flutter · Dart

Use the http package and read the decoded map.

dart
import 'dart:convert';
import 'package:http/http.dart' as http;

Future<Map<String, dynamic>> fetchStrings(String apiKey,
    {String platform = 'flutter'}) async {
  final res = await http.get(
    Uri.parse('https://api.glotra.yaxbi.com/sdk/export?platform=$platform'),
    headers: {'X-API-Key': apiKey},
  );
  if (res.statusCode != 200) {
    throw Exception('Glotra export failed: ${res.statusCode}');
  }
  return jsonDecode(res.body)['languages'] as Map<String, dynamic>;
}

// final languages = await fetchStrings(key);
// languages['en']['simple']['auth.login.title'];  // "Sign in"

CLI & CI

Pull the latest strings in a release step and commit or bundle the file, so a copy change ships without touching code.

bash
# Pull the current web strings in CI and commit or bundle them.
curl -fsS -H "X-API-Key: $GLOTRA_API_KEY" \
  "https://api.glotra.yaxbi.com/sdk/export?platform=web" -o messages.json

File formats

Besides the live export, the dashboard reads and writes the native files each platform already uses — so you can move an existing project in, or hand a build the exact layout it expects.

Import

Drop files into a project; Glotra detects the platform and language from each filename and matches keys across them.

Web
.json · e.g. web_en.json, en.json
iOS
.strings, .stringsdict · e.g. ios_en.strings, en.lproj/Localizable.strings
Android
.xml · e.g. android_en.xml, values-en/strings.xml

Export & download

Download a project as a zip laid out per platform, ready to drop into your repo:

Web
{lang}/strings.json
iOS
{lang}.lproj/Localizable.strings + Localizable.stringsdict
Android
values/ and values-{lang}/strings.xml

Use these one-off files to migrate or hand off. For a running app, prefer the export endpoint above — it always returns the current strings.

MCP server

Glotra is also a Model Context Protocol server, so AI assistants like Claude, Cursor and VS Code can work with your keys in plain language — list projects, search, and add or edit keys — while you keep control of what they may do. It is a hosted HTTP endpoint; there is nothing to install.

endpoint
POST https://api.glotra.yaxbi.com/mcp
  • You sign in, not a token. The assistant opens Glotra in your browser; you approve what it may do and, optionally, which projects it may touch.
  • Keys are written in your base language. The assistant sends only the base text; Glotra machine-translates every other project language and reports anything still pending.
  • It never exceeds your own role. A viewer stays read-only even if they approve editing.

Connect a client

Point any MCP client at the endpoint, then sign in with your Glotra account when it prompts you. The URL is also on the Connected apps page.

Claude Code

bash
claude mcp add --transport http glotra https://api.glotra.yaxbi.com/mcp

Then run /mcp in Claude Code and choose Authenticate.

Cursor & VS Code

Add to ~/.cursor/mcp.json or .vscode/mcp.json:

json
{
  "mcpServers": {
    "glotra": { "url": "https://api.glotra.yaxbi.com/mcp" }
  }
}

Claude.ai & Claude Desktop

Settings → Connectors → Add custom connector, paste the URL, then click Connect.

Tools & usage

Once connected, ask in plain language — for example “add the checkout button text ‘Pay now’ to the Shop project”. The assistant calls these tools:

list_projects
The projects you can reach, with each one's base and target languages.
get_project
One project's languages, key count and your permissions.
search_keys
Search or list keys and their translations.
get_key
A single key with every translation, plural forms included.
add_key
Create a key from base-language text; Glotra translates the rest.
update_key
Edit, rename or re-translate a key.
delete_key
Remove a key (needs the delete scope).
export_translations
The same JSON the SDK export returns.

Only the tools your approved scopes allow are offered — add_key and update_key appear only with write access, delete_key only with the delete scope. Every write is recorded in the key history, attributed to you and the app you connected.

Permissions & plans

  • Scopes you approve. read, write and delete are a ceiling; write defaults on, delete defaults off, and you can limit the connection to chosen projects.
  • Your live role still applies. Editing needs editor access to that project; a lapsed subscription makes connections read-only, same as the dashboard.
  • Disconnect any time. Manage connections under Connected apps; a revoked app loses access on its next request. Owners and admins can see and revoke every member's apps.
  • Included in every plan, including the free trial, at no extra cost.

API reference

GET /sdk/export

Returns the project's translations for one platform.

Header · X-API-Key (required)
The project API key.
Query · platform (required)
web, ios, android, flutter or other.
Responses
200 the export JSON · 401 missing or revoked key · 400 missing/invalid platform · 403 organization inactive.

Prefer an AI assistant to manage keys instead of fetching them? See Connected apps for the MCP server, or the FAQ.