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

# Set when a sent message expires

> Schedule the message to expire, replacing any expiry it already has. When the time comes it is replaced with a notice that it expired (or deleted), its buttons stop working, and by default LithoBlocks clears its own copies of what it said. Free. Members can expire only the messages they sent; owners and admins any.



## OpenAPI

````yaml /api-reference/openapi.json put /v1/messages/{id}/expiration
openapi: 3.0.0
info:
  version: 0.0.1
  title: LithoBlocks API
  description: >-

    Manage templates, compile and send Slack messages, schedule delivery, build
    batch digests, and configure interactive workflows.


    Use /v1 paths and snake_case request fields. Authenticate with an
    organization-scoped API key in the Authorization: Bearer header. Each
    operation documents its required scope; a key without it receives 403 and
    required_scopes. A user's organization role limits which scopes a key can
    receive. Compiling and sending require messages:create; read access alone
    does not allow either operation.


    Create and manage keys in Integrations → API Keys. Store credentials in a
    secret manager, grant only the scopes needed, and use separate keys for each
    environment. Resources and credentials do not transfer between environments.


    Use code and request_id to diagnose API errors. The error field can be a
    string or a schema-validation object; consult the endpoint response schema
    for details. Resource list endpoints document their pagination and
    compatibility fields individually.


    See the documentation guides for API key lifecycle, the complete scope/role
    matrix, environment availability, input-schema discovery, and idempotent
    sending. The endpoint definitions below are the source for request and
    response contracts.
                
  contact:
    name: LithoBlocks
    url: https://lithoblocks.com
    email: support@lithoblocks.com
servers:
  - url: https://api.lithoblocks.com
    description: Production (paths in this spec are rooted at /v1/...)
  - url: http://localhost:9999
    description: Local dev (paths in this spec are rooted at /v1/...)
security: []
paths:
  /v1/messages/{id}/expiration:
    put:
      tags:
        - Messages
      summary: Set when a sent message expires
      description: >-
        Schedule the message to expire, replacing any expiry it already has.
        When the time comes it is replaced with a notice that it expired (or
        deleted), its buttons stop working, and by default LithoBlocks clears
        its own copies of what it said. Free. Members can expire only the
        messages they sent; owners and admins any.
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: >-
              Any unique string (a UUID is fine). Repeating a request with the
              same key and body within 24 hours replays the original response
              with `Idempotency-Replayed: true` instead of running again; the
              same key with a different body is a 409. Incomplete and 5xx
              outcomes are retained for reconciliation beyond 24 hours. Applies
              only on the documented endpoints. Never automatically change keys
              to bypass an uncertain outcome.
            example: 3f7d2c1a-9b4e-4f0a-8c6d-2e1b5a7c9d10
          required: false
          in: header
          name: Idempotency-Key
      requestBody:
        description: When and how it expires
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MessageExpirationInput'
      responses:
        '200':
          description: The message with its expiry
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SentMessage'
        '400':
          description: '`invalid_request`: an edit with nothing to change'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '402':
          description: >-
            `insufficient_credits` or `overage_limit_exceeded`: a re-render uses
            one credit
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '403':
          description: >-
            Insufficient scope, or `not_message_sender`: members change only the
            messages they sent
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '404':
          description: Message not found in your organization
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '409':
          description: >-
            `message_not_live`, `expiration_in_progress`, `no_expiration`,
            `mutation_in_progress` or `reconciliation_required`; also an
            Idempotency-Key conflict, or `slack_not_connected`
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '422':
          description: >-
            Validation failed, or `expiration_in_past`: an expiry must be at
            least 60 seconds away
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/ApiError'
        '429':
          description: Rate limited
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '500':
          description: Internal error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '502':
          description: >-
            `slack_refused`: Slack refused the change and nothing changed;
            `details` carries Slack's error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '503':
          description: >-
            `rate_limited`: Slack is rate limiting changes; retry after the
            Retry-After header
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '504':
          description: >-
            `slack_outcome_unknown`: the change may or may not have happened;
            the message now needs reconciliation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
      security:
        - bearerAuth:
            - messages:update
components:
  schemas:
    MessageExpirationInput:
      type: object
      properties:
        after_seconds:
          type: integer
          minimum: 60
          maximum: 31622400
          description: >-
            Seconds after the message is delivered. At least 60: expiry runs
            about once a minute.
        at:
          type: string
          format: date-time
          description: An absolute time, at least 60 seconds from now.
        mode:
          type: string
          enum:
            - replace
            - delete
          default: replace
          description: >-
            `replace` (default): the message is replaced with a notice that it
            expired, and its buttons stop working. `delete`: it is deleted from
            Slack.
        retain_content:
          type: boolean
          default: false
          description: >-
            By default LithoBlocks clears its own copies of what the message
            said when it expires. `true` keeps them.
      additionalProperties: false
      description: >-
        Expire the message: replace it with a notice, or delete it. Precise to
        about a minute; a button clicked after the deadline does nothing even
        before the message is replaced.
    SentMessage:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: >-
            LithoBlocks' id for the message; send responses return it as
            `message_id`.
        template_id:
          type: string
          nullable: true
          format: uuid
          description: Null once the template has been deleted.
        template_name:
          type: string
          nullable: true
          description: The template's name when the message was sent.
        template_version_id:
          type: string
          nullable: true
          format: uuid
        workspace_id:
          type: string
          description: The Slack workspace (team) id.
        channel_id:
          type: string
          nullable: true
          description: The resolved channel; a `D…` id for a direct message.
        channel_name:
          type: string
          nullable: true
          description: >-
            The channel's name when the message was sent, without the #. Null
            for direct messages, private channels and messages sent before
            2026-10-22.
        message_ts:
          type: string
          description: Slack's timestamp for the message.
        recipient_email:
          type: string
          nullable: true
        recipient_slack_id:
          type: string
          nullable: true
        sent_at:
          type: string
        sent_by:
          type: string
          format: uuid
          description: The user the send is attributed to; for an API key, the key's owner.
        sender_api_key_id:
          type: string
          nullable: true
          format: uuid
        sender_client_id:
          type: string
          nullable: true
          description: The OAuth client a session token was issued to, e.g. an MCP client.
        source:
          type: string
          nullable: true
          enum:
            - api
            - api_bulk
            - web
            - scheduled
            - digest
            - slash
          description: How it was sent. Null for messages sent before 2026-10-22.
        reference:
          type: string
          nullable: true
          description: The caller's own handle for the message, if it gave one.
        lifecycle:
          type: string
          enum:
            - live
            - deleted
            - expired
          description: What has happened to the message in Slack since it was sent.
        revision:
          type: integer
          description: >-
            Increments with every change; a change names the revision it was
            made against.
        edited_at:
          type: string
          nullable: true
        deleted_at:
          type: string
          nullable: true
        expired_at:
          type: string
          nullable: true
        change_state:
          type: string
          enum:
            - idle
            - in_progress
            - needs_reconciliation
          description: >-
            `needs_reconciliation`: Slack's answer to a change was lost, and a
            person must say whether it went through before anything else can
            change.
        pending_action:
          type: string
          nullable: true
          enum:
            - edit
            - rerender
            - interaction_update
            - delete
            - expire
        fallback_text:
          type: string
          nullable: true
          description: The notification text sent with the blocks.
        text_editable:
          type: boolean
          description: >-
            Whether the stored blocks are exactly what Slack holds, so the text
            can be corrected in place.
        expiration:
          $ref: '#/components/schemas/SentMessageExpiration'
      required:
        - id
        - template_id
        - template_name
        - template_version_id
        - workspace_id
        - channel_id
        - channel_name
        - message_ts
        - recipient_email
        - recipient_slack_id
        - sent_at
        - sent_by
        - sender_api_key_id
        - sender_client_id
        - source
        - reference
        - lifecycle
        - revision
        - edited_at
        - deleted_at
        - expired_at
        - change_state
        - pending_action
        - fallback_text
        - text_editable
        - expiration
    ApiError:
      type: object
      properties:
        error:
          type: string
          description: Human-readable summary. Not stable; match on `code`.
        code:
          $ref: '#/components/schemas/ErrorCode'
        request_id:
          type: string
          description: >-
            Echoed from the request's X-Request-Id header, or generated. Quote
            it in support requests.
        message:
          type: string
        details:
          type: string
        error_details:
          type: string
        success:
          type: boolean
          enum:
            - false
        valid:
          type: boolean
          enum:
            - false
        required_scopes:
          type: array
          items:
            type: string
        user_scopes:
          type: array
          items:
            type: string
      required:
        - error
        - code
        - request_id
    ValidationError:
      type: object
      properties:
        success:
          type: boolean
          enum:
            - false
        error:
          type: object
          properties:
            issues:
              type: array
              items:
                type: object
                properties:
                  code:
                    type: string
                  path:
                    type: array
                    items:
                      anyOf:
                        - type: string
                        - type: number
                  message:
                    type: string
                required:
                  - code
                  - path
                  - message
            name:
              type: string
          required:
            - issues
            - name
        message:
          type: string
          description: >-
            The issues as one line, `path: message; path: message`, for callers
            that show a string (form builders such as Make)
        code:
          type: string
          enum:
            - validation_failed
        request_id:
          type: string
      required:
        - success
        - error
        - message
        - code
        - request_id
    SentMessageExpiration:
      type: object
      nullable: true
      properties:
        expires_at:
          type: string
        mode:
          type: string
          enum:
            - replace
            - delete
          description: >-
            `replace` (default): the message is replaced with a notice that it
            expired, and its buttons stop working. `delete`: it is deleted from
            Slack.
        state:
          type: string
          enum:
            - scheduled
            - processing
            - completed
            - failed
            - cancelled
          description: >-
            `failed`: the expiry gave up after its retries (see `last_error`);
            the message's buttons still do nothing after the deadline.
        retain_content:
          type: boolean
          description: >-
            Whether LithoBlocks keeps its copies of what the message said after
            it expires.
        attempts:
          type: integer
        last_error:
          type: string
          nullable: true
        completed_at:
          type: string
          nullable: true
      required:
        - expires_at
        - mode
        - state
        - retain_content
        - attempts
        - last_error
        - completed_at
      description: The message's expiry, if one was ever set.
    ErrorCode:
      type: string
      enum:
        - unauthenticated
        - invalid_token
        - insufficient_scope
        - access_denied
        - validation_failed
        - invalid_request
        - invalid_data
        - invalid_destination
        - invalid_search_query
        - not_found
        - template_not_found
        - version_not_found
        - organization_not_found
        - entity_not_found
        - field_not_found
        - user_not_found
        - profile_not_found
        - credits_not_found
        - insufficient_credits
        - overage_limit_exceeded
        - credit_deduction_failed
        - compilation_failed
        - no_blocks_to_send
        - slack_not_connected
        - slack_user_not_found
        - slack_dm_failed
        - slack_token_decrypt_failed
        - slack_api_error
        - already_exists
        - invitation_pending
        - idempotency_conflict
        - idempotency_in_progress
        - rate_limited
        - tier_limit
        - invalid_state
        - template_archived
        - template_in_use
        - template_not_activated
        - current_version_changed
        - message_not_found
        - not_message_sender
        - revision_conflict
        - message_not_live
        - mutation_in_progress
        - reconciliation_required
        - nothing_to_reconcile
        - text_not_editable
        - slack_refused
        - slack_outcome_unknown
        - expiration_in_past
        - expiration_in_progress
        - no_expiration
        - expiration_exceeds_maximum
        - maintenance
        - misconfigured
        - internal_error
      description: >-
        Machine-readable reason for the failure. Match on this, not on `error`.
        New codes may be added; existing ones are stable.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: >-
        LithoBlocks API key obtained from your organization dashboard. The
        LithoBlocks MCP server also presents a Supabase-issued user session
        token here on the user's behalf; such a token acts as that user with the
        scopes their organization role allows.

````

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