Official SDKs
Official bZapper libraries to integrate in minutes, in your language. They all cover the same set of API operations: the 13 message types (text, image, video, document, audio, sticker, location, contact, poll, reaction, buttons, list, and OTP), numbers/instances, API keys, usage, and the advanced features — groups, presence, conversations, and contacts.
Install with a single command — no cloning required. Node, Python, PHP, Go and Java are already published (npm, PyPI, Packagist, Go modules, and Maven Central).
The essentials: you only need your API key
The SDK already points at the production API (https://api.bzapper.com.br). You
pass no URL at all — just your API key (bz_live_..., generated in the panel
under API Keys). That's all.
The API URL is optional and only meant for development (
http://localhost:8080) or self-hosting. In production, leave it out.
Installation
| Language | Installation |
|---|---|
| Node / TypeScript | npm install @bzapper/client |
| Python | pip install bzapper |
| PHP | composer require bzapper/bzapper |
| Go | go get github.com/bernisoftware/bzapper-go@latest |
| Java (Maven) | see the <dependency> block below |
For Node, Python, PHP, and Go, the command above already downloads the latest version and all dependencies — you add nothing else.
Java — dependency (Maven / Gradle)
Add only the SDK artifact. The single runtime dependency (Jackson, for JSON) comes in transitively — you don't need to declare anything else.
Maven (pom.xml):
<dependency>
<groupId>br.com.bernisoftware</groupId>
<artifactId>bzapper</artifactId>
<version>0.5.0</version>
</dependency>
Gradle (build.gradle.kts):
implementation("br.com.bernisoftware:bzapper:0.5.0")
Requires Java 17+. No Gson, OkHttp, or any other manual lib — the SDK uses the
JDK's own java.net.http.HttpClient and pulls in Jackson by itself.
Quick start
Installed? Then just pass the API key and send. No URL.
Node / TypeScript
import { Bzapper } from '@bzapper/client';
const bz = new Bzapper({ apiKey: 'bz_live_...' });
await bz.sendText({ to: '+5511999999999', body: 'Hello from bZapper! 👋' });
Python
from bzapper import Client
bz = Client("bz_live_...")
bz.send_text(to="+5511999999999", body="Hello from bZapper! 👋")
PHP
use Bzapper\Client;
$bz = new Client("bz_live_...");
$bz->sendText("+5511999999999", "Hello from bZapper! 👋");
Go
bz := bzapper.NewClient("bz_live_...")
bz.SendText(context.Background(), bzapper.SendTextParams{
SendBase: bzapper.SendBase{To: "+5511999999999"},
Body: "Hello from bZapper! 👋",
})
Java
import com.bernisoftware.bzapper.BzapperClient;
import com.bernisoftware.bzapper.model.SendOptions;
var bz = new BzapperClient("bz_live_...");
bz.sendText(SendOptions.to("+5511999999999"), "Hello from bZapper! 👋");
Point at dev/self-host (optional)
Only if you're not using production:
new Bzapper({ apiKey: 'bz_live_...', baseUrl: 'http://localhost:8080' }); // Node
Client("bz_live_...", "http://localhost:8080") # Python
new Client("bz_live_...", "http://localhost:8080"); // PHP
bzapper.NewClient("bz_live_...", bzapper.WithBaseURL("http://localhost:8080")) // Go
new BzapperClient("http://localhost:8080", "bz_live_..."); // Java
Tip: explore and test everything in the Playground inside the panel (admin), with real sends and ready-made code examples in each language.
Presence in a group
Showing "typing…" in a group is just pointing the presence at the group's JID:
bz.presence_chat(instance_id=inst, to="[email protected]", state="typing")
Webhooks — receiving and processing events
The SDKs receive the webhook payload and process it for you: they verify the
HMAC signature (X-Bzapper-Signature), turn the envelope into a typed event,
and route it to a per-type handler. Each SDK also does the CRUD for webhooks
(createWebhook/listWebhooks/…). Events:
message.{received,sent,delivered,read,failed},
instance.{connected,disconnected,banned,logged_out,warming,status},
group.{joined,participant_added,participant_removed,participant_promoted,participant_demoted,subject_changed,description_changed}.
Python
from bzapper.webhooks import Webhooks
hooks = Webhooks(secret="whsec_...") # secret returned by create_webhook
@hooks.on("message.received")
def _(event):
print(event.sender.name, event.payload["body"])
# in your endpoint — raw body + header. Raises SignatureError if invalid.
hooks.handle(raw_body=request.get_data(), signature=request.headers["X-Bzapper-Signature"])
Node / TypeScript
import { Webhooks } from '@bzapper/client';
const hooks = new Webhooks('whsec_...');
hooks.on('message.received', (e) => console.log(e.sender?.name, e.payload.body));
// Express: use express.raw() and the ready-made middleware
app.post('/webhooks', express.raw({ type: '*/*' }), hooks.middleware());
Go
rx := bzapper.NewWebhookReceiver("whsec_...").
On("message.received", func(e *bzapper.WebhookEvent) { /* ... */ })
http.Handle("/webhooks", rx) // it's an http.Handler: verifies + routes on its own
PHP (new Bzapper\Webhooks($secret)) and Java (new Webhooks(secret)) follow the
same pattern: on(type, handler) + handle(rawBody, signature). Use the
event_id for idempotency (the API may redeliver). Verification is timing-safe;
always pass the raw body (not the re-serialized JSON).
Error handling
Every library throws a typed error with a stable neutral code
(always use the code, never the text) and the HTTP status. Example (Python):
from bzapper import Client, BzapperError
try:
bz.send_text(to="+550000", body="hi")
except BzapperError as e:
print(e.code, e.status_code) # e.g. "instance_not_connected", 409
Each SDK has a full README (in the package's repository) with examples for every message type, groups, presence, conversations, and errors.