> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wsapi.chat/llms.txt
> Use this file to discover all available pages before exploring further.

# Python SDK

> Python SDK for integrating WSAPI into Python applications

The WSAPI Python SDK provides a typed client (Pydantic v2) for sending WhatsApp messages, managing groups and chats, and receiving real-time events via webhooks or Server-Sent Events (SSE).

## Installation

```bash theme={null}
pip install wsapi-client
```

## Requirements

* Python 3.9 or later
* Valid WSAPI API key and instance ID

## Quick start

```python theme={null}
from wsapi_client import WSApiClient, ApiException
from wsapi_client.models.requests.messages import MessageSendTextRequest

client = WSApiClient(api_key="<your-api-key>", instance_id="<instance-id>")

req = MessageSendTextRequest(
    to="1234567890@s.whatsapp.net",
    text="Hello from Python!",
)

result = client.messages.send_text(req)
print("Message id:", result.id)

client.close()
```

<Note>
  Always call `client.close()` when done, or use the client as a context manager.
</Note>

## Error handling

The SDK provides two patterns for every operation:

<Tabs>
  <Tab title="Exception-based">
    Standard methods raise `ApiException` on failure:

    ```python theme={null}
    from wsapi_client import WSApiClient, ApiException
    from wsapi_client.models.requests.messages import MessageSendTextRequest

    client = WSApiClient(api_key="<your-api-key>", instance_id="<instance-id>")

    try:
        req = MessageSendTextRequest(
            to="1234567890@s.whatsapp.net", text="Hello!"
        )
        created = client.messages.send_text(req)
        print("Message id:", created.id)
    except ApiException as ex:
        print("Send failed:", ex.problem.detail)
    ```
  </Tab>

  <Tab title="Try-based (non-raising)">
    Methods prefixed with `try_` never raise. They return an `ApiResponse[T]`:

    ```python theme={null}
    resp = client.messages.try_send_text(req)
    if resp.is_success and resp.result:
        print("Message id:", resp.result.id)
    else:
        print("Send failed:", resp.error.detail if resp.error else "unknown")
    ```

    The `ApiResponse[T]` object contains:

    * `result` — data when successful (`None` if failed)
    * `error` — `ProblemDetails` when not successful (`None` if success)
    * `is_success` — convenience boolean
  </Tab>
</Tabs>

## Available resources

```python theme={null}
# Messages
client.messages.send_text(req)
client.messages.send_image(req)
client.messages.send_video(req)
client.messages.send_audio(req)
client.messages.send_document(req)
client.messages.send_sticker(req)
client.messages.send_contact(req)
client.messages.send_location(req)
client.messages.send_link(req)
client.messages.send_reaction(req)
client.messages.edit_text(req)
client.messages.mark_as_read(req)
client.messages.star(req)
client.messages.delete(req)

# Users, Instance, Contacts, Groups, Chats, Calls, Media
client.users.get_by_id("5511999999999")
client.instance.get_settings()
client.contacts.get_all()
client.groups.get_all()
client.chats.get_all()
client.calls.reject(call_id, req)
client.media.download(media_id)
```

## Receiving events via SSE

```python theme={null}
from wsapi_client import SSEClient, SSEConnectionState
from wsapi_client.models.events.messages import MessageEvent

sse = SSEClient(api_key="<your-api-key>", instance_id="<instance-id>")

def on_event(evt):
    if isinstance(evt, MessageEvent) and evt.text:
        print("[sse]", evt.sender_name, ":", evt.text)

def on_state(state, exc):
    print("[sse] Connection state:", state)
    if exc:
        print("[sse] Error:", exc)

sse.on_event = on_event
sse.on_connection_state_changed = on_state
sse.start()

# ... later
sse.stop()
```

## Handling webhooks

<Tabs>
  <Tab title="Flask">
    ```python theme={null}
    from flask import Flask, request, jsonify
    from wsapi_client.events.factory import parse_event
    from wsapi_client.models.events.messages import MessageEvent

    app = Flask(__name__)

    WEBHOOK_AUTH_TOKEN = "your-secret-token"

    @app.route("/wsapi/webhook", methods=["POST"])
    def handle_webhook():
        auth_header = request.headers.get("X-Webhook-Auth")
        if auth_header != WEBHOOK_AUTH_TOKEN:
            return jsonify({"error": "Unauthorized"}), 401

        try:
            parsed_event = parse_event(request.get_data(as_text=True))

            if isinstance(parsed_event, MessageEvent) and parsed_event.text:
                print(f"New message from {parsed_event.sender_name}: {parsed_event.text}")

            return jsonify({"status": "success"}), 200
        except Exception as e:
            print(f"Error processing event: {e}")
            return jsonify({"error": "Processing failed"}), 500

    if __name__ == "__main__":
        app.run(host="0.0.0.0", port=5000)
    ```
  </Tab>

  <Tab title="FastAPI">
    ```python theme={null}
    from fastapi import FastAPI, Request, HTTPException, Header
    from wsapi_client.events.factory import parse_event
    from wsapi_client.models.events.messages import MessageEvent
    from typing import Optional

    app = FastAPI()

    WEBHOOK_AUTH_TOKEN = "your-secret-token"

    @app.post("/wsapi/webhook")
    async def handle_webhook(
        request: Request,
        x_webhook_auth: Optional[str] = Header(None),
    ):
        if x_webhook_auth != WEBHOOK_AUTH_TOKEN:
            raise HTTPException(status_code=401, detail="Unauthorized")

        try:
            body = await request.body()
            parsed_event = parse_event(body.decode("utf-8"))

            if isinstance(parsed_event, MessageEvent) and parsed_event.text:
                print(f"New message: {parsed_event.text}")

            return {"status": "success"}
        except Exception as e:
            print(f"Error: {e}")
            raise HTTPException(status_code=500, detail="Processing failed")
    ```
  </Tab>
</Tabs>

## Available event types

| Category     | Events                                                                                                  |
| ------------ | ------------------------------------------------------------------------------------------------------- |
| **Session**  | `SessionLoggedInEvent`, `SessionLoggedOutEvent`, `SessionLoggedErrorEvent`                              |
| **Messages** | `MessageEvent`, `MessageDeleteEvent`, `MessageReadEvent`, `MessageStarEvent`, `MessageHistorySyncEvent` |
| **Chats**    | `ChatPresenceEvent`, `ChatSettingEvent`                                                                 |
| **Contacts** | `ContactEvent`                                                                                          |
| **Users**    | `UserPushNameEvent`, `UserPictureEvent`, `UserPresenceEvent`, `UserStatusEvent`                         |
| **Calls**    | `CallOfferEvent`, `CallAcceptEvent`, `CallTerminateEvent`                                               |

## GitHub

[github.com/wsapi-chat/wsapi-python](https://github.com/wsapi-chat/wsapi-python)
