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.
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.
GET /sdk/export?platform=… with the key in the X-API-Key header.A quick map of the pieces you will see across the dashboard, the export and the MCP tools.
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.
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.
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).
{
"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} عناصر" }
}
}
}
}Fetch once per build (or cache on your server) and hand the map to your i18n library.
// 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"
}// 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(" ")}}`,
]),
),
};Decode straight into a struct with URLSession — no dependencies.
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"Any JSON parser works; this uses Gson over a plain HttpURLConnection.
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"Use the http package and read the decoded map.
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"Pull the latest strings in a release step and commit or bundle the file, so a copy change ships without touching code.
# 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
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.
Drop files into a project; Glotra detects the platform and language from each filename and matches keys across them.
Download a project as a zip laid out per platform, ready to drop into your repo:
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.
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.
POST https://api.glotra.yaxbi.com/mcp
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 mcp add --transport http glotra https://api.glotra.yaxbi.com/mcp
Then run /mcp in Claude Code and choose Authenticate.
Add to ~/.cursor/mcp.json or .vscode/mcp.json:
{
"mcpServers": {
"glotra": { "url": "https://api.glotra.yaxbi.com/mcp" }
}
}Settings → Connectors → Add custom connector, paste the URL, then click Connect.
Once connected, ask in plain language — for example “add the checkout button text ‘Pay now’ to the Shop project”. The assistant calls these tools:
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.
read, write and delete are a ceiling; write defaults on, delete defaults off, and you can limit the connection to chosen projects.Returns the project's translations for one platform.
X-API-Key (required)platform (required)web, ios, android, flutter or other.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.