I run WhatsUsernames.link, a free WhatsApp link + QR code generator. This week I shipped everything the site does as a public REST API — and made three decisions I wish more small APIs made:
- No API key, no signup. Call the endpoint, get the response. No dashboard, no token, no confirmation email.
- Free, with per-IP rate limits generous enough for real use.
- CORS enabled on every endpoint — call it straight from the browser on a static site, no backend needed.
The endpoints
Base URL: https://whatsusernames.link. Everything is GET.
| Endpoint | What it does |
|---|---|
/api/v1/username-link |
WhatsApp link + short link from a username |
/api/v1/phone-link |
Official wa.me link from a phone number |
/api/v1/validate/username |
Validates username structure |
/api/v1/validate/key |
Validates a Username Key (4-8 letters/numbers) |
/api/v1/validate/phone |
Validates an international phone number |
/api/v1/qr |
QR code (PNG or SVG), custom size and colors |
/api/v1/openapi.json |
OpenAPI 3.1 spec of the API itself |
Try it right now
curl "https://whatsusernames.link/api/v1/username-link?username=joao.silva"
{
"username": "joao.silva",
"link": "https://wa.me/joao.silva",
"shortLink": "https://whatsusernames.link/joao.silva",
"notice": "As of 2026-07-04, wa.me/<username> links do not yet open a chat for most accounts..."
}
From the browser, no library:
const res = await fetch(
"https://whatsusernames.link/api/v1/phone-link?phone=351912345678&text=hello"
);
const { link } = await res.json();
// https://wa.me/351912345678?text=hello
A WhatsApp-green QR code as SVG, ready to drop into an <img> tag:
https://whatsusernames.link/api/v1/qr?username=joao.silva&format=svg&color=25d366
Design decisions that might interest you
Stable error codes. Errors are always JSON with a machine-readable code that never changes within v1:
{
"error": {
"code": "username_length",
"message": "Username must be 3-35 characters."
}
}
Honest responses about a moving target. WhatsApp's @username feature is in a phased regional rollout, and wa.me/<username> links don't open a chat for most accounts yet (I verified this empirically — server-side redirects and real-device taps). Instead of pretending otherwise, the username-link response includes a notice field with the current status, so your app is never caught off guard. Phone-number links (wa.me/<number>) are officially documented and work for everyone today.
Anti-phishing QR restriction. The QR endpoint only encodes wa.me links built from a validated username or phone number — never arbitrary content. You can't use it to mint QR codes pointing anywhere else.
Rate limiting that fails open. 60 req/min per IP for JSON, 20/min for QR (sliding window via Upstash Redis). Responses carry X-RateLimit-* headers, and 429s include Retry-After. If Redis is ever slow or down, requests proceed — availability over strictness for a free utility API.
Machine-readable spec. The OpenAPI 3.1 document means you can codegen a client — or just point an AI agent at it and it knows how to build WhatsApp links correctly. There's also an llms.txt on the site for the same reason.
What people are building with it
- Landing pages that generate contact links dynamically, no backend
- CRM/internal tools validating numbers before outreach campaigns
- Print-material generators needing brand-colored SVG QR codes
- n8n/Zapier/scripts building WhatsApp links on the fly
Docs live at whatsusernames.link/developers. Stack, for the curious: Next.js 15 route handlers on Vercel, Upstash Redis for rate limiting, qrcode for server-side QR generation, all TDD'd with Vitest.
If you build something with it, I'd genuinely love to hear about it in the comments.
Top comments (0)