REST API Reference
All Omnalingo REST routes are registered under the omnalingo/v1 namespace.
Base URL: https://yoursite.com/wp-json/omnalingo/v1/
Authentication
Section titled “Authentication”All endpoints require administrator capability (manage_options). Supported authentication methods:
- WordPress REST nonce (
X-WP-Nonceheader) — for requests from the admin UI - Application passwords (HTTP Basic Auth) — for external clients (WordPress 5.6+)
Response Envelope
Section titled “Response Envelope”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.
Settings
Section titled “Settings”GET /settings
Section titled “GET /settings”Returns the full plugin configuration.
Response: Full settings object (same structure stored in omnalingo_options).
POST /settings
Section titled “POST /settings”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"]}POST /settings/reset
Section titled “POST /settings/reset”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.
GET /settings/content-types
Section titled “GET /settings/content-types”Returns available WordPress post types and taxonomies for the content type selector in settings.
GET /settings/scan-roles
Section titled “GET /settings/scan-roles”Returns available WordPress user roles for the scan roles setting, including the special visitor pseudo-role.
GET /settings/cleanup/count
Section titled “GET /settings/cleanup/count”Returns counts of orphaned database records and whether automatic periodic cleanup is scheduled.
POST /settings/cleanup/execute
Section titled “POST /settings/cleanup/execute”Runs a one-time structural cleanup — removes dangling junction rows and broken pattern references without touching strings or translations. Returns row counts by category.
POST /settings/cleanup/schedule
Section titled “POST /settings/cleanup/schedule”Schedules a recurring structural cleanup every 30 days.
POST /settings/cleanup/unschedule
Section titled “POST /settings/cleanup/unschedule”Removes the scheduled recurring cleanup.
GET /settings/flagged-domains
Section titled “GET /settings/flagged-domains”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.
POST /settings/flagged-domains/cleanup
Section titled “POST /settings/flagged-domains/cleanup”Permanently deletes all strings and translations for the specified gettext domain.
Body: { "domain": "woocommerce" }
POST /settings/flagged-domains/dismiss
Section titled “POST /settings/flagged-domains/dismiss”Removes the flagged status from a domain’s strings without deleting them.
Body: { "domain": "woocommerce" }
POST /settings/language-packs
Section titled “POST /settings/language-packs”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"] }
GET /settings/language-packs/status
Section titled “GET /settings/language-packs/status”Returns current language pack download progress. Poll this during a download to update a progress indicator.
POST /settings/language-packs/clear
Section titled “POST /settings/language-packs/clear”Clears the language pack download status (call after displaying the completion message).
POST /settings/tours/complete
Section titled “POST /settings/tours/complete”Marks a guided tour as completed for the current user.
Body: { "tour": "tour_id" }
POST /settings/tours/reset
Section titled “POST /settings/tours/reset”Re-enables all guided tours for the current user by deleting their completion markers.
Content
Section titled “Content”GET /content
Section titled “GET /content”Returns a paginated list of indexed URLs with per-language translation status.
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
page | int | 1 | Page number |
per_page | int | 20 | Results per page |
type | string | '' | Filter by content type slug (page, product, category, etc.) |
status | string | '' | Filter by WordPress publish status |
translation | string | '' | Filter by translation status |
filter_languages | string | '' | Filter by language code |
orderby | string | 'default' | Sort field |
order | string | 'asc' | Sort direction |
search | string | '' | Title search |
Response: { "items": [...], "total": int, "pages": int }
GET /content/ids
Section titled “GET /content/ids”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, ... }] }
POST /content/custom-url
Section titled “POST /content/custom-url”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.
DELETE /content/{id}
Section titled “DELETE /content/{id}”Deletes a URL entry and all associated strings and translations. Strings that are not referenced by any other URL are also deleted.
Translation
Section titled “Translation”POST /content/{id}/translations
Section titled “POST /content/{id}/translations”Triggers AI translation for a single content item. The {id} is the Omnalingo URL ID (from /content), not the WordPress post ID.
Body:
| Field | Type | Required | Description |
|---|---|---|---|
language | string | yes | Target language code (e.g., de) |
skip_scan | bool | no | Skip the pre-translation scan (default: false) |
string_hashes | string[] | no | Translate 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.
POST /languages/{lang}/translations
Section titled “POST /languages/{lang}/translations”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 }
GET /languages/{lang}/translations/status
Section titled “GET /languages/{lang}/translations/status”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.
POST /translations/all
Section titled “POST /translations/all”Starts translation queues for all configured target languages.
Response: { "message": "...", "total": int, "target_languages": [...] }
GET /translations/all/status
Section titled “GET /translations/all/status”Returns combined status for all-languages translation. Also performs translation work (work-while-polling).
POST /translations/all/cancel
Section titled “POST /translations/all/cancel”Cancels the all-languages translation queue. Completed languages and partial progress are preserved.
Editor
Section titled “Editor”POST /editor/save
Section titled “POST /editor/save”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
hashavoids 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 }}GET /editor/strings?url_id={id}
Section titled “GET /editor/strings?url_id={id}”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").
POST /editor/resolve-image
Section titled “POST /editor/resolve-image”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": [...] }
POST /editor/pattern
Section titled “POST /editor/pattern”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 }
DELETE /editor/pattern/{id}
Section titled “DELETE /editor/pattern/{id}”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.
PATCH /editor/pattern/{id}/unsuppress
Section titled “PATCH /editor/pattern/{id}/unsuppress”Reactivates a suppressed auto-pattern.
POST /editor/pattern-impact
Section titled “POST /editor/pattern-impact”Preview how many existing strings a new pattern would match before creating it. Accepts the same body as POST /editor/pattern.
POST /editor/string/exempt
Section titled “POST /editor/string/exempt”Toggle pattern exemption for a string — excludes a specific string instance from matching a pattern.
Body: { "hash": "abc123...", "pattern_id": int, "exempt": true }
GET /editor/patterns
Section titled “GET /editor/patterns”Returns all patterns with summary data for the Pattern Manager view.
GET /editor/pattern/{id}/instances
Section titled “GET /editor/pattern/{id}/instances”Returns linked and excluded instance strings for a pattern. Used when expanding a pattern row in the Pattern Manager.
DELETE /editor/string/{id}
Section titled “DELETE /editor/string/{id}”Permanently deletes a string from the global string store — removes all URL mappings, all translations across all languages, and the string record itself.
Gather
Section titled “Gather”POST /gather/start
Section titled “POST /gather/start”Starts content gathering — indexes all public URLs on your site.
Response: { "message": "...", "status": { /* current progress */ } }
POST /gather/cancel
Section titled “POST /gather/cancel”Cancels a running gathering process. Already-indexed URLs are preserved.
GET /gather/status
Section titled “GET /gather/status”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.
POST /scan/start
Section titled “POST /scan/start”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"] }
POST /scan/cancel
Section titled “POST /scan/cancel”Cancels all pending scan jobs. Already-completed scans are preserved.
GET /scan/status
Section titled “GET /scan/status”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.
POST /scan/url
Section titled “POST /scan/url”Scans a single URL immediately using all configured scan roles.
Body: { "id": 42 } — the Omnalingo URL ID.
Response: { "item": { /* updated content item */ } }
License
Section titled “License”POST /license/save
Section titled “POST /license/save”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.
POST /license/disconnect
Section titled “POST /license/disconnect”Removes the stored API key and clears cached plan and quota data.
POST /client/refresh
Section titled “POST /client/refresh”Fetches fresh plan, quota, and usage data from Omnalingo’s cloud and resets the 12-hour auto-refresh timer.
String List
Section titled “String List”GET /string-list?url_id={id}
Section titled “GET /string-list?url_id={id}”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).