Long Polling

Get updates (long polling)

Retrieve outbound events for bots configured with polling delivery mode.

Long polling behavior:

  • If updates are available after offset, they are returned immediately
  • If none are available and timeout > 0, the request waits up to timeout seconds
  • If still no updates, returns an empty list with nextOffset
  • Returns 409 if delivery mode is not polling, or if offset is no longer available

Message attachment payloads are included inline in polling events, the same as webhooks: data.message.attachments[] with signed download URLs (including audio transcription metadata when available).

Use nextOffset from each response as offset in the next request.

get/v2/updates

Request

Query parameters

offsetstring

Opaque offset returned by a previous nextOffset. Omit on the first request.

limitinteger

Maximum updates to return (default: 50, max: 100)

timeoutinteger

Long polling timeout in seconds (default: 0, max: 30)

Headers

X-Signaturestring
Example:a3d5f8e7c2b1d4f6a8e9c7b5d3f1a2e4b6c8d0f2e4a6b8c0d2e4f6a8b0c2d4e6

HMAC signature of the request for authentication and replay protection.

Required only when authenticating with a static API key. If you are using an OAuth access token (issued by POST /oauth/token), omit this header — the JWT carries all the authentication and integrity guarantees.

Replay Protection: The signature includes a timestamp to prevent replay attacks. Requests with timestamps older than 5 minutes are rejected.

The signature payload differs by HTTP method:

  • POST/PUT/PATCH/DELETE: HMAC-SHA256 of {timestamp}.{body}
  • GET: HMAC-SHA256 of {timestamp}.{uri}

The signature is calculated as:

  1. Get the current Unix timestamp in milliseconds
  2. Determine the payload:
    • For POST/PUT/PATCH/DELETE: Use {timestamp}.{body} where body is the request body
    • For GET: Use {timestamp}.{uri} where uri is the full request URI (e.g., /v2/members?limit=10)
  3. Calculate HMAC-SHA256 of the combined payload using your API secret
  4. Hex-encode the output
  5. Include the timestamp in the X-Timestamp header

Example for GET request to /v2/members?limit=10:

timestamp = 1699564800000
payload = "1699564800000./v2/members?limit=10"
signature = HMAC-SHA256(secret, payload)
X-Signature: hex(signature)
X-Timestamp: 1699564800000

Example for POST request with body {"topicId":"123","text":"Hello"}:

timestamp = 1699564800000
payload = '1699564800000.{"topicId":"123","text":"Hello"}'
signature = HMAC-SHA256(secret, payload)
X-Signature: hex(signature)
X-Timestamp: 1699564800000

For multipart/form-data requests, sign the exact raw request body bytes (including boundaries and file bytes) as transmitted.

X-Timestampinteger
Example:1699564800000

Unix timestamp in milliseconds when the request was created. Used for replay protection — requests older than 5 minutes are rejected.

Required only when authenticating with a static API key. Omit when using an OAuth access token.

Response

Updates retrieved successfully

nextOffsetstring required

Opaque offset to pass as offset in the next /v2/updates call

Example response

{
  "updates": [
    {
      "updateId": "AAAAAAABAAAAAAAAAAABAA==",
      "eventType": "message.created",
      "createdAt": 1699564800000,
      "data": {
        "message": {
          "senderId": "550e8400-e29b-41d4-a716-446655440001",
          "senderName": "Alice Johnson",
          "attachments": [
            {
              "id": "550e8400-e29b-41d4-a716-446655440088",
              "type": "audio",
              "name": "voice-note.mp3",
              "url": "https://storage.zenzap.co/attachments/...",
              "transcription": {
                "status": "Done",
                "text": "Hey team, just a quick update on the project..."
              }
            }
          ],
          "mentions": [
            {
              "id": "550e8400-e29b-41d4-a716-446655440001",
              "name": "Alice Johnson"
            }
          ],
          "location": {
            "latitude": "37.7749",
            "longitude": "-122.4194",
            "name": "San Francisco Office",
            "address": "123 Market St, San Francisco, CA"
          },
          "task": {
            "title": "Review documentation",
            "text": "Please review the API docs by Friday",
            "assignee": "550e8400-e29b-41d4-a716-446655440001",
            "dueDate": 1699651200000,
            "subItemsCount": 3
          },
          "contact": {
            "name": "John Doe",
            "phoneNumbers": [
              "+1234567890"
            ],
            "emails": [
              "john@example.com"
            ],
            "role": "Engineer",
            "location": "San Francisco",
            "linkedIn": "https://linkedin.com/in/johndoe",
            "profileId": "550e8400-e29b-41d4-a716-446655440001"
          },
          "poll": {
            "id": "770e8400-e29b-41d4-a716-446655440010",
            "title": "Lunch spot?",
            "options": [
              {
                "id": "opt-1",
                "text": "Tacos"
              }
            ]
          },
          "call": {
            "initiatorId": "550e8400-e29b-41d4-a716-446655440001"
          }
        }
      }
    }
  ],
  "nextOffset": "AAAAAAABAAAAAAAAAAABAA=="
}

Changes

No recorded changes to this operation across all 1 revision of this API.