Skip to main content

Official Python SDK for the VZaps public API.

Project description

VZaps Python SDK

CI PyPI Python SDK Documentation license

Official Python client for the VZaps public API. Send WhatsApp messages, manage instances, configure webhooks, and subscribe to realtime events with a resource-oriented, sync and async interface.

Works in Python 3.10+. HTTP uses httpx; WebSocket realtime uses websockets.


Table of contents


Features

  • Automatic JWT handling — exchanges client_token + client_secret for a bearer token and refreshes it before expiry.
  • Resource-oriented APIinstances, messages, webhooks, contacts, groups, and events mirror the public HTTP contract.
  • Sync and async clientsVZapsClient and AsyncVZapsClient share the same resource surface.
  • Realtime WebSocket client — subscribe to instance events with reconnect, resume (last_event_id), and server-side ack.
  • Instance token support — pass instance_token on each instance-scoped request.
  • Extensible transport — inject a custom httpx.Client or httpx.AsyncClient for tests or custom runtimes.

Requirements

Runtime Minimum version
Python 3.10+

The SDK uses httpx for HTTP. No extra HTTP dependency is required beyond the package itself.


Installation

pip install vzaps

Quick start

Create credentials in the VZaps dashboard (client_token and client_secret), then send a text message:

from vzaps import VZapsClient

with VZapsClient(
    client_token="your-client-token",
    client_secret="your-client-secret",
) as client:
    client.messages.send_text(
        instance_id="VZKB8AU4S4CWY1SLXX4I5WJGRZQMDDFTV6",
        instance_token="instance-token",
        phone="5511999999999",
        message="Hello from VZaps",
    )

Async equivalent:

from vzaps import AsyncVZapsClient

async with AsyncVZapsClient(
    client_token="your-client-token",
    client_secret="your-client-secret",
) as client:
    await client.messages.send_text(
        instance_id="VZKB8AU4S4CWY1SLXX4I5WJGRZQMDDFTV6",
        instance_token="instance-token",
        phone="5511999999999",
        message="Hello from VZaps",
    )

Authentication

VZaps uses a two-step model:

  1. Account credentialsclient_token and client_secret identify your integration. The SDK calls POST /token and caches the JWT.
  2. Instance token — instance-scoped routes also require X-Instance-Token. Pass it on each instance-scoped request (see Instance tokens).

Every authenticated HTTP request sends:

Header Value
Authorization Bearer <jwt>
X-Client-Token Your client token
X-Instance-Token Instance token, on instance-scoped requests

You rarely need to call auth.get_access_token() directly — resources attach the token for you. Use it when integrating with custom HTTP logic:

token = client.auth.get_access_token()

Client options

Pass options to VZapsClient(...) or AsyncVZapsClient(...):

Option Type Default Description
client_token str Required. Public client token from the dashboard.
client_secret str Required. Client secret used to obtain JWTs.
timeout float | httpx.Timeout 30.0 HTTP request timeout in seconds.
token_skew_seconds float 60.0 Refresh JWT this many seconds before expiry.
limits httpx.Limits Optional httpx connection pool limits.
user_agent str package default Optional User-Agent header on HTTP requests.
http_client httpx.Client | httpx.AsyncClient Custom httpx client (tests, proxies, tracing).

Resources

The client exposes namespaced resources. Responses are decoded as Python objects (typically dict/list) so you can align with the OpenAPI schema.

client.instances

Method HTTP Description
create(request?) PUT /instances/create Create a WhatsApp instance.
list(request?) POST /instances/list List instances (pagination, search, sort).
get(instance_id) POST /instances/get Get instance details.
update(instance_id, request?, *, instance_token?) PATCH /instances/:id Update instance settings.
restart(instance_id, *, instance_token?) POST /instances/:id/restart Restart instance runtime.

client.messages

client.messages wraps the public WhatsApp send and chat endpoints. The most common calls are shown below; the SDK also exposes the other public message operations documented in the API reference, including media, interactive messages, reactions, polls, downloads, edits, deletes, presence, and read receipts.

client.messages.send_text(
    instance_id="VZ...",
    instance_token="instance-token",
    phone="5511999999999",
    message="Hello",
)

client.messages.send_image(
    instance_id="VZ...",
    instance_token="instance-token",
    phone="5511999999999",
    image="https://example.com/photo.jpg",
    caption="Check this out",
)

Available send helpers include send_text, send_image, send_audio, send_document, send_video, send_sticker, send_gif, send_location, send_contact, send_buttons, send_list, send_link, and send_poll. See the API documentation for complete payload examples.

client.webhooks

Method HTTP Description
get(instance_id, *, instance_token?) GET /instances/:id/webhook Read current webhook configuration.
set(request) POST /instances/:id/webhook Configure webhook URL and subscribed events.

client.contacts

Method HTTP Description
list(instance_id, *, instance_token?) GET /instances/:id/contact/list List contacts for the instance.
add(request) POST /instances/:id/contact/add Add a contact.

client.groups

Method HTTP Description
list(request) GET /instances/:id/group/list List groups (paginated).
get(request) GET /instances/:id/group/info Get group metadata by group_id.

client.sessions

Method HTTP Description
status(instance_id, *, instance_token=...) GET /instances/:id/session/status Check WhatsApp login state and, when connected, live profile fields.

GET /instances/{id}/session/status returns SessionStatusResponse. When data.connected is true, data includes (in order) phone, whatsapp_jid, push_name, business_name, business_profile, profile_picture_id, profile_picture_url, profile_url, and optional verified_name, about, website. When disconnected, data only has connected=False.

Other public namespaces are available as first-class resources too: sessions, users, queues, typebots, chatwoot, and chats.

client.request(method, path, ...)

Escape hatch for advanced calls or newly released endpoints:

instance = client.request(
    "POST",
    "/instances/get",
    body={"id": "VZ..."},
)

Instance tokens

Instance-scoped routes require the instance token in addition to account credentials. Pass it on each request that targets an instance:

client.messages.send_text(
    instance_id="VZ...",
    instance_token="instance-token",
    phone="5511999999999",
    message="Hello",
)

Webhooks

Configure HTTP callbacks for instance events (same payload shape as realtime data, delivered to your URL):

client.webhooks.set(
    instance_id="VZ...",
    instance_token="instance-token",
    webhook_url="https://example.com/webhooks/vzaps",
    events=["Message", "Connected", "Disconnected"],
)

Common event types: Message, ReadReceipt, Connected, Disconnected, Presence, ChatPresence, HistorySync, GroupParticipantsAdd, GroupParticipantsRemove, or All.

Event payloads (webhook and realtime) use snake_case, matching the platform. Incoming media events include media_url inside data when platform storage is available.


Realtime events

Subscribe to the same events over the VZaps realtime WebSocket. This is the recommended path for in-app notifications, bots, and dashboards that need low-latency delivery without exposing a public webhook URL.

Realtime subscriptions are async-first. Use AsyncVZapsClient and async with client.events.subscribe(...):

async with AsyncVZapsClient(
    client_token="...",
    client_secret="...",
) as client:
    async with client.events.subscribe(
        instance_id="VZ...",
        instance_token="instance-token",
        events=["Message", "Connected", "Disconnected"],
        reconnect=True,
        last_event_id="evt_previous_id",  # optional resume after disconnect
    ) as sub:

        @sub.on_open
        async def on_open() -> None:
            print("Connected to realtime")

        @sub.on("Message")
        async def on_message(event) -> None:
            print(event.data)

        @sub.on_error
        async def on_error(error) -> None:
            print(error)

        await sub.wait_closed()

Event envelope

Each WebSocket message keeps the platform shape (snake_case):

{
  "id": "evt_…",
  "type": "Message",
  "instance_id": "VZ…",
  "created_at": "2026-06-23T22:57:17.000Z",
  "data": {
    "type": "Message",
    "event": { },
    "media_url": "https://…"
  }
}
  • data — same payload as webhook delivery (snake_case).
  • media_url — present on incoming media messages when platform storage is available.

Delivery and ack

Delivery is at-least-once. After your handler runs, the SDK sends an ack automatically on the WebSocket connection. Use last_event_id when reconnecting if you need to reduce gaps. Deduplicate on event.id in your application if you process events idempotently.

Subscribe options

Option Type Default Description
instance_id str Required. Instance to watch.
events list[str] all subscribed Comma-filtered event types.
instance_token str Required. Instance token for authorization.
reconnect bool True Reconnect after socket close.
max_retries int unlimited Max reconnect attempts.
retry_delay_seconds float 1.0 Delay between reconnects.
last_event_id str Resume cursor after disconnect.

Handler registration

Method When it fires
on_open(...) WebSocket connected.
on_close(...) WebSocket closed.
on_error(...) Handler or transport error.
on("Message", ...) Matching realtime event type.
on("All", ...) Every event type.

Error handling

The SDK raises typed exceptions you can catch and branch on:

Class When
VZapsError Base class; HTTP errors include status_code, code, and details.
VZapsAuthenticationError Invalid client_token / client_secret (401).
VZapsTimeoutError Request exceeded timeout.
VZapsRateLimitError Rate limited (429).
VZapsAPIError Other non-2xx API responses.
VZapsRealtimeError Realtime handler or transport failures.
from vzaps import (
    VZapsAPIError,
    VZapsAuthenticationError,
    VZapsError,
    VZapsRateLimitError,
    VZapsTimeoutError,
)

try:
    client.messages.send_text(
        instance_id="VZ...",
        instance_token="instance-token",
        phone="5511999999999",
        message="Hello",
    )
except VZapsAuthenticationError:
    print("Check client credentials")
except VZapsTimeoutError:
    print("Request timed out")
except VZapsRateLimitError:
    print("Rate limited")
except VZapsAPIError as exc:
    print(exc.status_code, exc.message, exc.details)
except VZapsError:
    raise

Python

The package uses snake_case for Python APIs and request keyword arguments. Realtime and webhook event payloads stay in snake_case so both delivery channels match the platform wire format.

Resources accept dict payloads and keyword arguments, which makes it easy to pass newly released API fields before typed helpers are added:

client.messages.send_image(
    instance_id="VZ...",
    instance_token="instance-token",
    phone="5511999999999",
    image="https://example.com/photo.jpg",
    caption="Check this out",
)

page = client.instances.list(page=1, size=20, search="support")

Use client.request(...) when you need full control over method, path, and body.


Documentation


License

MIT © VZaps

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vzaps-0.1.1.tar.gz (21.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vzaps-0.1.1-py3-none-any.whl (24.1 kB view details)

Uploaded Python 3

File details

Details for the file vzaps-0.1.1.tar.gz.

File metadata

  • Download URL: vzaps-0.1.1.tar.gz
  • Upload date:
  • Size: 21.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for vzaps-0.1.1.tar.gz
Algorithm Hash digest
SHA256 d7ed1f231fdc7314297aa46c1ddba009d372b1d7ead8067dcfd131afaac06e68
MD5 2750008efd435dfc24165a9aab1de7f5
BLAKE2b-256 18aa3ff5894ea78524081bb34a62559c0e480787b442279fbac111e2317fd328

See more details on using hashes here.

Provenance

The following attestation bundles were made for vzaps-0.1.1.tar.gz:

Publisher: release.yml on VZaps/vzaps-sdk-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file vzaps-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: vzaps-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 24.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for vzaps-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ed35909cef49f262f932faeb8163e288014a5fd009acf88108773b73bcb78635
MD5 08574a98533c9c0d6b0a5e61f91923c6
BLAKE2b-256 37292296508d12a886ca2ead1ca56461678eb623d8c4a95f7cb734084026d37d

See more details on using hashes here.

Provenance

The following attestation bundles were made for vzaps-0.1.1-py3-none-any.whl:

Publisher: release.yml on VZaps/vzaps-sdk-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page