w Docs

REST API

2 min readUpdated November 9, 2026

All endpoints are public and read-only. Because a REST request has no page of its own, each one takes:

  • from: the URL of the page you are asking about (default: the home page). Only URLs on your own site are accepted; others return an error 400.
  • lang: the language of that page, when you know it (an enabled language code). Pass it on sites that use a domain or a ?lang= parameter per language.
Endpoint Returns Caching
GET /wp-json/cls/v1/languages Every enabled language with its URL for the page, plus current, default and display_mode Public, 5 minutes
GET /wp-json/cls/v1/current The page’s language: code, label, label_en, flag_url, rtl Public
GET /wp-json/cls/v1/switch/{code} One language’s URL for the page: code, label, label_en, flag_url, url, active, rtl. A code that is not enabled returns 404 with enabled_codes Public
GET /wp-json/cls/v1/geo Suggestions for the visitor making the request: country, source, current, geo, browser Never cached

With plain permalinks, use /?rest_route=/cls/v1/languages instead of /wp-json/cls/v1/languages.

Example: the French URL of the About page

curl "https://example.com/wp-json/cls/v1/switch/fr?from=https://example.com/about/"
{
  "code": "fr",
  "label": "Français",
  "label_en": "French",
  "flag_url": "https://example.com/wp-content/plugins/language-switcher-pro/assets/flags/64/fr.png",
  "url": "https://example.com/fr/about/",
  "active": false,
  "rtl": false
}

Example: /geo for a visitor from Germany on an English page

{
  "country": "DE",
  "source": "cloudflare",
  "current": "en",
  "geo": {
    "code": "de", "label": "Deutsch", "label_en": "German",
    "url": "https://example.com/de/about/", "flag": "…/de.png", "rtl": false,
    "message": "Möchten Sie diese Website auf Deutsch ansehen?", "dismiss": "Nein danke"
  },
  "browser": null
}

geo and browser are null when there is nothing to suggest, or when the visitor already chose a language.