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

# Check workspace event notifications

> Bounded, immediate JSON polling for REST and MCP. Requires realtime:read. The first call without a cursor returns no events and a starting nextCursor. Pass that cursor on subsequent calls, keeping the same filters, to read up to 100 notifications in chronological order. Save nextCursor after processing a page; retry the same input cursor to replay that page. Notifications contain resource identifiers and event types only, never message bodies, outbox payloads or private AI results. Fetch current resources using their separate read scopes. On hasMore, drain the next page; otherwise wait at least pollAfterSeconds before polling again. Cursors are workspace-specific and differ from SSE event IDs. Invalid or unavailable cursors return 400; restart and reconcile resources rather than silently assuming no changes. This is a change-hint feed, not an exactly-once delivery log: reconcile authoritative resource state, and use webhooks for durable background processing. MCP calls do not create a subscription or schedule future checks. Resource IDs and event types are visible across the workspace to holders of this scope.




## OpenAPI

````yaml GET /realtime/events/poll
openapi: 3.1.0
info:
  title: Protodesk API
  version: 0.1.0
  description: >
    The Protodesk Platform API: sync your customers in, attach your own business
    objects (orders, bookings, listings) to conversations, post and read
    messages across channels, and receive every workspace event via signed
    webhooks or a resumable SSE stream.


    Authenticate every request with a workspace-scoped API key: `Authorization:
    Bearer pk_...`. Operations that support retry protection document an
    `Idempotency-Key` header. Reuse it only with an identical request. List
    pagination is described on each endpoint.


    Task-oriented guides: [docs.protodesk.io](https://docs.protodesk.io).
servers:
  - url: https://api.protodesk.io/v1
    description: Production
  - url: http://localhost:8080/v1
    description: Local development
security: []
tags:
  - name: Evelin
    description: >-
      Human-owned AI connections using the existing Evelin runtime. Generation
      never sends a customer message.
  - name: Customers
    description: People or companies contacting a workspace across channels.
  - name: Conversations
    description: Customer conversations attached to channels and external business objects.
  - name: Messages
    description: Customer, agent, AI, system, and internal messages inside conversations.
  - name: Attachments
    description: Scoped file transfer for messages.
  - name: Channel identities
    description: >-
      The same customer across WhatsApp, email, chat, and more — linked
      identities per channel.
  - name: Statuses & priorities
    description: The workspace's conversation statuses and priority levels.
  - name: Assignments
    description: >-
      Who a conversation has been assigned to, over time. Assign via POST
      /conversations/{conversationId}/assign.
  - name: Webhooks
    description: Webhook subscriptions for receiving workspace events.
  - name: Realtime
    description: Server-sent event stream of workspace events.
  - name: API Keys
    description: Create, list, and revoke workspace API keys.
  - name: Account
    description: The workspace and scopes behind your API key.
  - name: System
    description: Service metadata and health endpoints.
paths:
  /realtime/events/poll:
    get:
      tags:
        - Realtime
      summary: Check workspace event notifications
      description: >
        Bounded, immediate JSON polling for REST and MCP. Requires
        realtime:read. The first call without a cursor returns no events and a
        starting nextCursor. Pass that cursor on subsequent calls, keeping the
        same filters, to read up to 100 notifications in chronological order.
        Save nextCursor after processing a page; retry the same input cursor to
        replay that page. Notifications contain resource identifiers and event
        types only, never message bodies, outbox payloads or private AI results.
        Fetch current resources using their separate read scopes. On hasMore,
        drain the next page; otherwise wait at least pollAfterSeconds before
        polling again. Cursors are workspace-specific and differ from SSE event
        IDs. Invalid or unavailable cursors return 400; restart and reconcile
        resources rather than silently assuming no changes. This is a
        change-hint feed, not an exactly-once delivery log: reconcile
        authoritative resource state, and use webhooks for durable background
        processing. MCP calls do not create a subscription or schedule future
        checks. Resource IDs and event types are visible across the workspace to
        holders of this scope.
      operationId: pollWorkspaceEvents
      parameters:
        - name: cursor
          in: query
          description: >-
            Opaque nextCursor from the preceding poll. Omit to establish a new
            checkpoint.
          schema:
            type: string
            maxLength: 512
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 25
        - name: conversationId
          in: query
          description: Only notifications associated with this conversation.
          schema:
            type: string
            maxLength: 128
        - name: eventTypes
          in: query
          description: >-
            Comma-separated supported event types. Keep filters unchanged while
            resuming.
          schema:
            type: string
            maxLength: 1024
          example: message.created,conversation.resolved
      responses:
        '200':
          description: A bounded notification page or an initial checkpoint.
          content:
            application/json:
              schema:
                type: object
                required:
                  - data
                  - nextCursor
                  - hasMore
                  - pollAfterSeconds
                properties:
                  data:
                    type: array
                    maxItems: 100
                    items:
                      type: object
                      required:
                        - id
                        - type
                        - resourceType
                        - resourceId
                        - createdAt
                      properties:
                        id:
                          type: string
                        type:
                          type: string
                        resourceType:
                          type: string
                        resourceId:
                          type: string
                        conversationId:
                          type: string
                        createdAt:
                          type: string
                          format: date-time
                  nextCursor:
                    type: string
                  hasMore:
                    type: boolean
                  pollAfterSeconds:
                    type: integer
                    enum:
                      - 3
        default:
          $ref: '#/components/responses/Error'
      security:
        - ApiKeyAuth: []
components:
  responses:
    Error:
      description: >-
        Error response. All /v1 responses carry RateLimit-Limit,
        RateLimit-Remaining, and RateLimit-Reset headers. A 429
        (rate_limit.exceeded) additionally carries Retry-After. Request bodies
        exceeding the route-class limit (1KB reads, 64KB writes) return 413
        (request.body_too_large).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
        RateLimit-Limit:
          $ref: '#/components/headers/RateLimitLimit'
        RateLimit-Remaining:
          $ref: '#/components/headers/RateLimitRemaining'
        RateLimit-Reset:
          $ref: '#/components/headers/RateLimitReset'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
  headers:
    RequestId:
      description: Request id for tracing this request in logs and support.
      schema:
        type: string
        example: req_x6q5vl75f5d53m7oet2k4r5w6a
    RateLimitLimit:
      description: >-
        Request budget for the route class (read or write) applied to this
        request.
      schema:
        type: integer
        example: 40
    RateLimitRemaining:
      description: Requests remaining in the current budget after this request.
      schema:
        type: integer
        example: 39
    RateLimitReset:
      description: Seconds until the budget refills to its full limit.
      schema:
        type: integer
        example: 1
    RetryAfter:
      description: Seconds to wait before retrying, sent with 429 responses.
      schema:
        type: integer
        example: 1
  schemas:
    ErrorEnvelope:
      type: object
      required:
        - error
      properties:
        error:
          $ref: '#/components/schemas/Error'
    Error:
      type: object
      required:
        - code
        - message
        - requestId
      properties:
        code:
          type: string
          example: route.not_found
        message:
          type: string
          example: Not found
        requestId:
          type: string
          example: req_x6q5vl75f5d53m7oet2k4r5w6a
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: Protodesk API key
      description: >
        Use a workspace API key in the Authorization header: Bearer pk_....
        Older pk_live_ and pk_test_ keys remain valid; their prefixes do not
        isolate data or select a separate environment.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.