wikimedia-url-shortener · git:20260813.957079d · 2026-08-13 · sha256 300e49f0e327cde5

wikimedia-url-shortener git:20260813.957079dA

Immutable. This exact content never changes and is served at /api/v1/blob/300e49f0e327cde5.

---
name: wikimedia-url-shortener
description: Create and expand w.wiki short URLs (Wikimedia's URL shortener) — redirect behavior, the missing expansion API, the browser CORS trap, server-side resolution patterns, and creation via the meta.wikimedia.org API
license: MIT
compatibility: opencode
depends_on: [wikimedia-api-access, wikimedia-auth-oauth]
skill_discovery_hints:
  - keywords: ["w.wiki", "short URL", "URL shortener", "shorten link", "shortlink", "Wikimedia URL Shortener", "UrlShortener"]
  - keywords: ["expand short url", "resolve redirect", "w.wiki api", "shortenurl"]
  - keywords: ["QR code", "qrcode", "special:urlshortener"]
last_verified: 2026-08-12
---

# Wikimedia URL Shortener (w.wiki)

> ⚠️ **User-Agent required:** All requests to `w.wiki` and `meta.wikimedia.org`
> need a descriptive User-Agent. See the
> **[wikimedia-api-access](../wikimedia-api-access/SKILL.md)** skill.

## What It Is

**w.wiki** is the Wikimedia Foundation's URL shortener, built on the
[Extension:UrlShortener](https://www.mediawiki.org/wiki/Extension:UrlShortener)
extension. Short URLs look like `https://w.wiki/TR9R` (or bare `w.wiki/TR9R`)
and **301-redirect** to the target URL.

- **Create** short URLs at `https://meta.wikimedia.org/wiki/Special:UrlShortener`
  or via the API (below). Requires edit rights on Meta-Wiki.
- **Expand** a short URL: **there is no expansion API** (see Gotcha 1) — the
  only way is to follow the redirect.
- **QR code** for any URL: `https://meta.wikimedia.org/wiki/Special:QrCode?url=<url>`
  (302s to a PNG).

## Quick Reference

| Task | Method |
|---|---|
| Expand a short URL (server-side) | `curl -sI https://w.wiki/CODE` → read `location:` header (or `curl -sL` to follow) |
| Expand in Node | `await fetch(url)` — `resp.url` is the final target after redirects |
| Expand in Python | `requests.head(url, allow_redirects=True)` → `resp.url` |
| Create (API) | `POST https://meta.wikimedia.org/w/api.php?action=shortenurl&url=...&format=json` (auth required) |
| Create (UI) | `https://meta.wikimedia.org/wiki/Special:UrlShortener` |
| QR code | `https://meta.wikimedia.org/wiki/Special:QrCode?url=<encoded>` |
| Manage short URLs | `https://meta.wikimedia.org/wiki/Special:ManageShortUrls` |

## Verified Facts (2026-08-12)

- `https://w.wiki/TR9R` → **301** → `https://commons.wikimedia.org/wiki/Commons:WikiPortraits/Bento-demo.json`.
- The 301 response carries `access-control-allow-origin: *`, but the **target
  page sends no CORS headers** — see Gotcha 2 for why browser-side expansion
  fails.
- **No API on w.wiki itself**: `https://w.wiki/api.php?...` is treated as a
  *short code* and returns an HTML "Wikimedia Error / Short URL Not Found"
  page. The `action=shortenurl` API module lives on **meta.wikimedia.org**
  (verified via `action=paraminfo&modules=shortenurl`), not w.wiki.
- `shortenurl` params: `url` (required, string), `qrcode` (boolean).
- Rate limits (per meta.wikimedia.org/wiki/Wikimedia_URL_Shortener):
  **10 creations / 2 minutes** for IPs, **50 / 2 minutes** for logged-in users.
- `Special:UrlShortener` (HTTP 200) and `Special:QrCode?url=...` (HTTP 302 →
  QR PNG) both exist on meta.

## Gotchas (don't rediscover these)

1. **There is no way to "look up" a w.wiki code without following the
   redirect.** No expansion endpoint exists — not on w.wiki, not in the API.
   The extension docs mention `action=shortenurl` (creation only). Expand by
   following the redirect and reading the final URL.

2. **Browsers cannot expand w.wiki links to wiki pages.** `fetch('https://w.wiki/CODE')`
   in a browser fails with `TypeError: Failed to fetch`: the browser follows
   the 301 (whose own response is CORS-permitted), then the target page
   (e.g. `commons.wikimedia.org`) sends **no CORS headers**, so the final
   response is blocked. `redirect: 'manual'` gives an opaque response with no
   readable `Location` header. **Fix:** expand server-side (curl / Node /
   Python), or add a same-origin resolver endpoint to your own server that
   follows the redirect and returns the final URL as JSON (see
   `deploy/server.js` `/api/resolve` in the WikiBento project for a working
   Node 20 zero-dependency implementation).

3. **w.wiki is not a MediaWiki API surface.** Anything under `w.wiki/` is
   interpreted as a short code — `api.php`, `w/`, etc. all 404 with "Short URL
   Not Found". Route API calls to meta.wikimedia.org instead.

4. **Creating short URLs requires authentication** (edit rights on Meta-Wiki)
   and the action is a write op: use POST with a CSRF token (see
   [wikimedia-auth-oauth](../wikimedia-auth-oauth/SKILL.md)). Anonymous POST
   returns a generic Wikimedia Error page, not JSON.

5. **Rate limits are per-user/IP and low** (10/2 min anon). For bulk
   shortening, batch is not a thing here — pace requests or use the UI.

## SOP 1: Expand a w.wiki Short URL

### curl (read the Location header — no body fetched)

```bash
curl -sI "https://w.wiki/TR9R" | grep -i '^location:'
# location: https://commons.wikimedia.org/wiki/Commons:WikiPortraits/Bento-demo.json
```

### Node (browser-unavailable; server-side only)

```javascript
const resp = await fetch('https://w.wiki/TR9R', { redirect: 'follow' });
console.log(resp.url); // final URL after redirects
```

### Python

```python
import requests
resp = requests.head('https://w.wiki/TR9R', allow_redirects=True, timeout=15)
print(resp.url)  # final URL after redirects
```

### Browser (the CORS trap — needs a server-side helper)

A browser `fetch()` cannot read the target (Gotcha 2). Pattern that works:
your own server exposes `GET /api/resolve?url=<https-url>`, follows the
redirect server-side, and returns `{"url": "<final>"}`; the client then
fetches the target through a CORS-enabled path (e.g. the MediaWiki Action
API `action=parse&prop=wikitext&origin=*` for wiki pages). See the WikiBento
`src/lib/share.js` + `deploy/server.js` for a tested reference implementation.

## SOP 2: Create a Short URL (API)

Requires a logged-in session with edit rights on meta.wikimedia.org.

```bash
# 1. Get a CSRF token
TOKEN=$(curl -s "https://meta.wikimedia.org/w/api.php?action=query&meta=tokens&type=csrf&format=json" \
  -b cookies.txt -A "$WIKIMEDIA_USER_AGENT" | python3 -c "import json,sys; print(json.load(sys.stdin)['query']['tokens']['csrftoken'])")

# 2. Shorten
curl -s -X POST "https://meta.wikimedia.org/w/api.php?action=shortenurl&format=json" \
  -b cookies.txt -A "$WIKIMEDIA_USER_AGENT" \
  --data-urlencode "url=https://commons.wikimedia.org/wiki/Commons:WikiPortraits/Bento-demo.json" \
  --data-urlencode "token=$TOKEN"
# → { "shortenurl": { "shorturl": "https://w.wiki/XXXX", ... } }
```

Pass `qrcode=1` to also get QR code data in the response.

## Use Cases

- **Shareable dashboard configs**: `https://wikibento.toolforge.org/?config=https://w.wiki/TR9R`
  — short, phone-friendly URLs that survive QR scanning (WikiBento verified
  this end-to-end 2026-08-12).
- **QR codes for demos/GLAM events**: `Special:QrCode?url=...` gives a PNG
  without any API call.
- **Link shorteners in templates/messages** where full URLs bloat wikitext.