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

# Prepare a local file upload

> Creates an upload job and returns signed credentials so you can POST a local file directly to the returned `uploadUrl`. After preparing, POST the file to `uploadUrl` as multipart form data with the returned `params`, `signature`, and `file` fields, then poll `GET /uploads/{id}` until status is `ready`.

See [File uploads](/api/file-uploads#local-file-upload) for a full walkthrough and curl examples.

**Supported file types:**
- Images: JPEG, PNG, GIF, WebP
- Videos: MP4, QuickTime (MOV)

**File size limits:**
- Images: 10 MB max
- GIFs: 15 MB max
- Videos: 350 MB max

The returned credentials are short-lived. Upload the file before `expiresAt`.



## OpenAPI

````yaml /api/openapi.json post /uploads/prepare
openapi: 3.1.0
info:
  title: Ordinal API
  version: 1.0.0
  description: API to create and manage Ordinal workspaces, posts, profiles, and analytics
servers:
  - url: https://app.tryordinal.com/api/v1
    description: Production server
security:
  - bearerAuth: []
tags:
  - name: Analytics
    description: Social media analytics data
  - name: Approvals
    description: Post approval workflows
  - name: Comments
    description: >-
      Post comments for team collaboration. Supports @mentions using the format
      @[Display Name](userId).
  - name: Engagements
    description: Auto-engagements for posts (likes, comments, reposts)
  - name: Invites
    description: Workspace invitations for adding new users
  - name: Labels
    description: Labels for organizing posts
  - name: Instagram
    description: Instagram utilities for location search and tagging
  - name: LinkedIn
    description: LinkedIn utilities for profile lookups, tagging, and mentions
  - name: Posts
    description: Create and manage posts
  - name: Profiles
    description: List connected social profiles
  - name: Slack Boosts
    description: >-
      List connected Slack channels (webhooks), then create and manage slack
      boosts so teams get notified in Slack when posts publish. Requires Slack
      connected with marketing boost channels.
  - name: Subscribers
    description: Post subscribers for notifications
  - name: File Uploads
    description: >-
      Upload files from URLs for use in posts. Supports images (JPEG, PNG, GIF,
      WebP) up to 10 MB and videos (MP4, MOV) up to 350 MB.
  - name: Ideas
    description: >-
      Create and manage content ideas. Ideas are draft posts without scheduled
      dates that can be converted to calendar posts.
  - name: Inline Comments
    description: >-
      Text-anchored comments on specific post content. Read-only API for
      retrieving inline comments across channels.
  - name: Users
    description: Workspace users
  - name: Webhooks
    description: >-
      Create, list, get, update, and delete webhooks to receive real-time event
      notifications
  - name: Workspaces
    description: Workspace information
paths:
  /uploads/prepare:
    post:
      tags:
        - File Uploads
      summary: Prepare a local file upload
      description: >-
        Creates an upload job and returns signed credentials so you can POST a
        local file directly to the returned `uploadUrl`. After preparing, POST
        the file to `uploadUrl` as multipart form data with the returned
        `params`, `signature`, and `file` fields, then poll `GET /uploads/{id}`
        until status is `ready`.


        See [File uploads](/api/file-uploads#local-file-upload) for a full
        walkthrough and curl examples.


        **Supported file types:**

        - Images: JPEG, PNG, GIF, WebP

        - Videos: MP4, QuickTime (MOV)


        **File size limits:**

        - Images: 10 MB max

        - GIFs: 15 MB max

        - Videos: 350 MB max


        The returned credentials are short-lived. Upload the file before
        `expiresAt`.
      operationId: uploads-prepare
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - filename
                - mimetype
                - size
              properties:
                filename:
                  type: string
                  minLength: 1
                  description: Original filename, including extension.
                mimetype:
                  type: string
                  minLength: 1
                  description: MIME type of the file (e.g., image/jpeg, video/mp4).
                size:
                  type: integer
                  exclusiveMinimum: 0
                  description: File size in bytes.
              additionalProperties: false
            example:
              filename: product-photo.jpg
              mimetype: image/jpeg
              size: 245678
      responses:
        '200':
          description: Signed credentials for uploading the file
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UploadPrepared'
              example:
                id: 550e8400-e29b-41d4-a716-446655440000
                status: awaiting_upload
                uploadUrl: https://upload.example.com
                params: '{"auth":{...},"template_id":"..."}'
                signature: sha384:...
                expiresAt: '2026-02-04T11:30:00.000Z'
                createdAt: '2026-02-04T10:30:00.000Z'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
components:
  schemas:
    UploadPrepared:
      type: object
      description: >-
        Response when a local file upload is prepared. Use `uploadUrl`,
        `params`, and `signature` to POST the file. See [File
        uploads](/api/file-uploads#local-file-upload) for the full multipart
        upload example.
      properties:
        id:
          type: string
          format: uuid
          description: Upload job ID. Use this to poll GET /uploads/{id}.
        status:
          type: string
          enum:
            - awaiting_upload
          description: Initial status while Ordinal waits for the file POST.
        uploadUrl:
          type: string
          format: uri
          description: URL to POST the file to as multipart form data.
        params:
          type: string
          description: Signed upload params. Include verbatim as the `params` form field.
        signature:
          type: string
          description: >-
            Signature for the params. Include verbatim as the `signature` form
            field.
        expiresAt:
          type: string
          format: date-time
          description: Time after which the signed credentials are no longer valid.
        createdAt:
          type: string
          format: date-time
      required:
        - id
        - status
        - uploadUrl
        - params
        - signature
        - expiresAt
        - createdAt
    ValidationError:
      type: object
      properties:
        code:
          type: string
        message:
          type: string
        data:
          type: object
          properties:
            errors:
              type: object
              additionalProperties:
                type: array
                items:
                  type: string
    Error:
      type: object
      properties:
        code:
          type: string
        message:
          type: string
  responses:
    BadRequest:
      description: Bad Request - Invalid input parameters
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ValidationError'
          example:
            code: BAD_REQUEST
            message: Bad Request
            data:
              errors:
                publishAt:
                  - Invalid date format
                status:
                  - Invalid enum value
    Unauthorized:
      description: Unauthorized - Missing or invalid API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: UNAUTHORIZED
            message: Invalid or unauthorized API key
    RateLimited:
      description: Too Many Requests - Rate limit exceeded
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: TOO_MANY_REQUESTS
            message: >-
              Rate limit of 100 requests per 60s exceeded. Quota resets in 45
              seconds
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        API key authentication. Generate an API key from your workspace
        settings.

````