Skip to the content.

DevLokalize API

A read/write REST API for pulling and pushing translations programmatically — the same API the iOS and Android SDKs are built on. Available on the Pro plan, scoped to the project owner’s subscription (not the plan of individual project members).

Base URL: https://devlokalize.com

Authentication

All requests require a bearer token in the Authorization header:

Authorization: Bearer dl_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Generate a token from Account → API tokens. Tokens are shown once at creation — store them securely (environment variable, CI secret, or your app’s secure storage). A token acts as its owning user for permission purposes: it can only read/write projects that user is a member of, at whatever role they hold on that project.

Rate limits

60 requests per minute per token. Responses that exceed the limit return 429 with a Retry-After header (seconds).

Errors

All error responses are {"error": "human-readable message"} with an appropriate HTTP status:

Status Meaning
401 Missing or invalid token
403 Valid token, but the project owner isn’t on the Pro plan, or the token’s user lacks permission for the action
404 Project, component, or language not found (also returned for private projects the token’s user can’t view, to avoid leaking existence)
429 Rate limit exceeded

Endpoints

GET /api/v1/projects/{slug}/bundle/{language}

Fetch every approved translation across every component in a project, for one language, in a single call. This is what the mobile SDKs use — it’s the right endpoint for “give my app everything it needs to display in French.”

Only APPROVED translations are included. A key with no approved translation is simply omitted from the response — callers should fall back to their own bundled default for anything missing, rather than showing an unreviewed string to end users.

Response

{
  "project": "my-app",
  "language": "fr",
  "components": {
    "homepage": {
      "hero.title": "Bienvenue",
      "hero.cta": "Commencer"
    },
    "settings": {
      "settings.title": "Paramètres"
    }
  }
}

GET /api/v1/projects/{slug}/{component}/{language}

Fetch every string in one component for one language, including its translation status — useful for building a review tool or syncing a single resource file, where you need more than just the approved text.

Response

{
  "component": "homepage",
  "language": "fr",
  "strings": [
    { "key": "hero.title", "source": "Welcome", "translation": "Bienvenue", "status": "APPROVED" },
    { "key": "hero.cta", "source": "Get started", "translation": "", "status": "UNTRANSLATED" }
  ]
}

POST /api/v1/projects/{slug}/{component}/{language}

Submit translations for one component/language. Requires contribute permission on the project. Translations from a trusted contributor (reviewer or maintainer role) are marked APPROVED immediately; everyone else’s submissions are marked NEEDS_REVIEW.

Request body

{
  "translations": {
    "hero.title": "Bienvenue",
    "hero.cta": "Commencer"
  }
}

Response

{ "updated": ["hero.title", "hero.cta"], "skipped": [] }

Keys that don’t exist in the component, or whose value isn’t a string, are returned in skipped rather than causing the whole request to fail.

SDKs

Both SDKs are read-only: they call the bundle endpoint, cache the result on-device, and expose a simple string lookup. They never write back to your project — use the REST API directly (or the web editor) for that.