ZenZap Messages API

Operations for sending messages

Operations 7

POST /v2/messages Send a message #
DELETE /v2/messages/{messageId} Delete a message #
PATCH /v2/messages/{messageId} Edit a message #
POST /v2/messages/{messageId}/reactions Add a reaction to a message #
DELETE /v2/messages/{messageId}/reactions/{reactionId} Remove a reaction from a message #
POST /v2/messages/{messageId}/delivered Mark a message as delivered #
POST /v2/messages/{messageId}/read Mark a message as read #

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-messages-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-messages-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Zenzap External Integration Messages 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: Messages
  description: Operations for sending messages
paths:
  /v2/messages:
    post:
      summary: Send a message
      description: 'Send a message to a topic. Your API key bot will appear as the sender.


        Supported request modes:

        - `application/json` for text messages

        - `multipart/form-data` for file/image messages


        Mentions:

        - Mention members directly in `text` using ``

        - Example: `Hello `

        - Mentioned profiles must be members of the topic


        Limits:

        - message length is limited to 10000 characters'
      operationId: createMessage
      security:
      - bearerAuth: []
        hmacSignature: []
      - oauth2ClientCredentials:
        - message:send
      tags:
      - Messages
      parameters:
      - $ref: '#/components/parameters/XSignature'
      - $ref: '#/components/parameters/XTimestamp'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MessageCreateRequest'
            examples:
              basic:
                summary: Basic message
                value:
                  topicId: 550e8400-e29b-41d4-a716-446655440000
                  text: Hello from my integration!
              withExternalId:
                summary: Message with external ID
                value:
                  topicId: 550e8400-e29b-41d4-a716-446655440000
                  text: 'Status update: Build completed successfully'
                  externalId: build-12345
              withMention:
                summary: Message with mention
                value:
                  topicId: 550e8400-e29b-41d4-a716-446655440000
                  text: Hi <@550e8400-e29b-41d4-a716-446655440001>, can you review this?
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/MessageFileUploadRequest'
            encoding:
              metaPart:
                contentType: application/json
            examples:
              fileUpload:
                summary: File upload
                value:
                  metaPart:
                    channelID: 550e8400-e29b-41d4-a716-446655440000
                    caption: Quarterly report
                    externalId: report-2026-q1
                    compressImage: false
                  filePart: (binary)
      responses:
        '200':
          description: File message accepted (multipart upload)
        '201':
          description: Text message created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageCreateResponse'
              example:
                id: 660e8400-e29b-41d4-a716-446655440001
                topicId: 550e8400-e29b-41d4-a716-446655440000
                createdAt: 1699564800000
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /v2/messages/{messageId}:
    delete:
      summary: Delete a message
      description: Delete a message by ID. Only the bot that sent the message can delete it.
      operationId: deleteMessage
      security:
      - bearerAuth: []
        hmacSignature: []
      - oauth2ClientCredentials:
        - message:write
      tags:
      - Messages
      parameters:
      - $ref: '#/components/parameters/XSignature'
      - $ref: '#/components/parameters/XTimestamp'
      - name: messageId
        in: path
        required: true
        description: The message ID to delete
        schema:
          type: string
          format: uuid
        example: 660e8400-e29b-41d4-a716-446655440001
      responses:
        '204':
          description: Message deleted successfully
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
    patch:
      summary: Edit a message
      description: 'Edit the text of a message. Only the bot that sent the message can edit it, and the bot must still be a member of the channel.


        Notes:

        - `text` is required and cannot be empty

        - Message length is limited to 10000 characters

        - Edited messages will have an `Edited` property marker applied'
      operationId: patchMessage
      security:
      - bearerAuth: []
        hmacSignature: []
      - oauth2ClientCredentials:
        - message:write
      tags:
      - Messages
      parameters:
      - $ref: '#/components/parameters/XSignature'
      - $ref: '#/components/parameters/XTimestamp'
      - name: messageId
        in: path
        required: true
        description: The message ID to edit
        schema:
          type: string
          format: uuid
        example: 660e8400-e29b-41d4-a716-446655440001
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MessagePatchRequest'
            example:
              text: Updated message content
      responses:
        '200':
          description: Message updated successfully
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /v2/messages/{messageId}/reactions:
    post:
      summary: Add a reaction to a message
      description: 'Add an emoji reaction to a message. The bot must be a member of the channel.


        This endpoint is idempotent per `{messageId, bot, reaction}`:

        - Returns `201` when a new reaction is created

        - Returns `200` when the same reaction already exists for this bot'
      operationId: addMessageReaction
      security:
      - bearerAuth: []
        hmacSignature: []
      - oauth2ClientCredentials:
        - reaction:write
      tags:
      - Messages
      parameters:
      - $ref: '#/components/parameters/XSignature'
      - $ref: '#/components/parameters/XTimestamp'
      - name: messageId
        in: path
        required: true
        description: The message ID to react to
        schema:
          type: string
          format: uuid
        example: 660e8400-e29b-41d4-a716-446655440001
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MessageReactionCreateRequest'
            example:
              reaction: 👍
      responses:
        '200':
          description: Reaction already existed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageReactionCreateResponse'
        '201':
          description: Reaction created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageReactionCreateResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /v2/messages/{messageId}/reactions/{reactionId}:
    delete:
      summary: Remove a reaction from a message
      description: 'Remove a reaction by ID. Only the bot that added the reaction can remove it, and the bot must still be a member of the channel.


        The `messageId` in the path must match the message the reaction belongs to.'
      operationId: deleteMessageReaction
      security:
      - bearerAuth: []
        hmacSignature: []
      - oauth2ClientCredentials:
        - reaction:write
      tags:
      - Messages
      parameters:
      - $ref: '#/components/parameters/XSignature'
      - $ref: '#/components/parameters/XTimestamp'
      - name: messageId
        in: path
        required: true
        description: The message ID the reaction belongs to
        schema:
          type: string
          format: uuid
        example: 660e8400-e29b-41d4-a716-446655440001
      - name: reactionId
        in: path
        required: true
        description: The reaction ID to remove
        schema:
          type: string
          format: uuid
        example: 990e8400-e29b-41d4-a716-446655440005
      responses:
        '204':
          description: Reaction removed successfully
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /v2/messages/{messageId}/delivered:
    post:
      summary: Mark a message as delivered
      description: 'Mark a message as delivered by the current bot.


        This endpoint is idempotent. If the message has not been fully persisted yet,

        delivery status is queued and applied when it becomes available.'
      operationId: markMessageDelivered
      security:
      - bearerAuth: []
        hmacSignature: []
      - oauth2ClientCredentials:
        - message:write
      tags:
      - Messages
      parameters:
      - $ref: '#/components/parameters/XSignature'
      - $ref: '#/components/parameters/XTimestamp'
      - name: messageId
        in: path
        required: true
        description: The message ID to mark as delivered
        schema:
          type: string
          format: uuid
        example: 660e8400-e29b-41d4-a716-446655440001
      responses:
        '200':
          description: Message marked as delivered
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /v2/messages/{messageId}/read:
    post:
      summary: Mark a message as read
      description: 'Mark a message as read by the current bot.


        This endpoint is idempotent. If the message has not been fully persisted yet,

        read status is queued and applied when it becomes available.'
      operationId: markMessageRead
      security:
      - bearerAuth: []
        hmacSignature: []
      - oauth2ClientCredentials:
        - message:write
      tags:
      - Messages
      parameters:
      - $ref: '#/components/parameters/XSignature'
      - $ref: '#/components/parameters/XTimestamp'
      - name: messageId
        in: path
        required: true
        description: The message ID to mark as read
        schema:
          type: string
          format: uuid
        example: 660e8400-e29b-41d4-a716-446655440001
      responses:
        '200':
          description: Message marked as read
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
components:
  responses:
    Forbidden:
      description: Forbidden - you do not have permission to perform this action
      content:
        text/plain:
          schema:
            type: string
          example: forbidden
    BadRequest:
      description: Bad request - invalid input
      content:
        text/plain:
          schema:
            type: string
          example: text is required
    InternalServerError:
      description: Internal server error
      content:
        text/plain:
          schema:
            type: string
          example: internal server error
    NotFound:
      description: Resource not found
      content:
        text/plain:
          schema:
            type: string
          example: Topic not found
    Unauthorized:
      description: Unauthorized - invalid or missing API token
      content:
        text/plain:
          schema:
            type: string
          example: unauthorized
  schemas:
    MessageReactionCreateRequest:
      type: object
      required:
      - reaction
      properties:
        reaction:
          type: string
          description: Emoji reaction to add
          minLength: 1
          example: 👍
    MessageCreateRequest:
      type: object
      required:
      - topicId
      - text
      properties:
        topicId:
          type: string
          format: uuid
          description: The ID of the topic to send the message to
          example: 550e8400-e29b-41d4-a716-446655440000
        text:
          type: string
          maxLength: 10000
          description: 'The message text content.

            To mention a member, use `<@profileId>` inside the text.

            Example: `Hello <@550e8400-e29b-41d4-a716-446655440001>`

            '
          example: Hello from my integration!
        externalId:
          type: string
          maxLength: 61
          description: Optional external identifier for tracking purposes
          example: build-12345
    MessageCreateResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: The created message ID
        topicId:
          type: string
          format: uuid
          description: The topic ID where the message was sent
        createdAt:
          type: integer
          format: int64
          description: Unix timestamp in milliseconds
    MessagePatchRequest:
      type: object
      required:
      - text
      properties:
        text:
          type: string
          description: Updated message text (max 10000 characters)
          maxLength: 10000
          example: Updated message content
    MessageReactionCreateResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Reaction ID
          example: 990e8400-e29b-41d4-a716-446655440005
        messageId:
          type: string
          format: uuid
          description: Message ID the reaction belongs to
          example: 660e8400-e29b-41d4-a716-446655440001
        reaction:
          type: string
          description: The reaction emoji
          example: 👍
        createdAt:
          type: integer
          format: int64
          description: Unix timestamp in milliseconds
          example: 1699564800000
    MessageFileMetaRequest:
      type: object
      required:
      - channelID
      properties:
        channelID:
          type: string
          format: uuid
          description: 'Topic ID for the uploaded file message.

            Note: multipart mode uses `channelID` (legacy field name) for compatibility.

            '
          example: 550e8400-e29b-41d4-a716-446655440000
        caption:
          type: string
          maxLength: 10000
          description: Optional caption text for the file message
          example: Quarterly report
        externalId:
          type: string
          maxLength: 100
          description: Optional external identifier for tracking purposes
          example: report-2026-q1
        compressImage:
          type: boolean
          description: 'Optional image compression flag.

            Supported only for image uploads.

            '
          default: false
    MessageFileUploadRequest:
      type: object
      required:
      - metaPart
      - filePart
      properties:
        metaPart:
          $ref: '#/components/schemas/MessageFileMetaRequest'
        filePart:
          type: string
          format: binary
          description: File content to upload
  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