Skip to content

REST API Reference

All Omnalingo REST routes are registered under the omnalingo/v1 namespace.

Base URL: https://yoursite.com/wp-json/omnalingo/v1/


All endpoints require administrator capability (manage_options). Supported authentication methods:

  • WordPress REST nonce (X-WP-Nonce header) — for requests from the admin UI
  • Application passwords (HTTP Basic Auth) — for external clients (WordPress 5.6+)

Every endpoint returns the same JSON envelope:

// Success (HTTP 200 unless noted otherwise)
{ "success": true, "data": { ... } }
// Error (HTTP 4xx or 5xx)
{ "success": false, "code": "snake_case_code", "message": "Human-readable description" }

An optional "unrecoverable": true key appears on 401/403 errors from translation API calls. Use this to abort queued translation requests immediately without retrying.


Returns the full plugin configuration.

Response: Full settings object (same structure stored in omnalingo_options).


Saves settings. Accepts a partial settings object — fields not included are left unchanged. After saving, language tables are synced and any missing WordPress language packs are downloaded automatically.

Response:

{
"message": "Settings saved successfully.",
"data": { /* full new settings */ },
"addedLanguages": ["de_DE"]
}

Factory reset. Resets all settings to defaults, drops and recreates all Omnalingo database tables, and removes all plugin data (preserving only the API key). Triggers an automatic content gathering run.


Returns available WordPress post types and taxonomies for the content type selector in settings.


Returns available WordPress user roles for the scan roles setting, including the special visitor pseudo-role.


Returns counts of orphaned database records and whether automatic periodic cleanup is scheduled.


Runs a one-time structural cleanup — removes dangling junction rows and broken pattern references without touching strings or translations. Returns row counts by category.


Schedules a recurring structural cleanup every 30 days.


Removes the scheduled recurring cleanup.


Returns gettext text domains that have been flagged as orphaned (from deactivated plugins or theme switches). Each entry includes the domain name, string count, reason, and timestamp.


Permanently deletes all strings and translations for the specified gettext domain.

Body: { "domain": "woocommerce" }


Removes the flagged status from a domain’s strings without deleting them.

Body: { "domain": "woocommerce" }


Downloads WordPress .mo language pack files for the specified locales (WordPress core, active plugins, active theme). Runs synchronously — the response is returned after all downloads complete.

Body: { "locales": ["de_DE", "fr_FR"] }


Returns current language pack download progress. Poll this during a download to update a progress indicator.


Clears the language pack download status (call after displaying the completion message).


Marks a guided tour as completed for the current user.

Body: { "tour": "tour_id" }


Re-enables all guided tours for the current user by deleting their completion markers.


Returns a paginated list of indexed URLs with per-language translation status.

Query parameters:

ParameterTypeDefaultDescription
pageint1Page number
per_pageint20Results per page
typestring''Filter by content type slug (page, product, category, etc.)
statusstring''Filter by WordPress publish status
translationstring''Filter by translation status
filter_languagesstring''Filter by language code
orderbystring'default'Sort field
orderstring'asc'Sort direction
searchstring''Title search

Response: { "items": [...], "total": int, "pages": int }


Same filters as /content but returns all matching IDs without pagination. Use for bulk operations that need to target all results across pages.

Response: { "items": [{ "id": int, ... }] }


Adds a custom URL to the content index — useful for 404 pages, custom templates, or any URL not tied to a WordPress post or term.

Body: { "url": "/custom-path/", "title": "Custom Page" }

The URL is normalized to relative with leading and trailing slashes. Returns HTTP 201 on success, 409 if the URL already exists.


Deletes a URL entry and all associated strings and translations. Strings that are not referenced by any other URL are also deleted.


Triggers AI translation for a single content item. The {id} is the Omnalingo URL ID (from /content), not the WordPress post ID.

Body:

FieldTypeRequiredDescription
languagestringyesTarget language code (e.g., de)
skip_scanboolnoSkip the pre-translation scan (default: false)
string_hashesstring[]noTranslate only these specific strings (empty = all untranslated)

Response:

{
"translated": 45,
"total": 45,
"words_translated": 380,
"message": "Translation completed successfully",
"translations": { /* per-language translation status */ },
"quota": { /* updated plan quota */ },
"errors": [ /* any partial failure errors */ ]
}

401/403 responses include "unrecoverable": true — use this signal to abort any queued translation requests.


Starts a translation queue for all untranslated content in the specified language. Returns immediately; processing happens during subsequent status polls.

URL parameter: {lang} must match [a-z]{2}(_[A-Z]{2})? (e.g., de, fr, de_DE).

Body (optional): { "force_rescan": false }

Response: { "message": "...", "total": int }


Returns current queue status and performs translation work during the request (work-while-polling).

Response:

{
"status": "running",
"progress": 65,
"processed": 130,
"total": 200,
"updated_items": [...],
"quota": { /* updated quota */ }
}

Polling guidance: Poll every 2–3 seconds. Each poll performs up to several seconds of translation work. Polling faster does not speed up translation.


POST /languages/{lang}/translations/cancel

Section titled “POST /languages/{lang}/translations/cancel”

Cancels the running translation queue for the language. Already-completed translations are preserved.


Starts translation queues for all configured target languages.

Response: { "message": "...", "total": int, "target_languages": [...] }


Returns combined status for all-languages translation. Also performs translation work (work-while-polling).


Cancels the all-languages translation queue. Completed languages and partial progress are preserved.


Saves manual translations from the visual editor or string list.

Body:

{
"contentId": 42,
"items": [
{
"original": "About Us",
"hash": "abc123...",
"type": "html",
"translations": {
"de": "Über uns",
"fr": "À propos de nous"
}
},
{
"original": "Add to cart",
"domain": "woocommerce",
"context": "",
"type": "gettext",
"translations": {
"de": "In den Warenkorb"
}
}
]
}

Notes:

  • Translation keys are language slugs (e.g., de), not locale codes (e.g., de_DE).
  • An empty string value for a translation deletes that translation row.
  • Providing hash avoids entity-encoding mismatches between what the editor renders and what is stored.

Response:

{
"message": "Translations saved.",
"count": 2,
"progress_by_lang": { "de": 85, "fr": 70 },
"untranslated_by_lang": { "de": 12, "fr": 30 }
}

Returns all strings mapped to a URL with their translations across all target languages. Database-only — does not trigger a scan.

Response: { "strings": { "hash": { "id": int, "original": "...", "type": "html|gettext|pattern", "translations": {...} } } }

For gettext strings, .mo file translations are included where no DB override exists (shown as "translated_by": "gt").


Resolves a WordPress attachment from an image URL. Used by the visual editor to display image dimensions and srcset data.

Body: { "url": "https://site.com/wp-content/uploads/image.jpg" }

Response: { "attachmentId": 42, "fullUrl": "...", "srcset": "...", "sizes": [...] }


Creates a translation pattern. Patterns are templates for strings that contain dynamic values — for example, %1$s items in your cart captures any quantity.

Body:

{
"original_string": "42 items in your cart",
"skeleton": "%1$s items in your cart",
"source": "manual",
"placeholder_meta": [
{ "position": 1, "name": "count", "type": "numerical", "multi_word": false }
]
}

Returns HTTP 409 with "collision": true if an existing pattern’s regex overlaps with this one.

Response: { "pattern_id": int, "skeleton": "...", "canonical_hash": "...", "linked_count": int }


Deletes or suppresses a pattern. Manual patterns are hard-deleted. Auto-detected patterns are suppressed to prevent re-creation on the next scan. Pass ?force_delete=1 to always hard-delete.


Reactivates a suppressed auto-pattern.


Preview how many existing strings a new pattern would match before creating it. Accepts the same body as POST /editor/pattern.


Toggle pattern exemption for a string — excludes a specific string instance from matching a pattern.

Body: { "hash": "abc123...", "pattern_id": int, "exempt": true }


Returns all patterns with summary data for the Pattern Manager view.


Returns linked and excluded instance strings for a pattern. Used when expanding a pattern row in the Pattern Manager.


Permanently deletes a string from the global string store — removes all URL mappings, all translations across all languages, and the string record itself.


Starts content gathering — indexes all public URLs on your site.

Response: { "message": "...", "status": { /* current progress */ } }


Cancels a running gathering process. Already-indexed URLs are preserved.


Returns gathering progress and performs a batch of gathering work if active (work-while-polling).

Optional query parameters: page, per_page, type — returns a content list page alongside the status, eliminating a separate /content request during gathering.


Schedules scan jobs for all indexed URLs using all configured scan roles.

Body (optional): { "rescan": false } — pass true to rescan already-scanned URLs.

Response: { "message": "...", "scheduled": int, "roles": ["visitor", "administrator"] }


Cancels all pending scan jobs. Already-completed scans are preserved.


Returns current scan queue status and processes scan work unless ?skip_work=1 is passed.

Response:

{
"status": "running",
"scanned_urls": 84,
"total_urls": 200,
"error_urls": 2,
"pending_urls": 116,
"total_words": 12500,
"next_items": [...],
"last_scan_timestamp": "2025-01-15T10:30:00Z"
}

Pass ?skip_work=1 when the browser is performing direct scans to avoid processing the same URLs simultaneously.


Scans a single URL immediately using all configured scan roles.

Body: { "id": 42 } — the Omnalingo URL ID.

Response: { "item": { /* updated content item */ } }


Saves the Omnalingo API key. For manually entered keys, verifies the key against Omnalingo’s cloud before saving.

Body: { "api_key": "omna-xxxx..." }

Keys must start with omna-. Returns 403 if remote verification fails.


Removes the stored API key and clears cached plan and quota data.


Fetches fresh plan, quota, and usage data from Omnalingo’s cloud and resets the 12-hour auto-refresh timer.


Returns all translatable strings for a URL. Unlike /editor/strings, this endpoint triggers a live scan of the page first, then merges the result with previously stored strings and their translations.

This is the endpoint used by the string list editor view. It can take 5–15 seconds on pages with slow generation times (heavy caching plugins, external API calls in the page template).

Response:

{
"strings": [
{
"original": "About Us",
"hash": "abc123...",
"type": "html",
"word_count": 2,
"translations": {
"de": { "translated_string": "Über uns", "translated_by": "ai" }
},
"_previouslyFound": false
}
],
"meta": {
"url_id": 42,
"title": "About Us",
"url": "/about/",
"total_strings": 45
},
"translator_names": { "5": "Jane Smith" }
}

translated_by values: "ai" (AI-generated), "gt" (from .mo file), or a user ID string (manual edit by that user).