Mastering MediaWiki API for Custom Integrations

Why the MediaWiki Action API matters

If you’ve ever tinkered with a wiki‑powered site and felt the urge to pull data into a dashboard, push alerts to Slack, or bulk‑update pages from a spreadsheet, the MediaWiki Action API is the bridge you’ve been looking for. It isn’t a fancy “magic” layer – it’s a well‑documented HTTP endpoint that lets you query, edit, and manage anything you’d normally do through the web UI. Think of it as the hidden control panel behind every Wikipedia article, ready to be repurposed for your own custom integration.

Getting your hands on the endpoint

The base URL is usually https://your‑wiki.org/w/api.php. Append query string parameters to tell the API what you need. A minimal request looks like this:

curl "https://example.org/w/api.php?action=query&list=allpages&aplimit=10&format=json"

That single line returns a JSON object with ten page titles – enough to verify you can reach the server.

Authentication in a nutshell

Read‑only calls (like the query module above) need no login. The moment you want to write – creating a page, uploading a file, adjusting user options – you must prove who you are.

Login flow (modern token‑based)

  1. Request a login token: action=query&meta=tokens&type=login
  2. POST the token together with username & password to action=login.
  3. For every write operation, fetch a CSRF (edit) token: action=query&meta=tokens&type=csrf.

Here’s a quick PHP example using cURL (the language hint helps editors apply syntax highlighting):

<?php
$api = 'https://example.org/w/api.php';
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_URL, $api . '?action=query&meta=tokens&type=login&format=json');
$loginToken = json_decode(curl_exec($ch), true)['query']['tokens']['logintoken'];

// now send credentials
$post = [
'action' => 'login',
'lgname' => 'MyBot',
'lgpassword'=> 's3cr3t',
'lgtoken' => $loginToken,
'format' => 'json'
];
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
$response = curl_exec($ch);
echo $response;
?>

Notice the extra assert=user flag you can tack on to force the API to reject the request if you’re not logged in – a tiny safety net that can save a lot of headache.

Core modules you’ll use most

MediaWiki’s API is split into “modules”. Each one does a specific job. Below is a cheat‑sheet of the “must‑know” group for custom integrations.

  • query – fetch pages, users, revisions, or any meta‑data.
  • edit – create or modify page wikitext.
  • upload – send files to the wiki’s file repository.
  • search – full‑text search, plus the handy opensearch autocomplete.
  • list – get enumerations such as allusers, categorymembers, recentchanges.
  • meta – site‑wide settings, siteinfo, token retrieval.

Example: Pulling the latest 5 revisions of a page

The following call grabs revision IDs, timestamps, and contributor names for “Main Page”.

curl "https://example.org/w/api.php?action=query&prop=revisions&titles=Main%20Page&rvlimit=5&rvprop=ids|timestamp|user&format=json"

In practice you’ll pipe that JSON into a parser – maybe jq for a quick prototype, or a full‑blown PHP/Node module for production.

Handling pagination – the “continue” parameter

Many list‑type modules cap results (often at 500 for bots, 50 for ordinary users). When you need more than the limit, the API returns a continue token. You simply feed it back on the next request.

It looks like this in raw JSON:

{
"continue": {
"apcontinue":"123456|Some_page",
"continue":"||"
},
"query": { … }
}

Then your next request adds apcontinue=123456|Some_page. This pattern repeats until the continue block disappears. It’s easy to loop over in any language; just watch out for infinite loops if you forget to update the token.

Parsing wikitext without saving

Sometimes you need to render a fragment to HTML for a preview pane. The parse module does exactly that, without touching the database.

curl -X POST -d "action=parse&title=Demo&text==Heading%0AThis%20is%20*bold*." https://example.org/w/api.php?format=json

The response includes parse.text.* – ready to drop into a <div> on your frontend.

Uploading a file

Uploading is a two‑step dance: get an edit token, then POST the file along with the token and a descriptive comment.

<?php
$token = getCsrfToken(); // assume you have a helper
$ch = curl_init('https://example.org/w/api.php');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
'action' => 'upload',
'filename' => 'example.png',
'file' => new CURLFile('/path/to/example.png'),
'comment' => 'Adding illustration for article',
'token' => $token,
'format' => 'json'
]);
$result = curl_exec($ch);
echo $result;
?>

Notice the use of CURLFile – a small detail that trips novices. Also, keep in mind the wiki’s uploadsize limit and the fileextensions whitelist.

Best practices – what the docs whisper

Even though the API feels like a loose set of endpoints, the MediaWiki community has codified a set of etiquette rules. Ignoring them may get you a 429 “Too many requests” or, worse, a permanent block.

  • Rate‑limit yourself. Aim for no more than one request per second unless you’ve asked for a higher quota.
  • Use maxlag. Adding maxlag=5 tells the server you’ll wait up to five seconds for replication lag, preventing “Database busy” errors.
  • Respect assert flags. assert=user or assert=bot let you double‑check your session role.
  • Cache results locally. Anything that can be cached – siteinfo, token fetches, static page content – should be, to reduce load.

Going deeper – custom extensions and API modules

If the built‑in modules don’t cut it, you can write your own. MediaWiki extensions can register new API modules via PHP classes that extend ApiBase. This is how projects like VisualEditor expose their rich editing capabilities.

A minimal skeleton looks like this:

class ApiMyCustom extends ApiBase {
public function execute() {
$param = $this->getParameter('myparam');
// Do something interesting…
$result = ['status' => 'ok', 'value' => $param];
$this->getResult()->addValue(null, 'mycustom', $result);
}
public function getAllowedParams() {
return ['myparam' => ['type' => 'string', 'required' => true]];
}
}

After registering the class in extension.json, you can call it just like any core module: action=mycustom&myparam=hello. The flexibility is impressive – you can hook into the same token, permission, and throttling infrastructure the core already provides.

Debugging tips you’ll thank yourself for

When something goes sideways, the API usually spits out an error object. Don’t ignore it.

{
"error": {
"code":"badtoken",
"info":"The token you provided is invalid."
}
}

Common pitfalls:

  • Forgotten format=json – you’ll get HTML back, which is hard to parse.
  • Mismatched Content-Type header when uploading – the server expects multipart/form‑data.
  • Stale CSRF token after a long pause – always fetch a fresh token right before a write.

A handy trick: add &debug=1 to any request, and the response will include a query-continue section and the raw query string the server interpreted. It’s like peeking into the API’s mind.

Wrapping it up

Mastering the MediaWiki Action API isn’t about memorizing every module; it’s about understanding the request‑response rhythm, handling tokens responsibly, and respecting the server’s limits. Once you have that foundation, the sky’s the limit – from syncing wiki content into a knowledge‑graph to building bots that keep documentation fresh. The API is sturdy, well‑documented, and, thanks to its extensibility, ready to grow alongside your own projects.

Take a moment, fire up a curl command, and watch JSON flow. That tiny snippet is the first step toward custom integrations that feel native, performant, and, most importantly, reliable.

Subscribe to MediaWiki Tips and Tricks

Don’t miss out on the latest articles. Sign up now to get access to the library of members-only articles.
jamie@example.com
Subscribe