Skip to main content
Use client.Events.SubscribeAsync to receive realtime events from an instance.

Common events

EventWhen it happens
MessageNew incoming or outgoing message.
ReadReceiptRead status update.
PresenceUser presence.
HistorySyncHistory synchronization.
ChatPresenceConversation presence.
ConnectedInstance connected.
DisconnectedInstance disconnected.
GroupParticipantsAddParticipant added to a group.
GroupParticipantsRemoveParticipant removed from a group.
AllHandler for every event.

Subscribe to realtime

await using var subscription = await client.Events.SubscribeAsync(
    new VZapsEventSubscribeRequest
    {
        InstanceId = "VZ...",
        InstanceToken = "instance-token",
        Events = new[] { VZapsEventType.Message, VZapsEventType.Connected },
        Reconnect = true,
        MaxRetries = 10,
        LastEventId = "evt_123",
    },
    cancellationToken);
Return: EventSubscription — object with on(), close(), and automatic reconnect when configured.

Register handlers

subscription.On(VZapsEventType.Message, async evt =>
{
    Console.WriteLine(evt.Id);
    await Task.CompletedTask;
});

subscription.On(VZapsEventType.All, evt =>
{
    Console.WriteLine(evt.Type);
});

Close subscription

await subscription.WaitForCloseAsync(cancellationToken);
Return: Promise<void> after the WebSocket closes. Use await using to ensure clean shutdown when the scope ends.

Event envelope

public sealed class VZapsEvent
{
    public string Id { get; set; }
    public string Type { get; set; }
    public string InstanceId { get; set; }
    public DateTimeOffset? CreatedAt { get; set; }
    public JsonElement Data { get; set; }
}

Delivery and ack

The SDK sends ack after handlers complete. Delivery is at-least-once; deduplicate by evt.Id when handlers have side effects.

Realtime or webhook?

Use realtime for workers, CLIs, dashboards, and processes that can keep an active WebSocket connection. Use webhooks for persistent server-to-server integrations.