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

# Upload media

> Give a URL or a file; the server decides how to store it. Images given by URL come back
ready (`201`, `status` `active`). Videos given by URL, and files larger than 50 MB, come back
`processing` (`202`): poll `GET /media_contents/{id}` until `status` is `active` (the `link`
is final then) or `failed` (`error_message` says why). Files sent as `multipart/form-data`
in `files[]` (1 to 10, up to 200 MB each) come back `active` (`201`). Use `presign` only for
files above the multipart limit. A `processing` or `failed` item cannot be attached to a post.



## OpenAPI

````yaml /openapi.json post /workspaces/{workspace}/media_contents
openapi: 3.1.0
info:
  title: PublishBuddy
  version: 1.0.0
servers:
  - url: https://api.publishbuddy.com/v1
security:
  - bearerAuth: []
paths:
  /workspaces/{workspace}/media_contents:
    post:
      tags:
        - MediaContent
      summary: Upload media
      description: >-
        Give a URL or a file; the server decides how to store it. Images given
        by URL come back

        ready (`201`, `status` `active`). Videos given by URL, and files larger
        than 50 MB, come back

        `processing` (`202`): poll `GET /media_contents/{id}` until `status` is
        `active` (the `link`

        is final then) or `failed` (`error_message` says why). Files sent as
        `multipart/form-data`

        in `files[]` (1 to 10, up to 200 MB each) come back `active` (`201`).
        Use `presign` only for

        files above the multipart limit. A `processing` or `failed` item cannot
        be attached to a post.
      operationId: workspaces.media_contents.store
      parameters:
        - name: workspace
          in: path
          required: true
          description: The workspace UUID
          schema:
            type: string
      requestBody:
        description: >-
          Either a JSON body with `url`, or a `multipart/form-data` body with
          `files[]`.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StoreMediaContentFromUrlRequestStub'
          multipart/form-data:
            schema:
              type: object
              properties:
                label:
                  type:
                    - string
                    - 'null'
                  description: >-
                    Label shown in the library, applied to every file in the
                    request
                  maxLength: 250
                folder_id:
                  type:
                    - string
                    - 'null'
                  format: uuid
                  description: >-
                    Folder UUID from `GET
                    /workspaces/{workspace}/media_library/folders`; omit for the
                    root of the library
                files:
                  type: array
                  description: >-
                    The image or video files (1 to 10 per request, up to 200 MB
                    each). JPEG, PNG, GIF, WebP, MP4 and QuickTime; the type is
                    read from the bytes. A larger file answers 413: use
                    `presign` for it.
                  items:
                    type: string
                    format: binary
                    contentMediaType: application/octet-stream
                  minItems: 1
                  maxItems: 10
              required:
                - files
      responses:
        '201':
          description: 'Stored: every item in `data` is `active`.'
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/MediaContentResource'
                  message:
                    type: string
                required:
                  - data
                  - message
        '202':
          description: >-
            Accepted: the item in `data` is `processing`; poll `GET
            /media_contents/{id}` until it is `active` or `failed`.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/MediaContentResource'
                  message:
                    type: string
                required:
                  - data
                  - message
        '401':
          $ref: '#/components/responses/AuthenticationException'
        '404':
          $ref: '#/components/responses/ModelNotFoundException'
        '413':
          description: >-
            Too large: the URL announces a file over the 2 GB library limit, or
            a file in `files[]` is over the per-file limit, in which case the
            message points at `presign`.
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                required:
                  - message
        '422':
          $ref: '#/components/responses/ValidationException'
components:
  schemas:
    StoreMediaContentFromUrlRequestStub:
      type: object
      description: >-
        The JSON shape of `POST /workspaces/{workspace}/media_contents`: a file
        given by URL. The multipart

        shape (files in the request) is StoreMediaContentFilesRequestStub; the
        generated spec shows both.
      properties:
        url:
          type: string
          format: uri
          description: >-
            Public http(s) URL of the image or video. Redirects are followed (3
            at most) and every hop must point at a public address. The file type
            is read from the bytes, not from the URL or the Content-Type.
          maxLength: 2048
        name:
          type:
            - string
            - 'null'
          description: >-
            Name to store the file under (3 to 100 characters, no extension
            needed: it comes from the file). Defaults to the URL's file name.
          minLength: 3
          maxLength: 100
        label:
          type:
            - string
            - 'null'
          description: Label shown in the library
          maxLength: 250
        folder_id:
          type:
            - string
            - 'null'
          format: uuid
          description: >-
            Folder UUID from `GET
            /workspaces/{workspace}/media_library/folders`; omit for the root of
            the library
      required:
        - url
      title: StoreMediaContentFromUrlRequestStub
    MediaContentResource:
      type: object
      properties:
        id:
          type: string
          description: UUID
        name:
          type: string
          description: Name of media file
        full_name:
          type: string
          description: Full relative name
        label:
          type:
            - string
            - 'null'
          description: Label of media
        link:
          type: string
          description: >-
            Full link to media. Final once `status` is `active`; a `processing`
            item's link may still change.
        status:
          type: string
          description: >-
            `active`: in the library and usable in posts. `processing`: a URL
            import still downloading; poll `GET /media_contents/{id}`. `failed`:
            the import failed, see `error_message`. `temporary`: a presigned
            upload not confirmed yet.
        error_message:
          type:
            - string
            - 'null'
          description: Why a URL import failed; `null` unless `status` is `failed`
        size:
          type:
            - integer
            - 'null'
          description: Media size in bytes
        width:
          type:
            - integer
            - 'null'
          description: Width in pixel
        height:
          type:
            - integer
            - 'null'
          description: Height in pixel
        time:
          type:
            - integer
            - 'null'
          description: Time is second
        thumbnail:
          anyOf:
            - $ref: '#/components/schemas/MediaContentResource'
              description: >-
                Linked video cover (present on videos only; null for
                images/thumbnails)
            - type: 'null'
        folder_id:
          type:
            - string
            - 'null'
          description: >-
            Folder UUID, or `null` when the media sits at the root of the
            library
      required:
        - id
        - name
        - full_name
        - label
        - link
        - status
        - error_message
        - size
        - width
        - height
        - time
        - thumbnail
        - folder_id
      title: MediaContentResource
  responses:
    AuthenticationException:
      description: Unauthenticated
      content:
        application/json:
          schema:
            type: object
            properties:
              message:
                type: string
                description: Error overview.
            required:
              - message
    ModelNotFoundException:
      description: Not found
      content:
        application/json:
          schema:
            type: object
            properties:
              message:
                type: string
                description: Error overview.
            required:
              - message
    ValidationException:
      description: Validation error
      content:
        application/json:
          schema:
            type: object
            properties:
              message:
                type: string
                description: Errors overview.
              errors:
                type: object
                description: A detailed description of each field that failed validation.
                additionalProperties:
                  type: array
                  items:
                    type: string
            required:
              - message
              - errors
  securitySchemes:
    bearerAuth:
      type: http
      description: 'Personal access token, sent as `Authorization: Bearer <token>`.'
      scheme: bearer

````

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