> ## 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.

# Propose immutable content changes without publishing

> Requires help:read and help:drafts:write. Existing article only. Expected revision must match. Reusing the same key and payload for the same connection returns its existing proposal; another payload conflicts. Keys are retained with proposals. Replays recheck connection expiry, revocation, and creator membership. Never directly edits or publishes an article. Request body is capped by the public API write limit (64 KiB by default). The authoring connection and human creator are recorded server-side.



## OpenAPI

````yaml POST /authoring/articles/{id}/proposals
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_live_...`. Create endpoints accept an `Idempotency-Key` header so
    retries are always safe. Lists use opaque cursor pagination (`data` /
    `hasMore` / `nextCursor`).


    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: 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: 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:
  /authoring/articles/{id}/proposals:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
    post:
      tags:
        - Help authoring
      summary: Propose immutable content changes without publishing
      description: >-
        Requires help:read and help:drafts:write. Existing article only.
        Expected revision must match. Reusing the same key and payload for the
        same connection returns its existing proposal; another payload
        conflicts. Keys are retained with proposals. Replays recheck connection
        expiry, revocation, and creator membership. Never directly edits or
        publishes an article. Request body is capped by the public API write
        limit (64 KiB by default). The authoring connection and human creator
        are recorded server-side.
      operationId: createAuthoringProposal
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 8
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - expectedRevision
                - content
              properties:
                expectedRevision:
                  type: integer
                  format: int64
                  minimum: 1
                content:
                  $ref: '#/components/schemas/AuthoringContent'
      responses:
        '200':
          description: >-
            Saved proposal or authorized retry, with a credential-free relative
            review URL. No article was published.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthoringProposal'
        default:
          $ref: '#/components/responses/Error'
      security:
        - ApiKeyAuth: []
components:
  schemas:
    AuthoringContent:
      type: object
      additionalProperties: false
      required:
        - title
        - excerpt
        - bodyMarkdown
      properties:
        title:
          type: string
        excerpt:
          type: string
        bodyMarkdown:
          type: string
    AuthoringProposal:
      type: object
      properties:
        kind:
          type: string
          enum:
            - update
            - create
        articleSetId:
          type: string
        articleSetName:
          type: string
        newArticle:
          type:
            - object
            - 'null'
          properties:
            slug:
              type: string
            collectionId:
              type: string
            tags:
              type: array
              items:
                type: string
            featured:
              type: boolean
            reviewNote:
              type: string
        id:
          type: string
        articleId:
          type: string
        status:
          type: string
          enum:
            - pending
            - approved
            - dismissed
        baseRevision:
          type: integer
          format: int64
        currentRevision:
          type:
            - integer
            - 'null'
          format: int64
        content:
          $ref: '#/components/schemas/AuthoringContent'
        reviewUrl:
          type: string
        publicationChanged:
          type: boolean
    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
  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
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: Protodesk API key
      description: >
        Use a workspace API key in the Authorization header. Keys use
        pk_live_<key_id>_<secret> for production and pk_test_<key_id>_<secret>
        for test mode.

````

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