Skip to main content
A QuickLink is a hosted Polymorfa page behind a persistent URL. Whoever opens the link confirms their phone number, chooses an allowed connection type, and completes signup or pairs a linked device for your project. Use QuickLink for Meta Cloud API or Linked Device connections. Direct QR and pairing-code endpoints require direct-pairing access for the team that owns the Number. The API returns 403 when access is absent. Every active team can create QuickLinks for testing numbers. QuickLinks for real numbers require Pay-As-You-Go; see Free team limits. Creating a link does not fund a number: pairing checks the number’s funding before starting the connection. Frozen teams and inactive projects cannot start onboarding. Meta Cloud API and Test Numbers retain their separate access requirements. Links remain active until the number connects or you cancel them. They do not grant messaging access. Meta Cloud API onboarding requires team beta access and an active project. Configuring Meta app IDs alone does not enable it. Unavailable optional Meta Cloud API choices are hidden; a project that forces Meta Cloud API cannot issue a link without access. Withdrawing access stops new onboarding and history requests while preserving reconciliation of operations already accepted by Meta. A pending invitation can report cloud_onboarding_unavailable; this does not report success or delete Meta assets.

Team-owned Meta apps

Teams with an active Branded QuickLink add-on and Meta Cloud API onboarding access can configure their own Meta app and Embedded Signup configuration for QuickLinks. Your app needs the Meta permissions and approvals required for the numbers you connect. Saving credentials does not grant those approvals or enable onboarding access. The app secret is submitted once and is not returned by the settings page. Replacing a configuration applies to new invitations; existing invitations keep their saved app. Disconnecting revokes saved configurations for unfinished onboarding. It does not delete customer-owned Meta assets or disconnect established numbers. A payment dispute blocks use of the saved app until the dispute is resolved; its settings remain available to view. Your team-owned app stays in use while the add-on is active, after you cancel renewal until the paid period ends, and during the three-day payment recovery period after a failed renewal payment. When access ends:
  • New QuickLinks and Customer invitations use Polymorfa’s standard Meta app and presentation. Creating them does not fail because of your saved app.
  • Unfinished invitations that were issued with your team-owned app stop before their next Meta step. Send a new link.
  • Connected Numbers keep running. Polymorfa does not stop, disconnect or delete a Number because the add-on ended or because you disconnected your app.
  • Your saved app configuration is kept until you disconnect it. It becomes usable again when the add-on is active again.
Team members receive a billing notice when a cancellation is scheduled, when a renewal payment fails, and when access ends. The payment failure notice gives the recovery deadline. Delivery follows your notification preferences.

Check and renew Meta Cloud API credentials

Polymorfa periodically validates the saved Meta credentials of each Number connected through the Meta Cloud API. Each check confirms that the access token is valid, that it has the whatsapp_business_messaging and whatsapp_business_management permissions for the WhatsApp Business Account, that Meta reports the phone number as connected, and that the app is subscribed to the account’s webhooks. Checks of Numbers that share a WhatsApp Business Account are spaced apart. A check only reads from Meta; it never stops or restarts the Number. Read the latest result with GET /messaging/{session}/cloud-credentials. checkedAt is the time of the last completed validation. status is: failureCode is one of token_expired, token_invalid, token_app_mismatch, app_credentials_rejected (the saved app secret no longer matches the Meta app), permission_missing, phone_not_registered, webhook_not_subscribed, credentials_unreadable, meta_unavailable or meta_response_invalid. To renew the authorization, stop the Number, then use a project token with quicklink:manage to call POST /messaging/{session}/cloud-credentials/reauthorize. The response contains a QuickLink bound to the same Number and phone number. It always uses the Meta Cloud API and your team-owned app while Branded QuickLink is active. Share the link with the person who manages the Number’s Meta assets. After they complete Embedded Signup, the Number starts with the renewed credentials and is checked again within minutes. Track progress with GET /messaging/quicklinks/{id}. The renewal link has purpose reauthorization in QuickLink status. You can cancel it before Meta work starts, and the existing Number stays in Polymorfa. Once Meta work starts, the cancellation endpoint returns 409; check the link’s status before taking another action. Reauthorization returns 409 state_conflict while the Number is running and 501 operation_not_supported for a Number that also has a linked-device connection. Both endpoints require Meta Cloud API onboarding beta access and return 403 feature_unavailable without it. An active Branded QuickLink add-on also lets you hide Powered by Polymorfa. Canceling renewal preserves this benefit until paid time ends. After the entitlement expires, QuickLinks show the watermark again; your saved preference is retained. The current branding entitlement applies when the page loads and after history or test-setup updates, including for links created before the entitlement changed. Saving hideWatermark: true without the add-on returns 402 with code addon_required. Saving a team-owned Meta app without it returns 403.

Fund linked-device pairing

Your team needs enough prepaid credit for the number’s first 24-hour window. Credit is reserved before pairing material is issued and consumed when WhatsApp confirms the connection. If funding is unavailable, the page asks the recipient to contact the sender. Add credit or review project billing priority, then send a new link. The pairing-code endpoint returns 402 with billing_credit_required; reading the page state reports failed with that error code.

Free team limits

Teams on Free can’t create QuickLinks for real numbers. Creating one returns 409 with the error code payg_required. QuickLinks for testing numbers and Link a real number now in the Console remain available. Linking a real number beyond the team’s allowance also returns payg_required. Upgrade the team to use these links; see Free and Pay-As-You-Go teams. You can create the same hosted link from three places.
Open a project, go to Numbers, select New number, then choose Send a QuickLink. Review the settings for that link, generate it, then copy the URL, share it, or show it as a QR code for a phone camera. Console shows the link moving from Opened to Linked to Connected, and adds the number to the list when the recipient confirms. For a Meta Cloud API number, the link stays at Linked while the readiness checks run, and Console names the recovery step when a check fails. While Meta has not answered a check, Cancel QuickLink stays available.To pair a phone that is with you, choose Link a real number now instead. Console runs an authenticated pairing flow inside the dialog. The embedded attempt cannot be shared or opened outside the Console.

Request fields

Start with projectId. A project token already identifies its project, so it can send an empty JSON object. A team key must specify projectId when the team has more than one project. QuickLink starts by confirming the recipient’s number before starting a connection. The saved Allow phone changes setting controls whether a prefilled number can be replaced; unprefilled invitations accept a number from the recipient. Changing a number waits for any Linked Devices attempt to stop. An unresolved Meta operation must finish before switching. Brazilian mobile numbers are checked with and without the ninth digit. The entered number remains the number used for Meta setup; Linked Devices uses the resolved WhatsApp identity. When both forms are registered, the recipient selects their account. Lookup hints are not proof of ownership or Meta eligibility. Editing the entered number clears the account choices; the recipient checks the new number before selecting an account. A number confirmed as not registered on WhatsApp can use dedicated Meta Cloud API setup only when that connection is allowed. With no supplied number, eligible links can open Meta’s number setup; Meta decides which number options are available. Polymorfa does not guarantee a supplied number. configuration.connectionPreference: "both" lets the recipient choose one allowed connection. It does not connect both transports. QuickLink snapshots your saved project settings. Before creating a link, choose its connection type, pairing methods, optional prefilled number, and history sync policy. API creation accepts these choices under configuration. Page text, appearance, support, privacy, terms, and callback URLs come from saved settings and cannot be changed for an individual link. Creation accepts these invitation fields: Omitted configuration fields inherit saved defaults. Set configuration.defaultMethod to null to choose pairing codes on phones and QR codes on laptops. Configure page text and appearance in team or project QuickLink settings. Configure privacy, terms, and callback URLs in project QuickLink settings. For example, offer phone pairing with history disabled:
For connection choices, history-sync options, and field limits, see Create a QuickLink.

What the recipient sees

The hosted page shows your business name, logo, and accent, and offers the enabled methods:
  • Scan QR code on a laptop or a second device. The page refreshes the code automatically until WhatsApp links.
  • Enter a code on the phone itself. The recipient types their number, receives a one-time code, and enters it under Link with phone number instead in WhatsApp.
Phones open on the pairing-code method by default and laptops on the QR code; a saved default method overrides that choice. The recipient can switch between allowed methods before connection completes. Before pairing starts, the page explains the configured history delivery and records the recipient’s choice. After WhatsApp links, it asks for connection confirmation. Cancelling before confirmation unlinks the device again. For Meta Cloud API, the page keeps showing setup progress after Meta signup while the readiness checks run, and asks for confirmation only after the number has started. When a check fails, the page names the recovery step. While Meta has not answered a check, the page says that setup checks again and keeps Cancel available; it does not offer signup again.

Track and finish the connection

Use either of these paths to learn the outcome. Callback URLs. Configure success and failure URLs in the project’s QuickLink settings. Each invitation snapshots those destinations when it is created. Creation requests cannot replace or clear them. Confirmation uses the success URL. Cancellation uses the failure URL with status=cancelled and reason=cancelled; connection failures use status=failed and a reason such as phone_mismatch or connection_failed. The hosted page returns after displaying the failure notice. After a Meta Cloud API or Hybrid connection, the hosted page states that Meta confirmed the setup checks and waits for the recipient to select Continue before opening the success URL. The checks do not send a message, so send and receive a test message before using the Number. Unresolvable links cannot supply a trusted callback and remain on the unavailable-link page. For example:
When supplied, the QuickLink’s externalId is included in the callback and the resulting session response. It may repeat across invitations. Customer correlation remains separate in externalCustomerId. Treat the query string as a hint and confirm the session state with GET /platform/sessions/{session} or the session webhooks. Status polling. GET /messaging/quicklinks/{id} returns the current status for the caller that created the link: An expired link returns 404.

Meta Cloud API readiness checks

After Meta accepts event delivery for the WhatsApp Business Account, Polymorfa checks the number before starting it. The link stays linked while the checks run. The first check that fails moves the link to failed with its own errorCode, and the number does not start. The link becomes connected only after every check passes and the recipient confirms. When Meta does not answer a check, for example during a Meta outage, the check is neither passed nor failed. The link stays linked and onboarding.errorCode is meta_readiness_unknown. Polymorfa checks again every two minutes and continues when Meta answers. You can cancel the link while it waits. If the link expires first, it fails with meta_readiness_unknown. A reauthorization link checks access, phone registration and the webhook subscription. It does not check the payment method or quality of a Number that is already in use. The checks run once, during setup. Afterwards, sends from the Number return a specific error when Meta reports a problem: whatsapp_authorization_required, whatsapp_payment_method_required or whatsapp_number_not_registered. Credential checks continue as described in Check and renew Meta Cloud API credentials. DELETE /messaging/quicklinks/{id} invalidates a pending link. For an initial real-number link, a 202 response means Number cleanup was requested. The Number remains in your project until cleanup finishes; check its status before creating a replacement. Cancelling a supplementary link leaves the existing Number in place. Console will not generate a replacement while the current link is active. Cancel it first, or wait until it connects or fails. Connected links cannot be cancelled; manage the Number instead. Console-created links can be inspected and cancelled only by the member who created them.

Saved settings

In the Console, open team or project Settings → QuickLink. You can:
  • enable or disable QuickLinks for the scope;
  • allow recipients to replace a prefilled phone number, or keep it locked;
  • choose the offered methods and which one opens first;
  • write the headline, description, and success message the person reads;
  • add a support link, and privacy and terms links for the confirmation step;
  • upload a logo, reuse the team logo or the project icon, and set the accent, theme, corner shape, and footer;
  • set project success and failure callback URLs and choose the chat-history behavior.
Project settings override the team defaults, and the preview shows the hosted page as the recipient sees it while you type. Fields left empty keep the standard wording. Use Get QuickLink settings and Update QuickLink settings to manage these defaults from your backend.

Direct pairing

Direct-pairing access If you need to build your own pairing interface, direct-pairing access must cover the Number before you call Get QR code or Request a pairing code. Without that access, these methods return 403. Use QuickLink instead.

Where to go next

Sessions

Manage the connected number after it lands in your project.

Customer pairing links

Assign connected numbers to Customers with durable, revocable links.

Webhooks

Observe the resulting session lifecycle.

Client tokens

Browser-safe credentials for messaging, separate from pairing.

Connection preference

connectionPreference and connectionEnforcement are separate from Linked Devices methods. Saved project settings provide the defaults. A normal QuickLink creation request can override the safe invitation fields under settings; Console presents those fields before generation. The resolved settings are snapshotted at issuance. The default is cloud with prefer. The settings are copied into each link when it is created; editing saved settings does not change existing links. Select a connection card, then choose Continue to start connecting. The preferred card appears first and is selected initially. Switching between connection types keeps the card height and action footer fixed. Longer instructions scroll within the card. Both connection views place Use Meta Cloud API instead or Use Linked Devices instead at the bottom left when switching is allowed, and Cancel at the bottom right. Actions use filled buttons with a secondary style for switching and a subtle red tint for Cancel. The page footer reads Powered by Polymorfa. Visitors can switch between light and dark themes and select English (ENG) or Brazilian Portuguese (BR) using the icon-only theme and language menus below the card on the left, with the Polymorfa attribution on the right. These choices do not change the invitation’s connection policy or the creator’s custom text. both cannot be forced. Optional Cloud choices are hidden when hosted Cloud signup is unavailable. Creating a forced-Cloud link in that case fails. Meta Cloud API setup offers Keep using the WhatsApp Business app for an eligible existing app number, or Use WhatsApp without the Business app for a new or existing Meta Cloud API number. Customers connect their own numbers and pay Meta directly for messaging.

Coexistence history

Configure a project webhook subscription for history.sync, contact.sync, and message.echo. QuickLink settings remind you to configure a destination. Enable HMS separately if you also want supported messages stored by Polymorfa. History sync never enables storage automatically. A business can decline history sharing in WhatsApp, including when the link’s history setting is enabled. history.sync delivers Meta’s refusal, progress, and history batches. Cloud history payloads contain kind: "history" and value; linked-device history retains its compressed chunk format. contact.sync contains kind: "contacts" and value. message.echo contains source: "whatsapp_business_app" and value. Confirming the connection does not wait for history import. Track progress through webhooks or the link’s onboarding status. A synchronization request being accepted is separate from import completion. HMS stores supported message metadata, preserves the original message ID, timestamp and direction, and applies its retention policy. Media references marked mediaStorage: "not_fetched" do not mean the media bytes were stored. Standalone contacts are delivered by webhooks. If onboarding.errorCode is sync_status_unknown, Meta did not confirm a contacts or history request. The connection can remain active while import status is uncertain. Check incoming history events and contact support with the QuickLink ID before attempting another signup. Do not create another invitation to retry the import: the original request may already have been accepted. The Linked Devices flow centers the QR code and offers Or use your phone number to log in underneath when both methods are allowed. Mobile browsers start with phone-number pairing when it is allowed. Resizing a desktop window does not change the initial method. The theme follows the device by default. A saved project theme sets the initial appearance; visitors can override it by choosing System, Light, or Dark. Language starts from the visitor’s first supported browser language, English or Portuguese. If neither appears, the page starts in English. Visitors can switch language on the page. When you supply externalId, native session.* lifecycle webhooks include that reference alongside the session name. It does not replace the event ID or grant access to the session. Customers identify the person or business responsible for Numbers. They do not store a phone number; supply any expected phone on the individual invitation. meta_registration_rejected means Meta explicitly refused number registration. Correct the registration restriction before starting another connection attempt. An uncertain request outcome remains pending until it can be reconciled. existing_cloud_registration_unverified means Meta did not report the number as either connected to Cloud API or ready for a new registration. Polymorfa stops before sending a registration PIN, so a PIN held by the number’s current provider is not replaced. The account owner resolves the number’s registration and PIN with that provider, then creates another invitation. When you supply prefillPhone, creation attempts to check whether the number is registered on WhatsApp. It first selects a connected Number that has previously observed the exact phone, then a connected Number with the same country calling code, then any connected Number. The selected customer and conversation are never exposed. A confirmed unregistered number returns 400 with phone_not_registered. If no connected Number can answer, the registration state remains unknown and the invitation continues with the project’s allowed connection choices. The same rule applies when the recipient enters or changes the number after opening the link. Invalid phone numbers still stop at the phone step. Missing profile names or photos do not invalidate a registered number. Customer invitations apply the same resolution to expectedPhone. cloud_start_failed means the runner reported that the Meta Cloud API connection could not start. Correct the reported connection restriction before issuing a new invitation. Polling the failed invitation does not retry startup. Customer invitations save these settings when the invitation is created, before it is opened. Their resolved phone identity is saved with the invitation; opening it does not replace that identity with a later lookup result. For a resolved prefilled number, the recipient sees Logging in as, the formatted international number and the inferred WhatsApp account type in one identity card. Polymorfa does not reuse another customer’s saved contact name or profile-photo access. When no provider-global display name is available, the card uses the number and a neutral profile icon. Not you? cancels the invitation through its saved failure callback. The connected number must match a prefilled invitation, including when the recipient scans a QR code. A mismatch fails confirmation and does not complete the invitation. meta_subscription_rejected means Meta explicitly refused the WABA webhook subscription. Correct the app permissions or WABA access restriction before creating a new invitation. An uncertain subscription result stays pending until it can be reconciled. While the subscription is pending, onboarding.errorCode is meta_subscription_status_unknown when Meta reports a different webhook callback for the Polymorfa app on that WABA. Polymorfa does not overwrite that callback. It checks again every 10 minutes and continues setup when Meta reports the Polymorfa callback. Ask the account owner to check the app’s webhook subscription, or cancel the invitation to stop. If the invitation expires first, it fails with the same code; create a new invitation after the owner resolves the callback. If confirmation returns a temporary error, retry confirmation while the invitation is valid. A retry does not repeat completed onboarding. If the invitation has expired, check the resulting Number before creating another invitation. An uncertain contacts sync cannot be confirmed from a later contact-change event. Contact support before retrying. Repeating Meta’s one-time synchronization may require the business owner to disconnect the Meta Cloud API connection and complete Embedded Signup again; this interrupts that connection and is never automatic.

Pairing on your phone

After requesting a pairing code, mobile browsers offer Open WhatsApp. Open Linked devices in the app that owns the number and enter the code. If the link opens a chat or a different installed app, open the correct WhatsApp app manually. The pairing code is never included in the external link. Browsers with picture-in-picture support also offer Keep code visible. This opens only when you select it. If the browser rejects the request, copy the code and switch to WhatsApp. The floating code closes when the pairing panel is removed or the code changes. You can open a newly issued code even if the previous picture-in-picture request is still loading. Browser and operating-system support varies. If Meta signup times out before returning its complete result, check the connection status and reload the page before starting another signup. Switching connection methods on the same page does not restart the expired signup window. New invitations created after a team loses access to its team-owned Meta app use the available Polymorfa Meta app or Linked Devices according to the project’s connection policy. Existing invitations retain their saved app binding.

Session configuration

Onboarding choices are frozen when the link is issued. Ongoing session settings inherit platform, team, and project defaults unless the session overrides a field. A changed default updates sessions that still inherit it. See Session configuration for updates and resets. Unknown configuration fields are rejected. Presentation, legal links, and callbacks cannot be set on an individual link. Configuration never grants HMS access or overrides the recipient’s history decision.

Simulated connections

For a testing number, include configuration.testing. Set a country and initial simulation configuration, then list the fields the recipient may customize:
Testing access and quotas apply independently of real-number onboarding. The recipient sees that the connection is simulated. The editable list accepts at most three fields. An empty list keeps all creator settings fixed. Simulation does not connect to real WhatsApp accounts.

Trusted-server Meta setup

Create a QuickLink first. Confirm the phone through POST /quicklink/{token}/phone. If both connection types are offered, select Official API through POST /quicklink/{token}/connection with { "connection": "cloud" }; a sole allowed Cloud connection is selected after phone confirmation. Then call POST /messaging/cloud-api/embedded-signup with the quicklinkId to advance Meta Cloud API setup. Include result when submitting the Embedded Signup result. For an initial invitation with history mode ask or force_on, first record the recipient’s choice through POST /quicklink/{token}/history with { "historySync": true | false }. A QuickLink that adds Official API to an existing Number reuses that Number’s history decision; its history endpoint is unavailable. The Meta signup result does not record that consent; advancing while it is pending returns 409. To request history after the recipient accepts, also set result.historySync to true in the Embedded Signup request. A missing or false result flag does not request history. The call uses the invitation’s reserved session and saved Meta app settings; it cannot choose a different session or supply app credentials. Console-only attempts and Test Numbers cannot use this endpoint. The caller needs quicklink:manage and access to the invitation’s project. Track the onboarding stage with GET /messaging/quicklinks/{id}. For a single-connection QuickLink, call POST /quicklink/{token}/confirm once the stage reaches connected. For an eligible Hybrid Link, complete Linked Devices pairing for the same Number and wait for hybridPhase: "ready" before confirming. Confirmation finishes the invitation, completes any attached Customer pairing, and returns the success redirect URL. The Embedded Signup response alone does not confirm the QuickLink.

Test history fixtures

Upload fixture messages with POST /messaging/testing/{projectId}/history-fixtures. The body contains messages, each with id, senderPhone, text, timestamp, and fromMe. Send at most 100 messages within a 512 KiB request. Message IDs must be unique and senders must belong to the project’s test-number pool. Test access and sandbox:write are required. Pass the returned fixtureId as configuration.testing.configuration.historyFixtureId when creating a test QuickLink. Fixtures provide simulated history for message retrieval; uploading a fixture does not publish live message events or enable HMS.