By industry

WhatsApp API for dev agencies that ship custom software

A dev agency that puts WhatsApp in every project shouldn't rebuild the infrastructure for every contract. With a managed WhatsApp API, WhatsApp becomes a standard in-house module: one session per client, the same integration across every system and no extra servers to maintain.

By D-API engineering team5 min read

The hidden cost of reinventing WhatsApp in every project

The request shows up in almost every scope: the scheduling system needs to remind the patient, the ERP needs to send the invoice, the portal needs to notify the agent. At many software shops, each team solves it their own way. One project uses an open source library running on the client's server, another uses a different vendor, a third has a script someone wrote and nobody else understands.

The price shows up after delivery, in the maintenance contract. Each variant has its own way of going down, its own way of reconnecting and its own knowledge concentrated in one person. When that person leaves, the project becomes a risk. And since WhatsApp maintenance is rarely priced in, the contract margin disappears into hours nobody bills.

Standardizing on a managed WhatsApp API solves the tedious part: the infrastructure stays with the vendor, and your team only writes each client's business logic, which is what the contract pays for.

Who handles what

Make it clear in the scope, and to your own team, where the agency's responsibility ends and the API provider's begins.

ResponsibilityDev agencyD-API
Rules for when and what to sendYesNo
Handling replies and events in the systemYesNo
Keeping the connection up and reconnectingNoYes, with continuous self-healing
Servers, IP and per-number isolationNoYes, each connection isolated with a dedicated IP
Resending webhooks when your system is downRespond fast with a 2xx statusUp to 7 retries with exponential backoff
Guiding the client on number usageYesSupport for your team

This split is the same build-or-buy discussion covered in detail in self-hosted vs managed.

A reusable WhatsApp module

The real gain comes when WhatsApp becomes an internal package, with the same interface in every project. What usually goes into that module:

  • Per-project config: API key and session name come from environment variables, never from code.
  • A send service that takes a phone number and content and hides the call details.
  • A webhook endpoint with the same shape in every system, which checks the incoming sessionId and queues the event before processing.
  • Standard error handling: the API returns success, error and statusCode, which allows a single mapping for logs and alerts.
  • Retries on your side. The SDK makes a plain HTTP call and doesn't retry on its own. Decide in the module which errors deserve a retry and with what interval.

In a Node project, the core of that module uses the official SDK:

import { DApi } from 'd-api-sdk'

const dapi = new DApi({ apiKey: process.env.DAPI_API_KEY! })
const SESSION = process.env.DAPI_SESSION_ID! // e.g. client-acme-production

export async function provision(webhookUrl: string) {
  await dapi.sessions.create({ sessionId: SESSION, connectionMode: 'qr', webhookUrl })
  const { qrCodeImage } = await dapi.sessions.getQRCode(SESSION)
  return qrCodeImage // show it on the settings screen of the client's system
}

export function notify(phone: string, text: string) {
  return dapi.messages.sendText({ sessionId: SESSION, to: phone, text })
}

Install details and available methods are in the Node.js SDK and the WhatsApp API in Node.js guide. Projects on other stacks call the same REST API; the WhatsApp API in Python guide shows the pattern outside Node.

One session per client, one session per environment

Each client of the agency has its own session, which isolates number, credentials and webhook. Within the same client, separate environments too. A simple convention prevents the most common mistake in any project, a test message reaching a real customer:

  • acme-dev: the team's test number, webhook pointing to a local tunnel.
  • acme-staging: the client's test number, used for acceptance testing.
  • acme-production: the client's real number, production server webhook.

If one of the projects is a product the client will sell to many end users, with one number per user, the design changes scale and gets closer to SaaS. In that case, read WhatsApp API for SaaS.

Delivery, handover and maintenance contracts

Custom projects have a delivery date, and the WhatsApp part is usually what generates the most tickets after it. Three practices cut that volume:

  1. Document who owns the account. If the client will take over the system, the account and API key should be in their name from the start. Transferring later is rework.
  2. Monitor connection status. Subscribe to the connection.status event and show in the system dashboard whether the number is connected, disconnected or logged_out. The client solves many cases alone once they can see the problem.
  3. Price maintenance by connection. D-API bills per connection, not per message, and the price per connection goes down as volume grows. So the WhatsApp cost of each contract is fixed and goes into the proposal without an inflated safety margin. The tiers are on pricing.

To validate the module on a pilot project, there's a 3-day free trial, no credit card. If your shop also serves agencies or runs automations for third parties, WhatsApp API for agencies shows the portfolio operating model.

Frequently asked questions

Is it worth hosting our own WhatsApp solution as a dev agency?
Only if keeping WhatsApp connections alive is the product you sell. For agencies delivering custom software, hosting means updating libraries, running servers and answering late-night tickets across every project at once, with nobody paying for it.
Should the API account be in the agency's name or the client's?
Both models work. If you handle ongoing maintenance, the account is usually yours and the cost goes into the maintenance contract. If the client will take over the system, create the account in their name from day one and use their key in the project config.
My project isn't in Node. Can I use D-API?
Yes. The official SDK is for Node and TypeScript, but the API is REST with header authentication, so any language that makes HTTP requests can integrate, whether PHP, Python, Java, C# or Go.
How do I separate staging and production?
Create different sessions, with names that indicate the environment, and different numbers. That way the team tests new flows in staging with no risk of sending a test message to a real customer.
The client may want to move to the official API later. Will I have to rewrite the integration?
No. On D-API the official and unofficial connections use the same sending routes. You change the session type on creation and, for the official API, use templates to start conversations. The rest of the code stays the same.

Try D-API's WhatsApp API

3-day trial with full access. No credit card, no lock-in.