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)
- Request a login token:
action=query&meta=tokens&type=login - POST the token together with username & password to
action=login. - 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
opensearchautocomplete. - 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. Addingmaxlag=5tells the server you’ll wait up to five seconds for replication lag, preventing “Database busy” errors. - Respect
assertflags.assert=userorassert=botlet 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-Typeheader 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.