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

# Edit a piece of content

> Rename a piece of content, replace its body, or both.

**Replacement, not a merge:** `body` replaces the artifact entirely, in the same shape the kind takes on create. Send the whole thing, not just the part that changed. Media already attached to the draft is the one exception — you can't send it back, so it's carried over rather than dropped.

**Scheduled pieces are locked:** if a send is queued or already running for this piece, its words go out exactly as written, so an edit to `body` is refused with an explanation. Cancel the schedule in the app first. Renaming is always allowed — a title isn't published anywhere.



## OpenAPI

````yaml /paragraph-api/openapi.json patch /v1/content/{contentId}
openapi: 3.1.0
info:
  title: Paragraph API
  version: 1.0.0
  description: >-
    Public API for interacting with Paragraph publications, posts, users, and
    coined writing.


    ## Rate Limiting

    API requests are rate-limited to ensure fair usage. Contact
    support@paragraph.com for higher limits.


    ## Pagination

    List endpoints support cursor-based pagination using `cursor` and `limit`
    parameters.
  contact:
    name: Paragraph Support
    email: support@paragraph.com
    url: https://paragraph.com/support
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
servers:
  - url: https://public.api.paragraph.com/api
    description: Production server
security:
  - {}
tags:
  - name: publications
    description: Operations related to publications
  - name: posts
    description: Operations related to posts and content
  - name: users
    description: Operations related to users and authors
  - name: coins
    description: Operations related to tokenized content
  - name: subscribers
    description: Operations related to subscriber management (requires API key)
paths:
  /v1/content/{contentId}:
    patch:
      tags:
        - content
      summary: Edit a piece of content
      description: >-
        Rename a piece of content, replace its body, or both.


        **Replacement, not a merge:** `body` replaces the artifact entirely, in
        the same shape the kind takes on create. Send the whole thing, not just
        the part that changed. Media already attached to the draft is the one
        exception — you can't send it back, so it's carried over rather than
        dropped.


        **Scheduled pieces are locked:** if a send is queued or already running
        for this piece, its words go out exactly as written, so an edit to
        `body` is refused with an explanation. Cancel the schedule in the app
        first. Renaming is always allowed — a title isn't published anywhere.
      operationId: updateContent
      parameters:
        - name: contentId
          in: path
          required: true
          schema:
            type: string
          description: Unique identifier of the content
      requestBody:
        description: Body
        content:
          application/json:
            schema:
              type: object
              properties:
                title:
                  type: string
                  minLength: 1
                  maxLength: 200
                  description: New name for this piece in your library
                body:
                  type: object
                  properties:
                    text:
                      type: string
                      description: >-
                        The post's text. `tweet`: a single tweet, at most 280
                        characters — use `tweets` for a thread and never send
                        both. `linkedin`: the post body.
                    tweets:
                      type: array
                      items:
                        type: string
                      description: >-
                        `tweet` only. One entry per tweet, in posting order,
                        each at most 280 characters. Never concatenate a thread
                        into one entry.
                    subject:
                      type: string
                      description: '`newsletter` only. Subject line.'
                    preheader:
                      type: string
                      description: >-
                        `newsletter` only. Optional preview line shown after the
                        subject.
                    body:
                      type: string
                      description: >-
                        `newsletter`: the email body. `x_article`: the article's
                        full CommonMark markdown.
                    title:
                      type: string
                      description: >-
                        `x_article` only. The headline as published on X.
                        Separate from the piece's `title`, which only names it
                        in your library.
                    canonicalUrl:
                      type: string
                      description: >-
                        `x_article` only. The original post this Article is a
                        version of. It must also appear as a markdown link
                        inside `body`.
                    media:
                      readOnly: true
                      description: >-
                        Not accepted. Media has to be uploaded to the
                        destination platform first, which the API can't do yet;
                        sending this field is rejected.
                  additionalProperties: false
                  description: >-
                    The replacement artifact, in the shape this piece's kind
                    uses
              additionalProperties: false
      responses:
        '200':
          description: Content updated successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    description: Unique identifier for this piece of content
                  kind:
                    type: string
                    description: >-
                      What this piece is: `tweet`, `linkedin`, `newsletter`, or
                      `x_article`
                  title:
                    type: string
                    description: What this piece is called in your library
                  excerpt:
                    type: string
                    description: First readable line of the body, for listing views
                  status:
                    type: string
                    enum:
                      - draft
                      - published
                      - archived
                    description: >-
                      Whether this piece has been delivered, is still a draft,
                      or was archived
                  scheduled:
                    type: boolean
                    description: Whether a scheduled send is queued against this piece
                  lockedReason:
                    type:
                      - string
                      - 'null'
                    description: >-
                      Why this piece can't be edited right now, or null when it
                      can. A queued or in-flight send locks the words, because
                      they go out exactly as written.
                  publishedAt:
                    type:
                      - string
                      - 'null'
                    description: ISO 8601 timestamp of the first delivery, or null
                  url:
                    type:
                      - string
                      - 'null'
                    description: >-
                      Where this piece went live, from the same delivery
                      `publishedAt` came from. Null when it hasn't been
                      delivered, and null by design for a channel that publishes
                      no page: a custom email renders into the message itself,
                      so there is no address to link to. Never guessed — a
                      delivery whose id isn't shaped like its channel reports
                      null rather than a link that would 404.
                  archivedAt:
                    type:
                      - string
                      - 'null'
                    description: >-
                      ISO 8601 timestamp of when this piece was archived, or
                      null
                  createdAt:
                    type: string
                    description: ISO 8601 timestamp of creation
                  updatedAt:
                    type: string
                    description: ISO 8601 timestamp of the last change
                  body:
                    type: object
                    additionalProperties: {}
                    description: The artifact itself, in the shape its kind uses
                required:
                  - id
                  - kind
                  - title
                  - excerpt
                  - status
                  - scheduled
                  - lockedReason
                  - publishedAt
                  - url
                  - archivedAt
                  - createdAt
                  - updatedAt
                  - body
        '400':
          description: The draft doesn't match its kind, or a queued send has locked it
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - false
                    description: Always false for error responses
                  msg:
                    type: string
                    description: Human-readable error message
                required:
                  - success
                  - msg
        '401':
          description: Invalid or missing API key
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - false
                    description: Always false for error responses
                  msg:
                    type: string
                    description: Human-readable error message
                required:
                  - success
                  - msg
        '404':
          description: Content not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - false
                    description: Always false for error responses
                  msg:
                    type: string
                    description: Human-readable error message
                required:
                  - success
                  - msg
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - false
                    description: Always false for error responses
                  msg:
                    type: string
                    description: Human-readable error message
                required:
                  - success
                  - msg
      security:
        - apiKey: []
      x-codeSamples:
        - lang: typescript
          label: Rewrite a draft
          source: |-
            import { ParagraphAPI } from "@paragraph-com/sdk"

            const api = new ParagraphAPI({ apiKey: "your-api-key" })
            const draft = await api.content.update({
              id: "7f3a2c18-5b9e-4c21-9a0d-8e6b1f4d2a55",
              body: { text: "Rewritten, and shorter." },
            })
        - lang: bash
          label: Rename a draft using curl
          source: >-
            curl -X PATCH
            "https://public.api.paragraph.com/api/v1/content/7f3a2c18-5b9e-4c21-9a0d-8e6b1f4d2a55"
            \
              -H "Authorization: Bearer your-api-key" \
              -H "Content-Type: application/json" \
              -d '{"title": "Launch note, second pass"}'
components:
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: >-
        API key for authenticating protected endpoints. Pass as Bearer token in
        Authorization header.

````