# IntlPull - Translation Management Platform Reference > **Version:** 0.1.0 | **Updated:** January 2026 > **Website:** https://intlpull.com | **Docs:** https://intlpull.com/learn IntlPull is a complete translation management platform that helps developers manage multi-language content across web, mobile, and desktop applications. This reference provides comprehensive documentation for implementing IntlPull integrations via CLI, SDKs, MCP servers, and APIs. --- ## Table of Contents 1. [Quick Start](#quick-start) 2. [CLI Reference](#cli-reference) 3. [SDK Integration](#sdk-integration) 4. [MCP Server (AI Integration)](#mcp-server-ai-integration) 5. [REST API Reference](#rest-api-reference) 6. [Data Formats & Structures](#data-formats--structures) 7. [Platform Features](#platform-features) 8. [IDE & Tool Integrations](#ide--tool-integrations) 9. [Common Workflows](#common-workflows) 10. [Authentication](#authentication) --- ## Quick Start ### Installation ```bash # CLI npm install -g @intlpullhq/cli # React SDK npm install @intlpullhq/react # DevTools (in-context editing) npm install --save-dev @intlpullhq/devtools # MCP Server (AI translations) npx @intlpullhq/mcp-server ``` ### Basic Workflow ```bash # 1. Initialize project npx @intlpullhq/cli init # 2. Create translation files with your i18n library # (next-intl, react-i18next, vue-i18n, etc.) # 3. Upload to IntlPull platform npx @intlpullhq/cli upload # 4. Download translations npx @intlpullhq/cli download # 5. Check translation status npx @intlpullhq/cli status ``` --- ## CLI Reference ### Global Options All commands support these flags: - `--project ` - Target specific project (overrides config) - `--verbose` - Show detailed logs - `--help` - Show command help ### Commands #### `npx @intlpullhq/cli init` Initialize IntlPull configuration in your project. ```bash npx @intlpullhq/cli init [options] Options: --framework Framework: next, react, vue, svelte, astro, expo --library i18n library: next-intl, react-i18next, react-intl, vue-i18n, svelte-i18n --output Translation files directory (default: ./messages) --project Link to existing project ID --yes Non-interactive mode (accept defaults) ``` **Example:** ```bash npx @intlpullhq/cli init --framework next --library next-intl --output ./locales ``` **Creates:** `.intlpull.json` configuration file --- #### `npx @intlpullhq/cli login` Authenticate with IntlPull platform. ```bash npx @intlpullhq/cli login [options] Options: --token Provide API key directly (for CI/CD) ``` **Interactive mode:** Opens browser for OAuth authentication **Token mode:** Use for automated environments **Example:** ```bash # Interactive npx @intlpullhq/cli login # CI/CD npx @intlpullhq/cli login --token ip_live_xxxxx ``` --- #### `npx @intlpullhq/cli upload` Upload translation keys to IntlPull platform. ```bash npx @intlpullhq/cli upload [options] Options: --file Upload specific extracted file --branch Target git branch (if branching enabled) --platform Tag keys: web, ios, android --all-languages Upload all language translations (not just source) --dry-run Simulate without uploading ``` **Example:** ```bash # Upload extracted keys npx @intlpullhq/cli upload --file .intlpull-extracted-demo.json # Upload with platform tag npx @intlpullhq/cli upload --platform ios # Upload to feature branch npx @intlpullhq/cli upload --branch feature/new-checkout ``` --- #### `npx @intlpullhq/cli download` Download translations from IntlPull platform. ```bash npx @intlpullhq/cli download [options] Options: --output Output directory (default: ./messages) --format json, yaml, typescript --branch Source branch --languages Specific languages (comma-separated) --yes Auto-confirm overwrites ``` **Example:** ```bash # Download all languages npx @intlpullhq/cli download # Download specific languages npx @intlpullhq/cli download --languages es,fr,de # Download from branch npx @intlpullhq/cli download --branch staging ``` **Output structure:** ``` messages/ en.json es.json fr.json ``` --- #### `npx @intlpullhq/cli status` Show translation progress and project stats. ```bash npx @intlpullhq/cli status ``` **Displays:** - Project name and ID - Total translation keys - Coverage per language (%) - Missing translations count - Current branch (if branching enabled) **Example output:** ``` Project: My App (proj_123) Total Keys: 156 Languages: ✓ English (en) 100% (156/156) ○ Spanish (es) 87% (136/156) [20 missing] ○ French (fr) 92% (144/156) [12 missing] Current Branch: main ``` --- #### `npx @intlpullhq/cli sync` Bi-directional sync: push changes and pull updates. ```bash npx @intlpullhq/cli sync [options] Options: --watch Watch mode (continuous sync) ``` **Example:** ```bash # One-time sync npx @intlpullhq/cli sync # Watch mode for development npx @intlpullhq/cli sync --watch ``` --- #### `npx @intlpullhq/cli import` Import existing translation files into IntlPull. ```bash npx @intlpullhq/cli import [options] Options: --file File to import --format json, yaml, android, ios, xliff, po, csv --language Target language --namespace Namespace (default: common) --preview Preview without importing ``` **Supported formats:** - **JSON:** Flat or nested key-value pairs - **YAML:** Standard YAML translation files - **Android:** strings.xml - **iOS:** .strings files - **XLIFF:** Translation exchange format - **PO:** Gettext files - **CSV:** Key, value, context columns **Example:** ```bash # Preview import npx @intlpullhq/cli import --file es.json --preview # Import Spanish translations npx @intlpullhq/cli import --file es.json --language es ``` --- #### `npx @intlpullhq/cli export` Export translations as downloadable archive. ```bash npx @intlpullhq/cli export [options] Options: --format json, yaml, android, ios, xliff --output Output filename (default: translations.zip) ``` **Example:** ```bash npx @intlpullhq/cli export --format json --output translations.zip ``` --- #### `npx @intlpullhq/cli projects` Manage IntlPull projects. ```bash npx @intlpullhq/cli projects Commands: list List all accessible projects create Create new project (interactive) link Link current directory to project ``` **Examples:** ```bash # List projects npx @intlpullhq/cli projects list # Create new project npx @intlpullhq/cli projects create # Link to existing project npx @intlpullhq/cli projects link proj_abc123 ``` --- ## SDK Integration ### @intlpullhq/react React SDK for web applications with OTA (Over-The-Air) updates. #### Installation ```bash npm install @intlpullhq/react ``` #### Setup ```tsx // app/layout.tsx or main.tsx import { IntlPullProvider } from '@intlpullhq/react'; function App() { return ( ); } ``` #### Hooks ##### useOTATranslations() Main hook for accessing translations. ```tsx import { useOTATranslations } from '@intlpullhq/react'; function MyComponent() { const { t, isLoading, error, locale } = useOTATranslations(); return

{t('welcome.title')}

; } ``` **Returns:** - `t(key: string, values?: object)` - Translation function - `isLoading: boolean` - Loading state - `error: Error | null` - Error state - `locale: string` - Current locale **Translation with variables:** ```tsx t('greeting', { name: 'Alice' }) // With ICU: "Hello, {name}!" → "Hello, Alice!" ``` ##### useLocale() Get current active locale. ```tsx import { useLocale } from '@intlpullhq/react'; function LanguageSwitcher() { const locale = useLocale(); return
Current: {locale}
; } ``` ##### useNamespace(namespace) Load specific namespace lazily. ```tsx import { useNamespace } from '@intlpullhq/react'; function CheckoutPage() { const { t, loaded, loading } = useNamespace('checkout'); if (loading) return ; return

{t('checkout.title')}

; } ``` ##### useLocaleLoader() Manually load and switch locales. ```tsx import { useLocaleLoader } from '@intlpullhq/react'; function LanguageSwitcher() { const { loadAndSwitch } = useLocaleLoader(); return ( ); } ``` #### Components ##### `` Suspense-like wrapper for lazy namespace loading. ```tsx import { NamespaceBoundary } from '@intlpullhq/react'; function App() { return ( } errorFallback={} > ); } ``` #### Provider Props | Prop | Type | Required | Description | |------|------|----------|-------------| | `projectId` | string | Yes | IntlPull project UUID | | `apiKey` | string | Yes | Public API key (`intl_public_*`) | | `defaultLocale` | string | No | Initial locale (default: 'en') | | `fallbackTranslations` | object | No | Initial data to prevent loading flicker | | `loadingComponent` | ReactNode | No | Custom loading component | | `suspendOnLoading` | boolean | No | Suspend rendering until loaded | | `cacheExpiration` | number | No | Cache duration in ms (default: 3600000) | --- ### @intlpullhq/devtools In-context translation editing for any framework. Works with IntlPull Chrome Extension. #### Supported Frameworks | Framework | Library | Import Path | |-----------|---------|-------------| | Next.js | next-intl | `@intlpullhq/devtools/next-intl` | | React | react-i18next | `@intlpullhq/devtools/react-i18next` | | React | react-intl (FormatJS) | `@intlpullhq/devtools/react-intl` | | Vue 3 | vue-i18n | `@intlpullhq/devtools/vue-i18n` | | Svelte | svelte-i18n | `@intlpullhq/devtools/svelte-i18n` | | Expo | react-native | `@intlpullhq/devtools/expo` | | Vite | any i18n | `@intlpullhq/devtools/vite` | #### Next.js Setup (next-intl) ```tsx // app/layout.tsx import { IntlPullDevTools } from '@intlpullhq/devtools'; export default function RootLayout({ children }) { return ( {children} {process.env.NODE_ENV === 'development' && } ); } ``` ```tsx // components/MyComponent.tsx import { useTranslations, useLocale } from 'next-intl'; import { useMarkedTranslations } from '@intlpullhq/devtools/next-intl'; function MyComponent() { const t = useMarkedTranslations( useTranslations('common'), 'common', useLocale() ); return

{t('welcome')}

; } ``` #### React Setup (react-i18next) ```tsx // components/MyComponent.tsx import { useTranslation } from 'react-i18next'; import { useMarkedTranslation } from '@intlpullhq/devtools/react-i18next'; function MyComponent() { const { t } = useMarkedTranslation(useTranslation('common'), 'common'); return

{t('welcome')}

; } ``` #### React Setup (react-intl) ```tsx import { useIntl } from 'react-intl'; import { useMarkedIntl } from '@intlpullhq/devtools/react-intl'; function MyComponent() { const intl = useMarkedIntl(useIntl()); return

{intl.formatMessage({ id: 'welcome' })}

; } ``` #### Vue 3 Setup (vue-i18n) ```ts // main.ts import { createApp } from 'vue'; import { intlPullPlugin } from '@intlpullhq/devtools/vue-i18n'; const app = createApp(App); if (import.meta.env.DEV) { app.use(intlPullPlugin); } ``` ```vue ``` #### Features - **Visual Editing:** Cmd/Ctrl + Click to edit translations - **Real-time Preview:** See changes instantly - **Tree View:** Navigate all translation keys - **Chrome Extension Integration:** Full IDE experience in browser --- ## MCP Server (AI Integration) Model Context Protocol server for AI-powered translations and management. ### Installation & Configuration ```bash # Run directly npx @intlpullhq/mcp-server # Or install globally npm install -g @intlpullhq/mcp-server ``` ### Claude Desktop Configuration **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json` **Windows:** `%APPDATA%\Claude\claude_desktop_config.json` **Linux:** `~/.config/Claude/claude_desktop_config.json` ```json { "mcpServers": { "intlpull": { "command": "npx", "args": ["-y", "@intlpullhq/mcp-server"], "env": { "GEMINI_API_KEY": "your-gemini-api-key" } } } } ``` ### Environment Variables - `GEMINI_API_KEY` - Google Gemini API key for AI translations (optional, uses mock mode without it) - `INTLPULL_API_KEY` - IntlPull API key for platform integration (optional) - `INTLPULL_PROJECT_ID` - Default project ID (optional) ### Available Tools #### translate_strings Translate array of strings to target language. **Parameters:** ```json { "strings": [ { "key": "welcome", "value": "Welcome" }, { "key": "submit", "value": "Submit" } ], "sourceLanguage": "en", "targetLanguage": "es" } ``` **Returns:** ```json { "translations": [ { "key": "welcome", "value": "Bienvenido" }, { "key": "submit", "value": "Enviar" } ] } ``` --- #### translate_file Translate entire extracted JSON file. **Parameters:** ```json { "inputFile": ".intlpull-extracted-demo.json", "sourceLanguage": "en", "targetLanguage": "fr", "outputFile": "fr.json" } ``` **Returns:** Writes translated file to `outputFile` --- #### list_languages Get all supported languages. **Returns:** ```json { "languages": [ { "code": "en", "name": "English" }, { "code": "es", "name": "Spanish" }, { "code": "fr", "name": "French" } // ... 30+ languages ] } ``` **Supported languages:** - Western: en, es, fr, de, it, pt, nl, sv, da, no, fi, pl - Asian: ja, ko, zh, zh-TW, hi, th, id, ms, vi - Middle Eastern: ar, he, tr - Eastern European: ru, uk, cs, el, hu, ro --- #### get_translation_status Get project translation progress. **Parameters:** ```json { "projectPath": "." } ``` **Returns:** ```json { "projectId": "proj_abc123", "projectName": "My App", "totalKeys": 156, "languages": [ { "code": "en", "name": "English", "progress": 100, "translated": 156, "missing": 0 }, { "code": "es", "name": "Spanish", "progress": 87, "translated": 136, "missing": 20 } ] } ``` --- #### generate_translation_file Generate translation file for specific language. **Parameters:** ```json { "extractedFile": ".intlpull-extracted-demo.json", "targetLanguage": "es", "format": "flat", "outputDir": "./messages" } ``` **Formats:** - `flat` - `{ "key": "value" }` - `nested` - `{ "section": { "key": "value" } }` --- #### get_branch_info Get git branch and translation strategy. **Returns:** ```json { "currentBranch": "main", "strategy": "per-branch", "baseBranch": "main" } ``` **Strategies:** - `per-branch` - Separate translations per git branch - `merged` - Sync with base branch automatically - `none` - Ignore branch structure --- #### set_branch_strategy Configure branch translation strategy. **Parameters:** ```json { "projectPath": ".", "strategy": "per-branch", "baseBranch": "main", "sourceLanguage": "en" } ``` --- #### merge_branch_translations Merge translations between branches. **Parameters:** ```json { "projectPath": ".", "direction": "to-base", "namespace": "common", "conflictResolution": "keep-base" } ``` **Directions:** - `to-base` - Merge feature branch → main - `from-base` - Sync main → feature branch **Conflict resolution:** - `keep-base` - Prefer base branch (default) - `keep-branch` - Prefer feature branch - `keep-both` - Keep both with suffix --- ### MCP Resources Access configuration and data via MCP resources: ``` intlpull://languages - List of all supported languages intlpull://config - Current project configuration ``` --- ## REST API Reference **Base URL:** `https://api.intlpull.com/api/v1` ### Authentication All API requests require authentication via one of: **API Key (Header):** ``` X-API-Key: ip_live_xxxxx ``` **JWT Bearer Token:** ``` Authorization: Bearer ``` **API Key Types:** - `intl_public_*` - Public keys for client-side SDK (read-only) - `ip_live_*` - User-scoped keys (full access to user's projects) - `intl_*` - Project-scoped keys (access to specific project) --- ### Projects #### List Projects ```http GET /projects ``` **Response:** ```json { "projects": [ { "id": "proj_abc123", "name": "My App", "source_language": "en", "created_at": "2024-01-15T10:00:00Z" } ] } ``` --- #### Get Project ```http GET /projects/{projectId} ``` **Response:** ```json { "id": "proj_abc123", "name": "My App", "source_language": "en", "target_languages": ["es", "fr", "de"], "total_keys": 156, "branch_strategy": "per-branch", "created_at": "2024-01-15T10:00:00Z" } ``` --- #### Create Project ```http POST /projects Content-Type: application/json { "name": "New App", "source_language": "en" } ``` **Response:** `201 Created` with project object --- ### Translation Keys #### List Keys ```http GET /projects/{projectId}/keys?namespace=common&search=button&tags=ui ``` **Query parameters:** - `namespace` - Filter by namespace - `search` - Search in keys/values - `tags` - Filter by tags (comma-separated) - `platform` - Filter by platform (ios, android, web) **Response:** ```json { "keys": [ { "id": "key_123", "key": "button.submit", "namespace": "common", "value": "Submit", "context": "Form submit button", "tags": ["ui", "forms"], "platforms": ["all"], "max_length": 50, "created_at": "2024-01-15T10:00:00Z" } ], "total": 156, "page": 1 } ``` --- #### Create Key ```http POST /projects/{projectId}/keys Content-Type: application/json { "namespace": "common", "key": "button.submit", "value": "Submit", "language": "en", "context": "Main form submit button", "max_length": 50, "tags": ["ui", "forms"], "platforms": ["all"] } ``` **Response:** `201 Created` **Auto-translation:** Creating a key automatically triggers AI translation to all target languages. --- #### Update Key ```http PATCH /projects/{projectId}/keys/{keyId} Content-Type: application/json { "value": "Send", "context": "Updated context", "tags": ["ui", "forms", "updated"] } ``` --- #### Delete Key ```http DELETE /projects/{projectId}/keys/{keyId} ``` **Response:** `204 No Content` --- ### Translations #### Get Translation ```http GET /projects/{projectId}/keys/{keyId}/translations/{language} ``` **Response:** ```json { "key_id": "key_123", "language": "es", "value": "Enviar", "status": "translated", "translated_at": "2024-01-15T11:00:00Z" } ``` --- #### Update Translation ```http PUT /projects/{projectId}/keys/{keyId}/translations/{language} Content-Type: application/json { "value": "Enviar ahora" } ``` --- #### Get Missing Translations ```http GET /projects/{projectId}/missing?language=es ``` **Response:** ```json { "language": "es", "missing_count": 20, "keys": [ { "key": "checkout.title", "namespace": "checkout", "source_value": "Checkout" } ] } ``` --- #### Auto-Fix Missing Translations ```http POST /projects/{projectId}/auto-fix Content-Type: application/json { "language": "es" } ``` Uses AI to translate all missing keys. --- ### Languages #### Get Language Stats ```http GET /projects/{projectId}/languages ``` **Response:** ```json { "source_language": "en", "languages": [ { "code": "en", "name": "English", "total_keys": 156, "translated": 156, "progress": 100 }, { "code": "es", "name": "Spanish", "total_keys": 156, "translated": 136, "progress": 87 } ] } ``` --- #### Add Language ```http POST /projects/{projectId}/language-settings Content-Type: application/json { "language_code": "es", "language_name": "Spanish", "auto_translate": true } ``` **auto_translate:** If true, triggers AI translation of all existing keys. --- #### Bulk Add Languages ```http POST /projects/{projectId}/language-settings/bulk Content-Type: application/json { "languages": [ { "language_code": "es", "language_name": "Spanish" }, { "language_code": "fr", "language_name": "French" }, { "language_code": "de", "language_name": "German" } ], "auto_translate": true } ``` --- #### Auto-Translate Language ```http POST /projects/{projectId}/languages/{language}/translate ``` Translates all missing keys for the language. --- #### Remove Language ```http DELETE /projects/{projectId}/language-settings/{languageCode} ``` --- ### Import / Export #### Import Translations ```http POST /projects/{projectId}/import Content-Type: application/json { "format": "json", "language": "es", "namespace": "common", "data": { "key1": "value1", "key2": "value2" }, "options": { "replaceModified": false, "detectIcuPlurals": true, "preTranslateWithTM": true } } ``` **Formats:** json, yaml, xliff, po, csv, android, ios --- #### Upload File ```http POST /projects/{projectId}/import/upload Content-Type: multipart/form-data file: language: es namespace: common format: json ``` --- #### Preview Import ```http POST /projects/{projectId}/import/preview Content-Type: application/json { "format": "json", "language": "es", "data": { "key1": "value1" } } ``` **Response:** ```json { "new_keys": 15, "existing_keys": 10, "would_delete": 2, "preview": [ { "key": "key1", "action": "create", "value": "value1" }, { "key": "key2", "action": "update", "old": "old value", "new": "new value" } ] } ``` --- #### Export Translations ```http POST /projects/{projectId}/export Content-Type: application/json { "format": "json", "languages": ["es", "fr"], "namespaces": ["common", "checkout"], "branch": "main" } ``` **Response:** ```json { "operation_id": "exp_abc123", "status": "processing" } ``` --- #### Download Export ```http GET /projects/{projectId}/export/download?operation_id=exp_abc123 ``` **Response:** ZIP file with translations --- ### OTA (Over-The-Air Updates) #### List Releases ```http GET /projects/{projectId}/ota/releases ``` **Response:** ```json { "releases": [ { "id": "rel_abc123", "version": "1.0.0", "branch": "main", "platform": "all", "published_at": "2024-01-15T12:00:00Z" } ] } ``` --- #### Publish Release ```http POST /projects/{projectId}/ota/publish Content-Type: application/json { "version": "1.0.0", "branch": "main", "platform": "all", "min_app_version": "1.0.0", "max_app_version": "2.0.0" } ``` **Platforms:** all, ios, android, web **App version constraints:** Optional semver constraints for compatibility --- #### Delete Release ```http DELETE /projects/{projectId}/ota/releases/{releaseId} ``` --- #### Get Manifest (Public) ```http GET /ota/{projectId}/manifest ``` **No authentication required** - Used by SDKs **Response:** ```json { "latest_version": "1.0.0", "available_locales": ["en", "es", "fr"], "releases": [ { "version": "1.0.0", "platform": "all", "bundle_url": "/ota/{projectId}/bundle/rel_abc123" } ] } ``` **Rate limit:** 120 requests/minute per IP+project --- #### Get Bundle (Public) ```http GET /ota/{projectId}/bundle/{releaseId}?locale=es ``` **No authentication required** - Used by SDKs **Response:** Flattened JSON key-value pairs ```json { "button.submit": "Enviar", "checkout.title": "Pagar", "cart.total": "Total" } ``` --- ### Branches (Git-like Workflow) #### List Branches ```http GET /projects/{projectId}/branches ``` **Response:** ```json { "branches": [ { "id": "branch_main", "name": "main", "is_default": true, "total_keys": 156 }, { "id": "branch_staging", "name": "staging", "is_default": false, "total_keys": 162, "parent_branch": "main" } ] } ``` --- #### Create Branch ```http POST /projects/{projectId}/branches Content-Type: application/json { "name": "feature/new-checkout", "parent_branch": "main", "copy_translations": true } ``` --- #### Get Branch Diff ```http GET /projects/{projectId}/branches/{branchId}/diff ``` **Response:** ```json { "added": [ { "key": "checkout.express", "value": "Express Checkout" } ], "modified": [ { "key": "cart.total", "old": "Total", "new": "Order Total" } ], "removed": [ { "key": "cart.subtotal", "value": "Subtotal" } ] } ``` --- #### Merge Branch ```http POST /projects/{projectId}/branches/{branchId}/merge Content-Type: application/json { "target_branch": "main", "conflict_resolution": "keep-source" } ``` **Conflict resolution:** - `keep-source` - Use source branch values - `keep-target` - Use target branch values - `manual` - Requires manual resolution --- ### Email Templates #### List Templates ```http GET /projects/{projectId}/email-templates ``` --- #### Create Template ```http POST /projects/{projectId}/email-templates Content-Type: application/json { "slug": "welcome-email", "name": "Welcome Email", "subject": "Welcome to {company}!", "html": "...", "variables": ["name", "company"] } ``` --- #### Publish Template ```http POST /projects/{projectId}/email-templates/{templateId}/publish ``` --- #### Render Email ```http POST /projects/{projectId}/emails/render Content-Type: application/json { "slug": "welcome-email", "language": "es", "variables": { "name": "Juan", "company": "Acme Corp" } } ``` **Response:** ```json { "subject": "¡Bienvenido a Acme Corp!", "html": "..." } ``` --- ### Webhooks #### List Webhooks ```http GET /projects/{projectId}/webhooks ``` --- #### Create Webhook ```http POST /projects/{projectId}/webhooks Content-Type: application/json { "url": "https://example.com/webhook", "events": [ "translation.created", "translation.updated", "key.created" ], "secret": "webhook_secret_key" } ``` **Available events:** - `translation.created`, `translation.updated`, `translation.deleted` - `key.created`, `key.updated`, `key.deleted` - `language.added`, `language.removed` - `import.completed`, `export.completed` - `ota.published` --- #### Test Webhook ```http POST /projects/{projectId}/webhooks/{webhookId}/test ``` Sends a test payload to the webhook URL. --- ### Team Management #### List Team Members ```http GET /projects/{projectId}/team ``` **Response:** ```json { "members": [ { "user_id": "user_123", "email": "alice@example.com", "role": "admin", "joined_at": "2024-01-15T10:00:00Z" } ] } ``` **Roles:** owner, admin, member, viewer --- #### Invite Member ```http POST /projects/{projectId}/team/invites Content-Type: application/json { "email": "bob@example.com", "role": "member" } ``` --- #### Update Member Role ```http PUT /projects/{projectId}/team/members/{userId} Content-Type: application/json { "role": "admin" } ``` --- #### Remove Member ```http DELETE /projects/{projectId}/team/members/{userId} ``` --- ### Workflows (Enterprise) #### List Workflows ```http GET /projects/{projectId}/workflows ``` --- #### Create Workflow ```http POST /projects/{projectId}/workflows Content-Type: application/json { "name": "Translation Approval", "stages": [ { "name": "Review", "required_approvals": 1 }, { "name": "Final Approval", "required_approvals": 2 } ] } ``` --- #### Get Pending Approvals ```http GET /projects/{projectId}/workflows/pending ``` --- #### Approve Translation ```http POST /projects/{projectId}/translations/{translationId}/approve Content-Type: application/json { "comment": "Looks good!" } ``` --- #### Reject Translation ```http POST /projects/{projectId}/translations/{translationId}/reject Content-Type: application/json { "comment": "Needs revision", "reason": "grammar" } ``` --- ### API Keys #### List Project Keys ```http GET /projects/{projectId}/api-keys ``` --- #### Create Project Key ```http POST /projects/{projectId}/api-keys Content-Type: application/json { "name": "Production Key", "permissions": ["read", "write"] } ``` --- #### List Organization Keys ```http GET /api-keys ``` --- #### Create Organization Key ```http POST /api-keys Content-Type: application/json { "name": "CI/CD Key", "scope": "organization" } ``` --- #### Revoke Key ```http DELETE /api-keys/{keyId} ``` --- ### Error Responses All errors follow this format: ```json { "error": "Error message description" } ``` **Common status codes:** - `200` - Success - `201` - Created - `204` - No Content (successful delete) - `400` - Bad Request (invalid input) - `401` - Unauthorized (missing/invalid auth) - `403` - Forbidden (insufficient permissions) - `404` - Not Found - `429` - Rate Limit Exceeded - `500` - Internal Server Error --- ## Data Formats & Structures ### Translation File Formats #### Flat JSON ```json { "button.submit": "Submit", "button.cancel": "Cancel", "label.email": "Email Address", "checkout.title": "Checkout" } ``` #### Nested JSON ```json { "button": { "submit": "Submit", "cancel": "Cancel" }, "label": { "email": "Email Address" }, "checkout": { "title": "Checkout" } } ``` #### TypeScript ```typescript export default { button: { submit: "Submit", cancel: "Cancel" }, label: { email: "Email Address" } } as const; ``` --- ### ICU Message Format IntlPull supports **ICU MessageFormat** for advanced translations: #### Variables ```json { "greeting": "Hello, {name}!" } ``` **Usage:** `t('greeting', { name: 'Alice' })` → "Hello, Alice!" --- #### Plurals ```json { "items_count": "{count, plural, =0 {No items} one {# item} other {# items}}" } ``` **Usage:** - `t('items_count', { count: 0 })` → "No items" - `t('items_count', { count: 1 })` → "1 item" - `t('items_count', { count: 5 })` → "5 items" --- #### Select (Gender) ```json { "invitation": "{gender, select, male {He invited you} female {She invited you} other {They invited you}}" } ``` --- #### Number Formatting ```json { "price": "Total: {amount, number, currency}" } ``` **Usage:** `t('price', { amount: 99.99 })` → "Total: $99.99" --- #### Date Formatting ```json { "deadline": "Due: {date, date, short}" } ``` **Usage:** `t('deadline', { date: new Date() })` → "Due: 1/15/24" --- #### Combined Example ```json { "order_summary": "{name} ordered {count, plural, one {# item} other {# items}} for {total, number, currency}" } ``` **Usage:** ```javascript t('order_summary', { name: 'Alice', count: 3, total: 149.97 }) ``` **Output:** "Alice ordered 3 items for $149.97" --- ### Platform Overrides Different text for different platforms: ```json { "button.action": { "all": "Continue", "ios": "Tap to continue", "android": "Tap to continue", "web": "Click to continue" } } ``` When exporting for iOS: `"button.action": "Tap to continue"` When exporting for web: `"button.action": "Click to continue"` --- ### Namespace Organization Organize translations by feature area: ``` messages/ common/ en.json # Common UI elements es.json checkout/ en.json # Checkout flow es.json auth/ en.json # Authentication es.json ``` **Benefits:** - Lazy loading (load only needed namespaces) - Team collaboration (different features, different files) - Better performance (smaller bundles) --- ## Platform Features ### 1. Branches Git-like branching for translations. **Use cases:** - Test copy changes before production - A/B testing different messages - Seasonal campaigns (holiday promotions) - Regional variations **Workflow:** ```bash # Create branch npx @intlpullhq/cli upload --branch feature/new-checkout # Test changes npx @intlpullhq/cli download --branch feature/new-checkout # Merge to main # (via API or dashboard) ``` --- ### 2. Over-The-Air (OTA) Updates Update translations without app store releases. **Benefits:** - Fix typos instantly - A/B test copy changes - Seasonal updates (holiday greetings) - Regional customization **How it works:** 1. Change translations in IntlPull 2. Publish OTA release 3. SDK fetches updates automatically 4. Users see new text on next app open **SDK integration:** ```tsx import { IntlPullProvider } from '@intlpullhq/react'; ``` SDK automatically checks for updates and applies them. --- ### 3. Platform-Specific Text Different copy for iOS, Android, and Web. **Example:** - iOS: "Tap to continue" - Android: "Tap to continue" - Web: "Click to continue" **Implementation:** ```bash # Tag keys with platform npx @intlpullhq/cli upload --platform ios ``` **SDK automatically uses correct platform:** ```tsx // iOS app shows: "Tap to continue" // Web app shows: "Click to continue" const text = t('button.action'); ``` --- ### 4. Translation Memory Reuse previous translations for consistency. **Features:** - Automatic similarity matching - Context-aware suggestions - Quality scoring - Fuzzy matching **API usage:** ```http POST /organization/memory/search Content-Type: application/json { "text": "Submit form", "source_language": "en", "target_language": "es", "min_quality": 0.8 } ``` --- ### 5. Glossaries Ensure consistent terminology across translations. **Features:** - Organization and project-level glossaries - Case-sensitive/insensitive matching - Forbidden terms (don't translate) - Fuzzy matching **Example glossary:** ```json { "terms": [ { "source": "Submit", "target_es": "Enviar", "target_fr": "Envoyer", "case_sensitive": false }, { "source": "Brand Name", "forbidden": true, "note": "Never translate brand name" } ] } ``` --- ### 6. Workflows (Enterprise) Approval-based translation releases. **Features:** - Multi-stage approval process - Translation locks after approval - Digital signatures - Audit trail **Workflow example:** 1. Translator submits translation 2. Reviewer approves/rejects 3. Final approver signs off 4. Translation locks and publishes --- ## IDE & Tool Integrations ### Claude Code ```json // .claude/settings.json { "mcpServers": { "intlpull": { "command": "npx", "args": ["-y", "@intlpullhq/mcp-server"], "env": { "GEMINI_API_KEY": "your-api-key" } } } } ``` **Usage:** ``` > Use translate_file to translate my en.json to Spanish > Use npx @intlpullhq/cli upload to sync translations to the platform ``` --- ### Cursor IDE ```json // .cursor/settings.json { "mcp": { "servers": { "intlpull": { "command": "npx", "args": ["-y", "@intlpullhq/mcp-server"] } } } } ``` --- ### VS Code + GitHub Copilot Add to workspace tasks: ```json // .vscode/tasks.json { "tasks": [ { "label": "Upload Translations", "type": "shell", "command": "npx @intlpullhq/cli upload" }, { "label": "Download Translations", "type": "shell", "command": "npx @intlpullhq/cli download" } ] } ``` --- ### Generic MCP Integration Any tool supporting MCP can use IntlPull: ```json { "mcpServers": { "intlpull": { "command": "npx", "args": ["-y", "@intlpullhq/mcp-server"], "env": { "GEMINI_API_KEY": "your-api-key", "INTLPULL_API_KEY": "ip_live_xxxxx" } } } } ``` --- ## Common Workflows ### Workflow 1: Initial Setup ```bash # 1. Install CLI npm install -g @intlpullhq/cli # 2. Login npx @intlpullhq/cli login # 3. Initialize project npx @intlpullhq/cli init --framework next --library next-intl # 4. Create translation files (your i18n library handles this) # 5. Upload to IntlPull npx @intlpullhq/cli upload # 6. Add target languages (via dashboard or API) # 7. Download translations npx @intlpullhq/cli download ``` --- ### Workflow 2: Continuous Development ```bash # Enable watch mode intlpull listen ``` **What happens:** - Watches for translation changes on IntlPull - Downloads updated translations automatically - Updates local files in real-time --- ### Workflow 3: Feature Branch Development ```bash # Create feature branch git checkout -b feature/new-checkout # Upload translations to branch npx @intlpullhq/cli upload --branch feature/new-checkout # Download branch translations npx @intlpullhq/cli download --branch feature/new-checkout # Test changes # Merge via API when ready curl -X POST https://api.intlpull.com/api/v1/projects/{id}/branches/{id}/merge ``` --- ### Workflow 4: OTA Update ```bash # 1. Update translations via dashboard # 2. Publish OTA release via API curl -X POST https://api.intlpull.com/api/v1/projects/{id}/ota/publish \ -H "X-API-Key: ip_live_xxxxx" \ -H "Content-Type: application/json" \ -d '{ "version": "1.1.0", "branch": "main", "platform": "all" }' # 3. SDK automatically fetches updates # Users see new translations on next app open ``` --- ### Workflow 5: Import Existing Translations ```bash # Preview import intlpull import --file es.json --language es --preview # Import translations intlpull import --file es.json --language es # Or via API with multiple files curl -X POST https://api.intlpull.com/api/v1/projects/{id}/import \ -H "X-API-Key: ip_live_xxxxx" \ -H "Content-Type: application/json" \ -d '{ "format": "json", "language": "es", "data": {...} }' ``` --- ### Workflow 6: AI-Powered Translation **Using MCP Server:** ``` > Use translate_file to translate .intlpull-extracted-demo.json from English to Spanish, French, and German ``` **Using CLI:** ```bash # Auto-fix missing translations intlpull fix --language es ``` **Using API:** ```bash curl -X POST https://api.intlpull.com/api/v1/projects/{id}/auto-fix \ -H "X-API-Key: ip_live_xxxxx" \ -H "Content-Type: application/json" \ -d '{ "language": "es" }' ``` --- ## Authentication ### API Key Types #### Public API Keys (`intl_public_*`) - **Use:** Client-side SDKs (React, mobile apps) - **Permissions:** Read-only access to published translations - **Security:** Safe to expose in client code - **Rate limits:** 120 req/min per IP+project **Example:** ```tsx ``` --- #### User API Keys (`ip_live_*`) - **Use:** CLI, server-to-server, automation - **Permissions:** Full access to user's projects - **Security:** Keep secret, use in server environments - **Rate limits:** 1000 req/min **Example:** ```bash export INTLPULL_API_KEY=ip_live_secret123 npx @intlpullhq/cli upload ``` --- #### Project API Keys (`intl_*`) - **Use:** CI/CD pipelines, specific project access - **Permissions:** Limited to single project - **Security:** Keep secret, rotate regularly - **Rate limits:** 500 req/min **Example:** ```bash curl -H "X-API-Key: intl_project_abc123" \ https://api.intlpull.com/api/v1/projects/{id}/keys ``` --- ### JWT Authentication For web applications using Better Auth integration: ```http Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9... ``` **Token validation:** JWKS endpoint at `https://auth.intlpull.com/.well-known/jwks.json` --- ### Organization Roles | Role | Permissions | |------|-------------| | `owner` | Full access, billing, delete organization | | `admin` | Manage projects, members, settings | | `member` | Create/edit translations, view analytics | | `viewer` | Read-only access to translations | --- ## Rate Limits | Endpoint Type | Limit | Window | |---------------|-------|--------| | Public OTA API | 120 req | 1 minute per IP+project | | User API Keys | 1000 req | 1 minute | | Project API Keys | 500 req | 1 minute | | Anonymous | 10 req | 1 minute | **Rate limit headers:** ``` X-RateLimit-Limit: 1000 X-RateLimit-Remaining: 999 X-RateLimit-Reset: 1640000000 ``` **Rate limit exceeded:** ```json { "error": "Rate limit exceeded. Try again in 42 seconds." } ``` --- ## Support & Resources - **Documentation:** https://docs.intlpull.com - **API Status:** https://status.intlpull.com - **Support:** support@intlpull.com - **GitHub:** https://github.com/intlpull - **Discord:** https://discord.gg/intlpull --- ## Version History **v0.1.0** (January 2026) - Initial release - CLI with scan, upload, download, sync - React SDK with OTA support - MCP server for AI translations - DevTools for in-context editing - REST API (50+ endpoints) - 30+ languages support --- *Last updated: January 1, 2026*