open-wa
DocsLicensed features

Licensed features

What licensed features are for, how keys are used, and where to validate unlock behavior.

Licensed features

open-wa has license-gated functions. This page explains how the runtime applies a key and how to check the exact behavior you plan to use.

What licensing affects

License-gated behavior includes features such as:

  • certain advanced or insiders-only capabilities
  • restricted flows like messaging non-contact numbers
  • premium/support-tier unlocks tied to a host account

The method tier and the behavior available in a deployed release are separate checks. A key does not make an absent method available, and the host account must still support the operation.

Current behavior

At launch, the runtime resolves the configured licenseKey. When the host account context is available, it sends the key to the license validation service. The runtime classifies the result before it marks the client ready. A server-confirmed response is a valid unlock. The runtime injects the returned license payload into the browser.

If the runtime cannot confirm the key with the server, it can fall back to local license metadata. That fallback records the key type and lets the session continue, but it is not the same as a server-confirmed capability unlock. Invalid or expired classifications are blocking failures and stop readiness before finalization.

Feature gating comes from the generated method metadata. Each method declares a license tier of none, insiders, or restricted. Use that metadata as the feature list for your build.

Exact gated features

The current generated method schema marks these methods as licensed:

FeatureLicense tier
getNumberProfileinsiders
checkNumberStatusinsiders
getOrderinsiders
postTextStatusinsiders
postImageStatusinsiders
postVideoStatusinsiders
getStories / getStatusesinsiders
getStatusinsiders
deleteStatusinsiders
deleteAllStatus / deleteAllStatusesinsiders
sendInteractive (buttons, lists, forms, carousels, bookings)insiders
sendRawMessage (constructed protocol payloads)insiders
sendButtonsinsiders
sendAdvancedButtonsinsiders
sendListMessage / sendListinsiders
getStarredMessagesinsiders
setProfilePicture / setProfilePicinsiders
createGrouprestricted
joinGroupViaLink / joinGrouprestricted

Methods marked none are not license-gated in the schema. Old docs and changelog entries can contain previous tiers, names, or runtime surfaces. Use the generated API reference for the package version that you deploy.

For new v5 integrations, use sendInteractive for buttons, lists, forms, carousels, and bookings. It requires an applied Insiders or higher license for the sending account. The legacy sendButtons, sendAdvancedButtons, and sendListMessage methods remain in the schema with their own Insider gates; sendButtons and sendListMessage are deprecated.

Runtime-specific number check

The ordinary sendText method is marked none in the schema, but the current client reports that sending to a number that is not already a contact requires a Restricted or Premium licence. This is an additional runtime check for that recipient path, so the method badge alone does not describe it. Confirm the runtime response and test that path in the session and release you will use.

How keys are supplied

You can provide a license key in the runtime config:

await create({
  licenseKey: 'YOUR-LICENSE-KEY',
});

Or via the Easy API / CLI path:

npx @open-wa/wa-automate@5.1.0 --session-id sales --host 127.0.0.1 --port 8080 --license-key "YOUR-LICENSE-KEY"

License behavior

When the license is valid, the runtime applies the server-confirmed license payload, records the license lifecycle as satisfied, and continues launch. The relevant runtime status is valid.

When the runtime can use only local metadata, it records metadata_only. The session can continue, but this status does not confirm an unlock. The license server did not confirm the capability.

When you supply no key, the runtime records missing. Ungated methods continue to work. Do not expect gated methods to work.

For an expired or invalid key, the runtime records expired or invalid. It marks the license lifecycle as failed and emits a fatal bootstrap error. Readiness stops before finalization.

Common license workflow

  1. review the current first-party offer and confirm it covers the behavior you intend to run
  2. supply it through config or CLI at launch
  3. verify the runtime recognizes the key in the session you care about
  4. test the specific gated feature instead of assuming success from configuration alone

Status inspection

For Easy API sessions, inspect the /health endpoint and read the license object:

curl http://localhost:8080/health

The response includes fields like:

{
  "license": {
    "status": "valid",
    "source": "local",
    "keyType": "server",
    "detail": "License capability remained server-confirmed at check time."
  }
}

From a client method surface, you can also call getLicenseType to inspect the runtime license type exposed by the session:

const licenseType = await client.getLicenseType();
console.log(licenseType);

For launch-level diagnostics, listen for license.check.after or inspect the launch timeline in /health. The same status values are used there: valid, metadata_only, missing, invalid, and expired.

Operational advice

  • Treat license configuration as deploy-time secret material.
  • Validate the license against the actual host account you intend to run.
  • If unlock behavior looks inconsistent, verify the host number, deployment clock, and current runtime mode before assuming the key itself is wrong.

If the key looks wrong

Check these first:

  • the host account number associated with the running session
  • whether the feature is available in the runtime surface that you use
  • whether the machine clock and deployment environment are sane
  • whether you are testing the gated feature through the same session the key is meant for

Failure messages

The current runtime uses these license failure details:

SituationMessage
Validation server rejects the keyLicense key was rejected by the validation server.
Preload fails before validationLicense preload failed before validation.
No key is availableNo license material was available for this session.
Key is marked expiredResolved license key is marked as expired.
Key is marked invalidResolved license key is marked as invalid.
Server-confirmed payload cannot be appliedLicense payload did not confirm successful application.
Apply phase fails without a more specific detailLicense lifecycle did not complete successfully
Blocking status reaches launch finalizationLicense lifecycle blocked readiness with status: ${status}
License validation request failsLicense validation request failed: ${error}

You can also see the license_server_validation_failed warning in logs when the validation request fails and the runtime tries the metadata fallback path.

Use Get a license to choose Insiders or Restricted and enter your GitHub username, WhatsApp number, and use case. The purchase button on a licensed method selects that method’s tier for you.

When you open the license form from the dashboard, it fills in the session’s phone number when available and includes the session reference with your use case. Continue to Gumroad to review the selected license, prefilled details, current price, and terms before paying. You still need to configure the purchased key in your runtime.

Support escalation

If a license still fails, examine the host account, runtime version, deployment clock, and gated method. Then, collect the /health license object. Also collect the masked log key, host account number, and method name.

For support, use the project Discord or the paid support links from the primary support page. Include the status value and failure message above so the issue can be routed quickly, and mask the key and host account number before sharing logs.

Scope note

Feature availability has changed over time. Use the current generated API reference and runtime behavior as the source of truth for what is available in the build you are actually deploying.

Was this helpful?

Your answer includes the page path and docs version.

On this page