Published 2026-08-249 min readTutorial

WhatsApp QR code integration: the complete guide.

QR-based integration is the fastest way to connect a real WhatsApp number to your product: your customer scans one code with the WhatsApp already on their phone, and you get an always-on API for that number. This guide covers the whole surface: provisioning, four ways to put the QR in front of a customer, the typed-code fallback for devices that can’t scan, and the lifecycle you manage after the scan.



01

What QR linking actually is (and isn't)

Every WhatsApp user has seen the QR flow: it’s how WhatsApp connects additional devices to an account. The account owner opens Settings > Linked Devices > Link a Device and points their camera at a code. QR-based integration builds on exactly that user-visible flow: the scan authorizes an always-on connection that Mossmoon hosts, so the number becomes programmable without the phone needing to stay online.

What it is not: the WhatsApp Business API. There is no Meta Business Manager, no business verification, no display-name review, no template catalog, and no 24-hour customer service window. The number keeps working normally on the owner’s phone the entire time. The structural comparison between the two paths is its own post: WhatsApp Business API vs personal WhatsApp API.


02

Provision a line, get a connect URL

One authenticated POST creates a line and returns everything you need for onboarding:

curl -X POST https://mossmoon.app/api/v1/wa/lines \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "existing",
    "webhook_url": "https://your.app/wa-hook",
    "agency_external_user_id": "customer_042"
  }'

→ 201 Created
{
  "line_id": "wa_8f3c2e1a",
  "status": "pending_link",
  "connect_url": "https://mossmoon.app/wa/connect/<token>",
  "webhook_secret": "wsec_...",
  "created_at": "2026-08-24T10:00:00Z"
}

The connect_url hosts the QR. Nothing bills at this point; billing starts only when the QR is actually scanned and the line goes ready. The token inside the URL is the only credential the page needs, which is what makes every embedding option below possible without exposing your API key to the browser.


03

Four ways to put the QR in front of your customer

  1. The hosted connect page (default). Send the connect_url as-is. Your customer gets a clean page with the QR, plain-language instructions, and a live status that flips to ✓ Connected the moment the scan lands. Zero build effort.
  2. Bare iframe embed. Append ?bare=1 and the page strips its header, instructions, and footer, leaving just the QR. Drop it in an iframe inside your own onboarding UI and your customer never sees anything but your product:
<iframe
  src="https://mossmoon.app/wa/connect/<token>?bare=1"
  width="320"
  height="440"
  style="border: 0; background: transparent;"
></iframe>
  1. Branded QR. Pass a logo_url when you create the line (an https URL to a square PNG/JPEG/WebP/SVG under 200KB) and your logo is embedded at the center of the QR. Fetched and validated once at creation; QR refreshes keep the same logo. White-label agencies use this so the connect moment carries their brand, not ours.
  2. Fully custom UI. The docs’ Embed the QR section covers rendering the QR inside your own components using the connect token directly, for teams that want pixel-level control over the onboarding screen.

04

The fallback when scanning isn't possible: pairing codes

QRs assume the phone with WhatsApp can point its camera at a second screen. That breaks down in kiosk setups, accessibility flows, and any automation that types rather than reads. For those, mint a pairing code instead:

POST /api/v1/wa/lines/wa_8f3c2e1a/pairing-code
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

{
  "phone_number": "+14155551234"
}

→ 200 OK
{
  "line_id": "wa_8f3c2e1a",
  "code": "ABCD1234",
  "expires_in_seconds": 60
}

Your customer types the 8-character code into WhatsApp’s Link a device > Link with phone number screen. Codes are only valid while the line is pending_link and expire in about 60 seconds; call the endpoint again to mint a fresh one. Both paths (QR and code) end in the same place: a ready line.


05

After the scan: the lifecycle you actually manage

A line moves through a small set of states, and each transition fires a signed webhook at the webhook_url you set at creation:

pending_link ──(scan)──▶ ready ──(long phone offline)──▶ disconnected
                                        │                        │
                                        │                (re-scan via reconnect_url)
                                        ▼                        │
                                   [messaging]  ◀────────────────┘
  • line.ready fires seconds after the scan, with the connected phone number in the payload. This is your “onboarding complete” signal (and when billing starts).
  • message.received fires for every inbound from then on, and POST /api/v1/wa/lines/{line_id}/send handles outbound. The webhook setup guide walks through the receiving side with full code samples.
  • line.disconnected fires if the line ever needs re-authorizing (typically after the phone has been offline a long time), and includes a reconnect_url. The line_id is stable across reconnects, so your data model never migrates: surface the reconnect link to your customer, they scan again, the same line resumes.

06

Keeping newly connected numbers healthy

A QR scan makes a number programmable in two minutes, and the biggest mistake teams make is treating minute three like a broadcast tower. WhatsApp’s anti-abuse systems watch how numbers behave, and a fresh integration that suddenly fires hundreds of messages to strangers looks exactly like spam, because it is.

  • Ramp up gradually on newly connected numbers, replying to inbound conversations before initiating outbound ones. The docs’ warm-up section has a day-by-day timeline.
  • Keep it one-to-one. Mossmoon rate-limits outbound and refuses patterns that look like cold blasts, on purpose. If your use case is genuine mass broadcast, the Business API is the right tool for that job.
  • Established, actively used numbers are structurally healthier candidates for integration than brand-new SIMs bought yesterday.

Provision a line and scan your first QR in the next ten minutes.

First line free for 7 days. $15/line/mo after, flat. No Meta onboarding, no templates, no 24-hour window.

WhatsApp QR code integration guide: connect numbers to your product · Mossmoon