Blink Messages API

Send, read, edit and delete messages within a chat.

Operations 6

GET /chats/{chatId}/messages List messages from a chat #
POST /chats/{chatId}/messages Send a new message into a chat #
GET /chats/{chatId}/messages/{messageId} Look up a single message #
PATCH /chats/{chatId}/messages/{messageId} Edit the contents of a message #
DELETE /chats/{chatId}/messages/{messageId} Delete a message #

Specifications

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/joinblink-com:joinblink-com-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

joinblink-com-messages-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Blink Chat Messages API
  version: 1.1.0
  description: 'The Blink Chat API lets integrations create and manage chats, control who has access to them and who is in them, and send, read, edit, react to and delete messages on behalf of an app.

    ## Concepts

    All calls are made from an **app identity**; every endpoint acts on behalf of that app.

    A **chat** is a **private** thread of communication: the users and apps individually granted access to it take part, and nobody else.

    **Access and membership are separate.** *Access* is permission to be in a chat, given by a **grant** and listed in the chat''s **grants** collection. *Membership* is whether a principal has actually joined: members appear in the chat''s member listing and the chat reaches their inbox.

    The two usually move together — granting a user or app access also joins them, and revoking it removes them — but membership can change on its own: a member may leave, or be removed by an administrator, while keeping their grant, and may then rejoin with `:join`.

    A **member** is a user or app currently in a chat. Each member carries their `role` (`admin` or `member`), their `membership` state, and `access_via`, the grant giving them access. The caller''s own row comes back with an `@type` of `me` and carries the favourite flag and inbox state that belong to them alone.

    A **message** carries a structured **body** (Markdown, and other variants), an optional set of file **attachments**, a **sender**, and any **reactions** recorded against it.

    **Attachments** - message files and chat icons are referenced by the id of an existing attachment. This API does not yet expose a way to upload attachments.

    ## Pagination

    List endpoints return a page of results together with a `page` object. To fetch the next page, pass the returned `next_cursor` value back in the `cursor` query parameter.

    ## Errors

    Errors are returned as RFC 9457 problem documents (`application/problem+json`) using the `ProblemDetail` schema.'
servers:
- url: https://api.joinblink.com/api/platform
  description: Production API. Replace with the base URL for your environment.
security:
- bearerAuth: []
tags:
- name: Messages
  description: Send, read, edit and delete messages within a chat.
paths:
  /chats/{chatId}/messages:
    get:
      tags:
      - Messages
      summary: List messages from a chat
      operationId: listMessages
      description: 'Returns a page of messages from the given chat, ordered from newest to oldest. Pages backwards through history: pass the returned page''s `next_cursor` back via the `cursor` query parameter to fetch the messages sent before the last one on this page.'
      parameters:
      - $ref: '#/components/parameters/ChatId'
      - $ref: '#/components/parameters/Size'
      - $ref: '#/components/parameters/Cursor'
      responses:
        '200':
          description: A page of messages, newest first.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CursorPageMessage'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
    post:
      tags:
      - Messages
      summary: Send a new message into a chat
      operationId: sendMessage
      description: Sends a new message into the given chat, and returns the created message in full, exactly as a subsequent GET of the message would. The sender is required and must be the authenticated app making the request; posting under an alias or on behalf of another user or app is not permitted. The body carries the structured body and any attached files.
      parameters:
      - $ref: '#/components/parameters/ChatId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SendMessage'
            examples:
              markdown:
                summary: Markdown message from an app, with link unfurling
                value:
                  sender:
                    '@type': app
                    app_identity_id: aid-00000000-0000-0000-0000-000000000005
                  body:
                    '@type': markdown
                    markdown: '**Heads up:** the build is broken — see #123.'
                  unfurl_links: true
              with_attachment:
                summary: Message with an image attachment
                value:
                  sender:
                    '@type': app
                    app_identity_id: aid-00000000-0000-0000-0000-000000000005
                  files:
                  - attachment_id: a-00000000-0000-0000-0000-000000000000
                    type: IMAGE
                    caption: Office whiteboard photo
                  body:
                    '@type': markdown
                    markdown: Notes from today's standup
      responses:
        '201':
          description: The created message.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Message'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
  /chats/{chatId}/messages/{messageId}:
    get:
      tags:
      - Messages
      summary: Look up a single message
      operationId: getMessage
      description: Looks up a single message by its identifier and returns it in full.
      parameters:
      - $ref: '#/components/parameters/ChatId'
      - $ref: '#/components/parameters/MessageId'
      responses:
        '200':
          description: The message.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Message'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
    patch:
      tags:
      - Messages
      summary: Edit the contents of a message
      operationId: updateMessage
      description: 'Edits the contents of an existing message, and returns the edited message in full, exactly as a subsequent GET of the message would, carrying the server-set `edited_at`. Each field follows PATCH semantics: omit a field to leave it unchanged, or supply a value to replace it. An empty `files` list removes all attachments.'
      parameters:
      - $ref: '#/components/parameters/ChatId'
      - $ref: '#/components/parameters/MessageId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EditMessage'
            examples:
              editBody:
                summary: Replace the message body
                value:
                  body:
                    '@type': markdown
                    markdown: '**Update:** the build is green again.'
      responses:
        '200':
          description: The edited message.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Message'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
    delete:
      tags:
      - Messages
      summary: Delete a message
      operationId: deleteMessage
      description: 'Deletes an existing message by clearing it: the message is left in place, but its attachments are discarded and its body is replaced with a `deleted` marker, so clients can indicate that a message used to exist at this position. The deleted message is returned in full, exactly as a subsequent GET of it would with a `deleted` body and no files.'
      parameters:
      - $ref: '#/components/parameters/ChatId'
      - $ref: '#/components/parameters/MessageId'
      responses:
        '200':
          description: The deleted message.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Message'
              example:
                message_id:
                  chat_id: c-00000000-0000-0000-0000-000000000000
                  local_message_id: m-00000000-0000-0000-0000-000000000000
                sender:
                  '@type': app
                  app_identity_id: aid-00000000-0000-0000-0000-000000000000
                created_at: '2026-09-04T18:08:03.446993Z'
                edited_at: '2026-09-08T08:07:40.798289Z'
                files: []
                body:
                  '@type': deleted
                reactions: []
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
  /chats/{chatId}/messages/{messageId}/permalink:
    get:
      tags:
      - Messages
      summary: Get a durable link to a message
      operationId: getMessagePermalink
      description: Returns a durable link to a message, suitable for referencing or sharing the message outside the normal chat flow. Works for messages sent by both users and apps.
      parameters:
      - $ref: '#/components/parameters/ChatId'
      - $ref: '#/components/parameters/MessageId'
      responses:
        '200':
          description: The message permalink.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessagePermalink'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
components:
  schemas:
    App:
      type: object
      description: A message sent by an automated app.
      required:
      - '@type'
      properties:
        '@type':
          type: string
          enum:
          - app
          example: app
        app_identity_id:
          type: string
          description: The app that sent the message.
          example: aid-00000000-0000-0000-0000-000000000000
    Sender:
      description: The originator of a message. A message read back may have been sent by a user, by a user acting under an alias, by an app, or by the system itself (for membership changes, chat lifecycle events, etc.). Serialised with an `@type` discriminator. When sending a message only the authenticated app may be named as the sender — see `SendMessage`.
      oneOf:
      - $ref: '#/components/schemas/User'
      - $ref: '#/components/schemas/Alias'
      - $ref: '#/components/schemas/App'
      - $ref: '#/components/schemas/System'
      discriminator:
        propertyName: '@type'
        mapping:
          user: '#/components/schemas/User'
          alias: '#/components/schemas/Alias'
          app: '#/components/schemas/App'
          system: '#/components/schemas/System'
    Reaction:
      type: object
      description: A reaction recorded against a message. `users` always contains the authenticated user if they reacted, but might not contain every user who reacted; `count` is always the total number of unique users who recorded the reaction (so it may exceed the length of `users`).
      properties:
        reaction:
          type: string
          description: The reaction, as an emoji string.
          example: 👍
        count:
          type: integer
          format: int64
          description: The number of unique users who have recorded this reaction.
          example: 3
        users:
          type: array
          description: The IDs of a possible subset of users who have recorded this reaction; always includes the authenticated user if they recorded it.
          uniqueItems: true
          items:
            type: string
            example: u-00000000-0000-0000-0000-000000000000
    Header:
      type: object
      description: 'A header body: the automatically-generated first message of a chat, announcing its creation (e.g. "Alex created the chat"). Attributed to whoever actually created the chat (a user or app sender, never system). Response-only: created by the system when a chat is created and never sent or edited by a client.'
      required:
      - '@type'
      properties:
        '@type':
          type: string
          enum:
          - header
          example: header
        text:
          type: string
          description: A human-readable rendering of the chat-creation notice.
          example: Alex created the chat.
    SendMessage:
      type: object
      description: Parameters for sending a new message into a chat.
      required:
      - sender
      properties:
        sender:
          allOf:
          - $ref: '#/components/schemas/App'
          description: The message sender. Required, and must be the authenticated app making the request — an `app` sender carrying your own app identity. Posting under an alias or on behalf of another user or app is not permitted.
        files:
          type: array
          description: Attachments to include with the message.
          items:
            $ref: '#/components/schemas/File'
        body:
          $ref: '#/components/schemas/Body'
        unfurl_links:
          type: boolean
          description: Whether links found in the message should be unfurled into previews.
          example: true
    User:
      type: object
      description: A message sent by a regular user, posting under their own identity.
      required:
      - '@type'
      properties:
        '@type':
          type: string
          enum:
          - user
          example: user
        user_id:
          type: string
          description: The user who sent the message.
          example: u-00000000-0000-0000-0000-000000000000
    Alias:
      type: object
      description: A message sent by a user posting under an alias.
      required:
      - '@type'
      properties:
        '@type':
          type: string
          enum:
          - alias
          example: alias
        user_id:
          type: string
          description: The underlying user who sent the message.
          example: u-00000000-0000-0000-0000-000000000000
        alias_id:
          type: string
          description: The alias the user was posting as.
          example: al-00000000-0000-0000-0000-000000000000
    ProblemDetail:
      type: object
      additionalProperties: true
      description: An RFC 9457 problem document describing why the request failed.
      properties:
        type:
          type: string
          format: uri
          description: Identifies the problem type; `about:blank` when unclassified.
          example: about:blank
        title:
          type: string
          description: Short, human-readable summary of the problem type.
          example: Not Found
        status:
          type: integer
          format: int32
          description: The HTTP status code, repeated in the body.
          example: 404
        detail:
          type: string
          description: Human-readable explanation specific to this occurrence.
          example: Not Found
        instance:
          type: string
          format: uri
          description: The path of the request that failed.
    File:
      type: object
      description: A file attached to a message.
      properties:
        attachment_id:
          type: string
          description: The id of an existing attachment in the attachments service. This API does not yet provide a way to upload attachments.
          example: a-00000000-0000-0000-0000-000000000000
        type:
          type: string
          description: Broad category describing the content of an attached file. Determines how clients should preview or render the attachment.
          enum:
          - UNKNOWN
          - IMAGE
          - AUDIO
          - VIDEO
        caption:
          type: string
          description: Optional caption describing the file. Used as alt-text for items being visually rendered.
          example: Office whiteboard photo
    Empty:
      type: object
      description: An empty body, used for messages that carry no renderable content of their own (for example, messages whose payload is conveyed entirely through attachments).
      required:
      - '@type'
      properties:
        '@type':
          type: string
          enum:
          - empty
          example: empty
    Structured:
      type: object
      description: 'A structured-message body: a placeholder for rich, structured messages whose concrete shape is not yet defined. Response-only for now — a message may not be sent or edited with this body type; the variant exists so pre-existing rich messages can be represented when read back.'
      required:
      - '@type'
      properties:
        '@type':
          type: string
          enum:
          - structured
          example: structured
    Body:
      description: The structured body of a message. Always has a discriminated content type indicating how clients should render it. Serialised with an `@type` discriminator. On send and edit only `markdown` and `empty` may be supplied; the remaining variants are response-only.
      oneOf:
      - $ref: '#/components/schemas/Markdown'
      - $ref: '#/components/schemas/Empty'
      - $ref: '#/components/schemas/Structured'
      - $ref: '#/components/schemas/SystemBody'
      - $ref: '#/components/schemas/Header'
      - $ref: '#/components/schemas/Deleted'
      - $ref: '#/components/schemas/Unknown'
      discriminator:
        propertyName: '@type'
        mapping:
          markdown: '#/components/schemas/Markdown'
          empty: '#/components/schemas/Empty'
          structured: '#/components/schemas/Structured'
          system: '#/components/schemas/SystemBody'
          header: '#/components/schemas/Header'
          deleted: '#/components/schemas/Deleted'
          unknown: '#/components/schemas/Unknown'
    PageMetadata:
      type: object
      description: Metadata describing a page of a cursor-paginated listing.
      properties:
        size:
          type: integer
          format: int64
          description: The number of items in this page.
        total_elements:
          type:
          - integer
          - 'null'
          format: int64
          description: Total number of items across all pages, when known; otherwise null.
        total_pages:
          type:
          - integer
          - 'null'
          format: int64
          description: Total number of pages, when known; otherwise null.
        has_next:
          type: boolean
          description: Whether a further page is available.
        next_cursor:
          type:
          - string
          - 'null'
          description: Opaque, base64-encoded cursor for the next page; null if there is none.
        prev_cursor:
          type:
          - string
          - 'null'
          description: Opaque, base64-encoded cursor for the previous page; null if there is none.
    Markdown:
      type: object
      description: A Markdown body, expected to be rendered by a Markdown-capable client.
      required:
      - '@type'
      properties:
        '@type':
          type: string
          enum:
          - markdown
          example: markdown
        markdown:
          type: string
          description: The Markdown source for the message.
          example: '**Heads up:** the build is broken — see #123.'
    System:
      type: object
      description: A message generated by the chat system itself, rather than by any user or app. Used for system notices such as membership changes or chat lifecycle events.
      required:
      - '@type'
      properties:
        '@type':
          type: string
          enum:
          - system
          example: system
    CursorPageMessage:
      type: object
      description: A page of messages.
      properties:
        content:
          type: array
          items:
            $ref: '#/components/schemas/Message'
        page:
          $ref: '#/components/schemas/PageMetadata'
    EditMessage:
      type: object
      description: 'Parameters for editing an existing message. Each field follows PATCH semantics: omit a field to leave it unchanged, or supply a value to replace it. An empty `files` list removes all attachments.'
      properties:
        files:
          type: array
          description: If present, the new set of attached files; an empty list removes all attachments.
          items:
            $ref: '#/components/schemas/File'
        body:
          $ref: '#/components/schemas/Body'
    MessageId:
      type: object
      description: Globally unique identifier for a message, composed of the owning chat id and the local message id that distinguishes the message within that chat.
      required:
      - chat_id
      - local_message_id
      properties:
        chat_id:
          type: string
          description: Globally unique identifier for a chat; a `c-` prefixed string.
          example: c-00000000-0000-0000-0000-000000000000
        local_message_id:
          type: string
          description: Identifies a message within its enclosing chat; an `m-` prefixed string. Only meaningful in combination with a chat id.
          example: m-00000000-0000-0000-0000-000000000000
    MessagePermalink:
      type: object
      description: A durable link to a message.
      properties:
        permalink:
          type: string
          description: The durable URL pointing directly at the message.
          example: https://app.joinblink.com/#/inbox/c-00000000-0000-0000-0000-000000000000#m-00000000-0000-0000-0000-000000000000
    Unknown:
      type: object
      description: 'A body for a pre-existing message that cannot be represented by any other variant. Response-only: it appears when messages are read back so a chat''s history can always be listed, and is never accepted on the way in. It carries no payload, so clients should render it as a placeholder.'
      required:
      - '@type'
      properties:
        '@type':
          type: string
          enum:
          - unknown
          example: unknown
    Deleted:
      type: object
      description: A tombstone body left behind when a message is soft-deleted. Indicates to clients that a message used to be present at this position but has since been removed; any prior content and attachments are discarded.
      required:
      - '@type'
      properties:
        '@type':
          type: string
          enum:
          - deleted
          example: deleted
    Message:
      type: object
      description: A single message sent within a Blink chat.
      properties:
        message_id:
          $ref: '#/components/schemas/MessageId'
        sender:
          $ref: '#/components/schemas/Sender'
        created_at:
          type: string
          format: date-time
          description: The instant the message was originally sent.
          example: '2026-05-14T09:30:00Z'
        edited_at:
          type: string
          format: date-time
          description: The instant the message's content was last edited; absent if it has never been edited. Changes to related structures such as reactions do not update this value.
          example: '2026-05-14T09:32:11Z'
        files:
          type: array
          description: Attachments that accompany this message.
          items:
            $ref: '#/components/schemas/File'
        body:
          $ref: '#/components/schemas/Body'
        reactions:
          type: array
          description: Reactions recorded against this message. Read-only in this API.
          items:
            $ref: '#/components/schemas/Reaction'
    SystemBody:
      type: object
      description: 'A system-generated body, used for messages emitted by the chat system itself (membership changes, chat lifecycle events, etc.). Response-only: it is paired one-to-one with the `system` sender and cannot be sent or edited by a client.'
      required:
      - '@type'
      properties:
        '@type':
          type: string
          enum:
          - system
          example: system
        text:
          type: string
          description: A human-readable rendering of the system notice.
          example: Alex joined the chat.
  responses:
    Forbidden:
      description: The caller is not permitted to perform this action.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
    Unauthorized:
      description: Authentication is missing or invalid.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
    UnprocessableEntity:
      description: The request was well-formed but failed validation.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
    NotFound:
      description: The requested resource does not exist.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
    BadRequest:
      description: The request body or a parameter could not be read.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
  parameters:
    MessageId:
      name: messageId
      in: path
      required: true
      description: Identifies a message within its enclosing chat; an `m-` prefixed string. Only meaningful in combination with a chat id.
      schema:
        type: string
        example: m-00000000-0000-0000-0000-000000000000
    ChatId:
      name: chatId
      in: path
      required: true
      description: Globally unique identifier for a chat; a `c-` prefixed string.
      schema:
        type: string
        example: c-00000000-0000-0000-0000-000000000000
    Cursor:
      name: cursor
      in: query
      required: false
      description: Pagination cursor token. Pass the `next_cursor` from a previous page to fetch the next one.
      schema:
        type: string
    Size:
      name: size
      in: query
      required: false
      description: The number of items to return per page, between 1 and 150.
      schema:
        type: integer
        format: int32
        default: 50
        minimum: 1
        maximum: 150
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'A bearer token supplied in the `Authorization` header as `Authorization: Bearer <token>`.'
x-provenance:
  method: searched
  source: https://developer.joinblink.com/reference
  harvested: '2026-10-28'
  tool: harvest-readme-openapi.py
  note: Assembled verbatim from the OpenAPI definition ReadMe embeds in each operation page of the provider's developer portal; paths and components merged by API title, nothing authored.
  assembled_from:
  - https://developer.joinblink.com/reference/createchat.md
  - https://developer.joinblink.com/reference/deletechat.md
  - https://developer.joinblink.com/reference/deletemessage.md
  - https://developer.joinblink.com/reference/getchat.md
  - https://developer.joinblink.com/reference/getmessage.md
  - https://developer.joinblink.com/reference/getmessagepermalink.md
  - https://developer.joinblink.com/reference/getmymembership.md
  - https://developer.joinblink.com/reference/grantaccess.md
  - https://developer.joinblink.com/reference/joinchat.md
  - https://developer.joinblink.com/reference/leavechat.md
  - https://developer.joinblink.com/reference/listchatinbox.md
  - https://developer.joinblink.com/reference/listgrants.md
  - https://developer.joinblink.com/reference/listmembers.md
  - https://developer.joinblink.com/reference/listmessages.md
  - https://developer.joinblink.com/reference/removeappmember.md
  - https://developer.joinblink.com/reference/removeusermember.md
  - https://developer.joinblink.com/reference/revokeappaccess.md
  - https://developer.joinblink.com/reference/revokeuseraccess.md
  - https://developer.joinblink.com/reference/sendmessage.md
  - https://developer.joinblink.com/reference/updateappmemberrole.md
  - https://developer.joinblink.com/reference/updatechat.md
  - https://developer.joinblink.com/reference/updatemessage.md
  - https://developer.joinblink.com/reference/updateusermemberrole.md
  merge:
    pages: 23
    deduped: 380
    conflicts_kept_first: 0