ZenZap Long Polling API

Long polling allows your integration to fetch outbound events instead of receiving webhooks. Use `GET /v2/updates` with: - `offset`: value returned as `nextOffset` from the previous response - `limit`: max updates per request (default 50, max 100) - `timeout`: wait time in seconds when no updates are available (default 0, max 30) Event payloads in polling responses match webhook `data` payloads for the same event type. This includes `data.message.attachments[]` with signed URLs for file/image/video/audio messages.

Operations 1

GET /v2/updates Get updates (long polling) #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/zenzap-long-polling-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

zenzap-long-polling-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Zenzap External Integration Long Polling API
  description: API for external applications to integrate with Zenzap.
  version: 2.0.0
  contact:
    name: Zenzap Support
    url: https://zenzap.co/support
servers:
- url: https://api.zenzap.co
  description: Production server
security:
- bearerAuth: []
  hmacSignature: []
- oauth2ClientCredentials: []
tags:
- name: Long Polling
  description: Long polling allows your integration to fetch outbound events instead of receiving webhooks.
paths:
  /v2/updates:
    get:
      summary: Get updates (long polling)
      description: '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.'
      operationId: getUpdates
      security:
      - bearerAuth: []
        hmacSignature: []
      - oauth2ClientCredentials:
        - updates:read
      tags:
      - Long Polling
      parameters:
      - $ref: '#/components/parameters/XSignature'
      - $ref: '#/components/parameters/XTimestamp'
      - name: offset
        in: query
        required: false
        description: Opaque offset returned by a previous `nextOffset`. Omit on the first request.
        schema:
          type: string
      - name: limit
        in: query
        required: false
        description: 'Maximum updates to return (default: 50, max: 100)'
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 50
      - name: timeout
        in: query
        required: false
        description: 'Long polling timeout in seconds (default: 0, max: 30)'
        schema:
          type: integer
          minimum: 0
          maximum: 30
          default: 0
      responses:
        '200':
          description: Updates retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UpdatesResponse'
              example:
                updates:
                - updateId: AAAAAAABAAAAAAAAAAABAA==
                  eventType: message.created
                  createdAt: 1699564800000
                  data:
                    message:
                      id: 660e8400-e29b-41d4-a716-446655440001
                      topicId: 550e8400-e29b-41d4-a716-446655440000
                      senderId: 550e8400-e29b-41d4-a716-446655440001
                      senderType: user
                      senderName: Alice Johnson
                      type: text
                      text: Hello team!
                      createdAt: 1699564800000
                    truncated: false
                nextOffset: AAAAAAABAAAAAAAAAAABAA==
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalServerError'
components:
  responses:
    BadRequest:
      description: Bad request - invalid input
      content:
        text/plain:
          schema:
            type: string
          example: text is required
    Conflict:
      description: Conflict - request cannot be completed in current state
      content:
        text/plain:
          schema:
            type: string
          example: delivery mode is not polling
    Unauthorized:
      description: Unauthorized - invalid or missing API token
      content:
        text/plain:
          schema:
            type: string
          example: unauthorized
    InternalServerError:
      description: Internal server error
      content:
        text/plain:
          schema:
            type: string
          example: internal server error
  schemas:
    UpdatesResponse:
      type: object
      required:
      - updates
      - nextOffset
      properties:
        updates:
          type: array
          items:
            $ref: '#/components/schemas/PollingUpdate'
          description: Ordered list of updates after the provided offset
        nextOffset:
          type: string
          description: Opaque offset to pass as `offset` in the next `/v2/updates` call
          example: AAAAAAABAAAAAAAAAAABAA==
    MessageMention:
      type: object
      properties:
        id:
          type: string
          description: The mentioned profile ID
          example: 550e8400-e29b-41d4-a716-446655440001
        name:
          type: string
          description: Display name used for the mention text
          example: Alice Johnson
    WebhookTask:
      type: object
      description: 'Task snapshot sent when a task is created, updated, or its status changes.

        The `action` field indicates what triggered this snapshot.

        '
      properties:
        id:
          type: string
          description: The task ID
        action:
          type: string
          enum:
          - Added
          - Updated
          - Deleted
          - MarkedAsDone
          - MarkedAsOpened
          - Replied
          description: 'What triggered this task snapshot:

            - `Added`: Task was created

            - `Updated`: Task details were changed

            - `Deleted`: Task was removed

            - `MarkedAsDone`: Task was completed

            - `MarkedAsOpened`: Task was reopened

            - `Replied`: Comment was added to task

            '
        title:
          type: string
          description: Task title
          example: Review documentation
        text:
          type: string
          description: Task description
          example: Please review the API docs by Friday
        status:
          type: string
          enum:
          - Open
          - Done
          description: Current task status
        assignee:
          type: string
          description: User ID of the assignee
          example: 550e8400-e29b-41d4-a716-446655440001
        dueDate:
          type: integer
          format: int64
          description: Due date as Unix timestamp in milliseconds
          example: 1699651200000
        isDueDateTimeSelected:
          type: boolean
          description: Whether a specific time was selected for the due date
        parentId:
          type: string
          description: Parent task ID (for subtasks)
        subItemsCount:
          type: integer
          description: Number of subtasks
          example: 3
    PollingUpdate:
      type: object
      required:
      - updateId
      - eventType
      - createdAt
      - data
      properties:
        updateId:
          type: string
          description: Opaque update identifier. Use as offset in subsequent polling calls.
          example: AAAAAAABAAAAAAAAAAABAA==
        eventType:
          type: string
          enum:
          - message.created
          - message.updated
          - message.deleted
          - reaction.added
          - reaction.removed
          - member.added
          - member.removed
          - topic.updated
          description: The update event type
          example: message.created
        createdAt:
          type: integer
          format: int64
          description: Unix timestamp in milliseconds when the update was created
          example: 1699564800000
        data:
          description: Event payload. Structure matches the webhook `data` payload for the same event type.
          oneOf:
          - $ref: '#/components/schemas/WebhookMessageCreatedData'
          - $ref: '#/components/schemas/WebhookMessageUpdatedData'
          - $ref: '#/components/schemas/WebhookMessageDeletedData'
          - $ref: '#/components/schemas/WebhookReactionData'
          - $ref: '#/components/schemas/WebhookMemberData'
          - $ref: '#/components/schemas/WebhookTopicUpdatedData'
    WebhookMessageUpdatedData:
      type: object
      required:
      - message
      properties:
        message:
          $ref: '#/components/schemas/WebhookMessage'
        updatedFields:
          type: array
          items:
            type: string
          description: List of fields that changed
          example:
          - text
        truncated:
          type: boolean
          description: Whether the payload content was truncated
          example: false
    WebhookTopicUpdatedData:
      type: object
      required:
      - topicId
      properties:
        topicId:
          type: string
          format: uuid
          description: The topic that was updated
        name:
          type: string
          description: New topic name (only present if changed)
        description:
          type: string
          description: New topic description (only present if changed)
        actorId:
          type: string
          description: The actor who made the update
        changes:
          type: object
          description: Map of changed fields and their new values
          additionalProperties: true
    WebhookReactionData:
      type: object
      required:
      - messageId
      - topicId
      - emoji
      - userId
      properties:
        messageId:
          type: string
          format: uuid
          description: The message that was reacted to
        topicId:
          type: string
          format: uuid
          description: The topic containing the message
        emoji:
          type: string
          description: The emoji that was added/removed
          example: 👍
        userId:
          type: string
          description: The user who added/removed the reaction
          example: 550e8400-e29b-41d4-a716-446655440001
        reactionId:
          type: string
          format: uuid
          description: Reaction ID (present when available)
        createdAt:
          type: integer
          format: int64
          description: Unix timestamp in milliseconds when the reaction event was created
          example: 1699564800000
        reaction:
          $ref: '#/components/schemas/WebhookReactionObject'
    WebhookReactionObject:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Reaction ID
        messageId:
          type: string
          format: uuid
          description: The reacted message ID
        topicId:
          type: string
          format: uuid
          description: Topic ID containing the message
        userId:
          type: string
          description: The reacting user ID
        emoji:
          type: string
          description: The reaction emoji
    WebhookContact:
      type: object
      description: Shared contact information
      properties:
        name:
          type: string
          description: Contact name
          example: John Doe
        phoneNumbers:
          type: array
          items:
            type: string
          description: Phone numbers
          example:
          - '+1234567890'
        emails:
          type: array
          items:
            type: string
          description: Email addresses
          example:
          - john@example.com
        role:
          type: string
          description: Job title or role
          example: Engineer
        location:
          type: string
          description: Location or office
          example: San Francisco
        linkedIn:
          type: string
          description: LinkedIn profile URL
          example: https://linkedin.com/in/johndoe
        profileId:
          type: string
          description: Zenzap profile ID if the contact is a Zenzap user
          example: 550e8400-e29b-41d4-a716-446655440001
    WebhookMessageDeletedData:
      type: object
      required:
      - messageId
      - topicId
      properties:
        messageId:
          type: string
          format: uuid
          description: The deleted message ID
        topicId:
          type: string
          format: uuid
          description: The topic where the message was deleted
        deletedAt:
          type: integer
          format: int64
          description: Unix timestamp in milliseconds when deletion occurred
          example: 1699564800000
        deletedBy:
          type: string
          description: The user ID who deleted the message
        message:
          type: object
          description: Minimal message snapshot
          properties:
            id:
              type: string
              format: uuid
            topicId:
              type: string
              format: uuid
            senderId:
              type: string
    WebhookLocation:
      type: object
      description: Shared location data
      properties:
        latitude:
          type: string
          description: Latitude coordinate
          example: '37.7749'
        longitude:
          type: string
          description: Longitude coordinate
          example: '-122.4194'
        name:
          type: string
          description: Location name (optional)
          example: San Francisco Office
        address:
          type: string
          description: Street address (optional)
          example: 123 Market St, San Francisco, CA
    WebhookMessageCreatedData:
      type: object
      required:
      - message
      properties:
        message:
          $ref: '#/components/schemas/WebhookMessage'
        truncated:
          type: boolean
          description: Whether the payload content was truncated
          example: false
    WebhookTranscription:
      type: object
      description: 'Transcription data for audio attachments (voice messages).


        **Transcription flow:**

        1. `message.created` arrives with `transcription.status: "Pending"`

        2. `message.updated` arrives when transcription completes with `status: "Done"` and `text` populated

        '
      properties:
        status:
          type: string
          enum:
          - Pending
          - Started
          - Done
          - Failed
          description: 'Transcription status:

            - `Pending`: Queued for transcription

            - `Started`: Transcription in progress

            - `Done`: Transcription complete, `text` field populated

            - `Failed`: Transcription failed

            '
        text:
          type: string
          description: The transcribed text (only present when status is "Done")
          example: Hey team, just a quick update on the project...
    WebhookMemberData:
      type: object
      required:
      - topicId
      - memberIds
      properties:
        topicId:
          type: string
          format: uuid
          description: The topic where the member was added/removed
        memberIds:
          type: array
          items:
            type: string
          description: One or more member IDs affected by the operation
          example:
          - 550e8400-e29b-41d4-a716-446655440003
        memberId:
          type: string
          description: Single member ID (present when exactly one member changed)
          example: 550e8400-e29b-41d4-a716-446655440003
        memberType:
          type: string
          enum:
          - user
          - bot
          description: Type of member for single-member events
          example: user
        actorId:
          type: string
          description: The actor who triggered the member change
          example: 550e8400-e29b-41d4-a716-446655440001
        createdAt:
          type: integer
          format: int64
          description: Unix timestamp in milliseconds when the event payload was created
          example: 1699564800000
    WebhookAttachment:
      type: object
      description: 'File attachment with download URL. URLs are signed and expire after 60 minutes.

        Download files promptly after receiving the webhook.

        '
      properties:
        id:
          type: string
          description: The attachment ID
        type:
          type: string
          enum:
          - image
          - file
          - video
          - audio
          description: The attachment type
        name:
          type: string
          description: The original file name
          example: document.pdf
        url:
          type: string
          format: uri
          description: 'Signed URL to download the attachment.

            **Important:** URLs expire after 60 minutes.

            '
          example: https://storage.zenzap.co/attachments/...?token=...&expires=...
        transcription:
          $ref: '#/components/schemas/WebhookTranscription'
      example:
        id: att_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...
    WebhookMessage:
      type: object
      description: 'Message object as delivered in webhook events. Includes additional fields

        not present in the REST API response, such as message type-specific data.

        '
      required:
      - id
      - topicId
      - senderId
      - senderName
      - senderType
      - type
      - createdAt
      properties:
        id:
          type: string
          format: uuid
          description: The message ID
        topicId:
          type: string
          format: uuid
          description: The topic ID where the message was sent
        senderId:
          type: string
          description: The sender's member ID
          example: 550e8400-e29b-41d4-a716-446655440001
        senderName:
          type: string
          description: The sender's display name
          example: Alice Johnson
        senderType:
          type: string
          enum:
          - user
          - bot
          - system
          description: The type of sender
        type:
          type: string
          enum:
          - text
          - image
          - file
          - video
          - audio
          - location
          - task
          - contact
          description: 'The message type:

            - `text`: Regular text message

            - `image`, `file`, `video`, `audio`: Message with attachment

            - `location`: Shared location

            - `task`: Task snapshot (created, updated, completed, etc.)

            - `contact`: Shared contact

            '
        text:
          type: string
          description: 'The message text content (may be empty for non-text types).

            Mention tokens are preserved as `<@profileId>`.

            '
        previousText:
          type: string
          description: Previous message text (present on `message.updated` when text changed)
        createdAt:
          type: integer
          format: int64
          description: Unix timestamp in milliseconds when the message was created
        updatedAt:
          type: integer
          format: int64
          description: Unix timestamp in milliseconds when the message was last updated
        parentId:
          type: string
          format: uuid
          description: ID of the message being replied to (for threaded replies)
        mentionedProfiles:
          type: array
          items:
            type: string
          description: IDs of mentioned users in the message
        attachments:
          type: array
          items:
            $ref: '#/components/schemas/WebhookAttachment'
          description: Array of file attachments
        mentions:
          type: array
          items:
            $ref: '#/components/schemas/MessageMention'
          description: Array of user mentions in the message
        location:
          $ref: '#/components/schemas/WebhookLocation'
        task:
          $ref: '#/components/schemas/WebhookTask'
        contact:
          $ref: '#/components/schemas/WebhookContact'
  parameters:
    XSignature:
      name: X-Signature
      in: header
      required: false
      description: "HMAC signature of the request for authentication and replay protection.\n\n**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.\n\n**Replay Protection:** The signature includes a timestamp to prevent replay attacks.\nRequests with timestamps older than 5 minutes are rejected.\n\nThe signature payload differs by HTTP method:\n- **POST/PUT/PATCH/DELETE**: HMAC-SHA256 of `{timestamp}.{body}`\n- **GET**: HMAC-SHA256 of `{timestamp}.{uri}`\n\nThe signature is calculated as:\n1. Get the current Unix timestamp in milliseconds\n2. Determine the payload:\n   - For POST/PUT/PATCH/DELETE: Use `{timestamp}.{body}` where body is the request body\n   - For GET: Use `{timestamp}.{uri}` where uri is the full request URI (e.g., `/v2/members?limit=10`)\n3. Calculate HMAC-SHA256 of the combined payload using your API secret\n4. Hex-encode the output\n5. Include the timestamp in the `X-Timestamp` header\n\nExample for GET request to `/v2/members?limit=10`:\n```\ntimestamp = 1699564800000\npayload = \"1699564800000./v2/members?limit=10\"\nsignature = HMAC-SHA256(secret, payload)\nX-Signature: hex(signature)\nX-Timestamp: 1699564800000\n```\n\nExample for POST request with body `{\"topicId\":\"123\",\"text\":\"Hello\"}`:\n```\ntimestamp = 1699564800000\npayload = '1699564800000.{\"topicId\":\"123\",\"text\":\"Hello\"}'\nsignature = HMAC-SHA256(secret, payload)\nX-Signature: hex(signature)\nX-Timestamp: 1699564800000\n```\n\nFor `multipart/form-data` requests, sign the exact raw request body bytes\n(including boundaries and file bytes) as transmitted.\n"
      schema:
        type: string
        pattern: ^[a-f0-9]{64}$
        example: a3d5f8e7c2b1d4f6a8e9c7b5d3f1a2e4b6c8d0f2e4a6b8c0d2e4f6a8b0c2d4e6
    XTimestamp:
      name: X-Timestamp
      in: header
      required: false
      description: '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.

        '
      schema:
        type: integer
        format: int64
        example: 1699564800000
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'Bearer token for the request. Two flavors:


        - **Static API key** — pass your API key (the value returned as `apiKey` when the bot was created). Must be paired with `X-Signature` + `X-Timestamp` (the `hmacSignature` scheme).

        - **OAuth access token** — pass the JWT returned by `POST /oauth/token`. No signature headers are required.

        '
    hmacSignature:
      type: apiKey
      in: header
      name: X-Signature
      description: 'HMAC-SHA256 signature for request verification. Required **only** when authenticating with a static API key. Omit when using an OAuth access token.

        '
    oauth2ClientCredentials:
      type: oauth2
      description: 'OAuth 2.0 `client_credentials` grant for API-key bots. Use the `clientId` and `clientSecret` returned when the bot was created (or rotated) to mint short-lived access tokens. See [Authentication](/api-reference/authentication) for details.


        Access tokens are bearer JWTs and expire after 1 hour. There is no refresh token — re-mint with the client credentials when the token expires.

        '
      flows:
        clientCredentials:
          tokenUrl: https://api.zenzap.co/oauth/token
          scopes:
            channel:list: List topics the bot belongs to
            channel:read: Read topic metadata
            channel:write: Create/update topics and manage members
            message:read: Read messages
            message:send: Send messages
            message:write: Edit / delete / mark-delivered / mark-read messages
            reaction:write: Add and remove reactions on messages
            task:read: Read tasks
            task:write: Create / update / delete tasks
            poll:write: Create polls and cast / retract votes
            member:read: List organization members
            updates:read: Long-poll for outbound events