Issue Nº 43 — Sep 25, 2026

A bare Origin header gets no CORS headers at all

Issue forty-three covers wiktionary, a keyless dictionary API in the Dictionaries category. This session queried it live. The action API only sends CORS headers when the request carries an explicit origin=* parameter. Titles are case-sensitive, unlike Wikipedia. And the REST definition endpoint answers from a 14-day edge cache, while the action API answers with no caching at all.

Titles are case-sensitive, unlike Wikipedia

This session sent GET https://en.wiktionary.org/w/api.php?action=query&titles=hello&format=json. It returned pageid 4803 for the page titled "hello".

This session then sent the same request with titles=Hello. It returned no pageid, only a -1 placeholder key and a missing flag.

Wiktionary turns off first-letter capitalization for page titles. Wikipedia uppercases the first letter, so hello and Hello are the same page there. A Wikipedia query for titles=hello returned a normalized entry from "hello" to "Hello" and pageid 6710844. A client that reuses Wikipedia title-handling code against Wiktionary will miss entries that start with a lowercase letter.

The action API needs origin=*; a bare Origin header gets nothing

This session sent GET https://en.wiktionary.org/w/api.php?action=query&titles=hello&format=json with an Origin: https://example.com header and no origin query parameter. The response carried no access-control-allow-origin header at all, only cache-control: private, must-revalidate, max-age=0.

This session repeated the same request with &origin=* appended to the query string. The response then carried access-control-allow-origin: * and access-control-allow-credentials: false.

So a browser page that calls the action API cross-origin must add origin=* to the URL. Setting an Origin request header, which browsers do automatically, is not enough on its own.

The REST endpoint behaves differently here: this session sent GET https://en.wiktionary.org/api/rest_v1/page/definition/hello with no origin parameter at all, and it still returned access-control-allow-origin: *. The two endpoint families disagree on what unlocks CORS.

REST definitions are edge-cached HTML wrapped in JSON; the action API isn't cached

This session sent GET https://en.wiktionary.org/api/rest_v1/page/definition/hello. Each definition string held markup, for example <span class="use-with-mention">...<a rel="mw:WikiLink" href="/wiki/greeting#English">greeting</a>...</span>. A caller expecting plain text has to strip HTML first.

The response headers read cache-control: s-maxage=1209600, max-age=0, must-revalidate and x-cache-status: hit-front. 1,209,600 seconds is 14 days: Wikimedia's edge served this from a two-week cache, not from a fresh render.

The action API's action=query response, by contrast, came back private, must-revalidate, max-age=0: no shared caching at all.

The REST spec at /api/rest_v1/?spec labels /page/definition/{term} "Experimental" and rates it stable under Wikimedia's endpoint stability policy. It is not one of the math-rendering routes that spec actually marks deprecated.

Wikimedia's REST API page calls RESTBase, the technology behind this API, "being deprecated". So this endpoint may change, even though the spec does not mark it deprecated yet.

Wiktionary, by the numbers

Rendered live from the atlas entry
AuthenticationNone required
HTTPSSupported
CORSEnabled
PricingFree
FormatsJSON, XML
Rate limit

Wikimedia guidance: unauthenticated clients should stay below 5 requests/second (concurrency 1), authenticated clients up to 10 requests/second (concurrency 3)

Key endpoints
  • GET/api.php?action=query&titles={title}&format=json
wikidictionarymultilingualopen-datamediawiki

Sources

Facts checked Sep 2026