fastify-xwhatconverts
fastify-xwhatconverts
WhatConverts lead tracking integration for Fastify v5. Decorates fastify.xwhatconverts with four service namespaces: leads (CRUD + constants), accounts (Agency Key required), profiles, and recordings. All methods validate inputs, attach the original WhatConverts error object on API failure, and expose structured error codes.
Installation
npm install @xenterprises/fastify-xwhatconverts
Quick Start
import Fastify from "fastify";
import xWhatConverts from "@xenterprises/fastify-xwhatconverts";
const fastify = Fastify({ logger: true });
await fastify.register(xWhatConverts, {
token: process.env.WHATCONVERTS_TOKEN,
secret: process.env.WHATCONVERTS_SECRET,
});
// List recent phone call leads
const result = await fastify.xwhatconverts.leads.list({
leadType: "phone_call",
leadsPerPage: 50,
});
await fastify.listen({ port: 3000 });
Options
| Name | Type | Default | Required | Description |
|---|---|---|---|---|
token | string | — | Yes | WhatConverts API token. |
secret | string | — | Yes | WhatConverts API secret. |
baseUrl | string | "https://app.whatconverts.com/api/v1" | No | API base URL override. |
active | boolean | true | No | Set false to skip plugin registration. |
Methods
Leads (fastify.xwhatconverts.leads)
- leads.list(params?) — List leads with optional filters.
- leads.get(leadId, params?) — Get a single lead by ID.
- leads.create(params) — Create a new lead.
- leads.update(leadId, params) — Update an existing lead.
- leads.delete(leadId) — Delete a lead by ID.
Accounts (fastify.xwhatconverts.accounts) — Agency Key required
- accounts.list(params?) — List accounts with optional filters.
- accounts.get(accountId) — Get a single account by ID.
- accounts.create(params) — Create a new account.
- accounts.update(accountId, params) — Update an existing account.
- accounts.delete(accountId) — Delete an account (removes all profiles, leads, and numbers).
Profiles (fastify.xwhatconverts.profiles)
- profiles.list(params?) — List profiles with optional filters.
- profiles.get(profileId) — Get a single profile by ID.
- profiles.create(params) — Create a new profile.
- profiles.update(profileId, params) — Update an existing profile.
- profiles.delete(profileId) — Delete a profile by ID.
Recordings (fastify.xwhatconverts.recordings)
- recordings.get(leadId) — Get the call recording as an
ArrayBuffer. - recordings.getBuffer(leadId) — Get the call recording as a Node.js
Buffer. - recordings.getUrl(leadId) — Construct the recording API URL without a network request.
Error Reference
| Error | Cause |
|---|---|
[xWhatConverts] options.token is required and must be a string | Missing or non-string token at registration |
[xWhatConverts] options.secret is required and must be a string | Missing or non-string secret at registration |
[xWhatConverts] options.baseUrl must be a string | Non-string baseUrl at registration |
[xWhatConverts] leads.get: leadId is required | leads.get() called without leadId |
[xWhatConverts] leads.create: profileId is required | leads.create() missing profileId |
[xWhatConverts] leads.create: leadType is required | leads.create() missing leadType |
[xWhatConverts] leads.update: leadId is required | leads.update() called without leadId |
[xWhatConverts] leads.delete: leadId is required | leads.delete() called without leadId |
[xWhatConverts] accounts.get: accountId is required | accounts.get() called without accountId |
[xWhatConverts] accounts.create: accountName is required | accounts.create() missing accountName |
[xWhatConverts] accounts.update: accountId is required | accounts.update() called without accountId |
[xWhatConverts] accounts.delete: accountId is required | accounts.delete() called without accountId |
[xWhatConverts] profiles.get: profileId is required | profiles.get() called without profileId |
[xWhatConverts] profiles.create: accountId is required | profiles.create() missing accountId |
[xWhatConverts] profiles.create: profileName is required | profiles.create() missing profileName |
[xWhatConverts] profiles.update: profileId is required | profiles.update() called without profileId |
[xWhatConverts] profiles.delete: profileId is required | profiles.delete() called without profileId |
[xWhatConverts] recordings.get: leadId is required | recordings.get() called without leadId |
[xWhatConverts] recordings.getBuffer: leadId is required | recordings.getBuffer() called without leadId |
[xWhatConverts] recordings.getUrl: leadId is required | recordings.getUrl() called without leadId |
[xWhatConverts] Network error: <message> | Network-level failure (DNS, timeout, connection refused) |
[xWhatConverts] API error: <status> | Non-2xx response from WhatConverts API |
Environment Variables
| Variable | Required | Description |
|---|---|---|
WHATCONVERTS_TOKEN | Yes | API token from the WhatConverts dashboard. |
WHATCONVERTS_SECRET | Yes | API secret from the WhatConverts dashboard. |
How It Works
On registration the plugin validates token and secret, builds a Basic Auth header from them, then decorates fastify.xwhatconverts with four service namespaces (leads, accounts, profiles, recordings). All JSON service methods share a common apiRequest helper that sets Authorization and Content-Type, handles both JSON and empty responses, and wraps failures as structured errors with code, statusCode, and whatConvertsError. The recordings service uses apiBinaryRequest which returns the raw response body as an ArrayBuffer. API credentials are held in closure scope and are never exposed on the decorator.
AI Context
package: "@xenterprises/fastify-xwhatconverts"
type: fastify-plugin
use-when: WhatConverts lead tracking — lead CRUD, account management (Agency Key), profile management, call recording retrieval
decorator: fastify.xwhatconverts (leads, accounts, profiles, recordings)
env: WHATCONVERTS_TOKEN, WHATCONVERTS_SECRET
accounts: requires Agency Key (token/secret from agency account)
error-shape: { code, statusCode, whatConvertsError } on API failures
