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

# Publish or Schedule Draft

> Manage saved unpublished posts without choosing a publish date.

Saved drafts are available to all users. Normal publishing and scheduling rules apply when submitting.

Drafts stay separate from scheduled and published posts. Saving does not publish or use your posting allowance. Text, media, destinations, and platform settings can be unfinished.

Use the draft UUID from the save response. Read the draft's current `revision` before editing, deleting, or submitting, then send it as `expected_revision`. A `409` means the draft changed or was submitted; read it again before continuing.

Only the submit endpoint publishes or schedules. It runs the same account, plan, content, and platform checks as [Create Post](/api-reference/endpoint/create). If validation fails, the draft stays saved. After a successful submission, the draft read includes `submission` with the original jobs. Repeating the same submission revision and schedule returns those same jobs.

Use `profile_id` for a non-default connection profile. A draft uses one profile. Lists include only unpublished drafts in that profile.

See the [draft workflow](/home/drafts) for dashboard, API, MCP, and CLI examples.


## OpenAPI

````yaml POST /api/v1/drafts/{id}/submit
openapi: 3.0.3
info:
  title: Mallary API
  version: 1.6.0
  description: >
    Public API for multi-platform publishing, analytics, media upload, and
    webhooks.


    Authentication:

    - Use header `Authorization: Bearer {api_key}`.

    - API key identity is authoritative. Do not use `user_id` to identify a
    caller.


    Connection profiles:

    - Omit `profile_id` to use the authenticated user's default profile.

    - Send the profile's random public `profile_id` when you want to publish,
    list posts, read post analytics or audience counts, list platforms, update
    settings, or disconnect a platform for a non-default profile.

    - Use `GET /api/v1/profiles` to list profile IDs.

    - Per-platform account caps by plan: Free 1, Starter 4, Pro 10, Business 50.


    Rate limits (per user, per minute) depend on subscription plan:

    - plan_id 1: 75 req/min

    - plan_id 2: 150 req/min

    - plan_id 3: 750 req/min

    - plan_id 4: 1500 req/min
servers:
  - url: https://mallary.ai
    description: Production
security:
  - bearerAuth: []
externalDocs:
  description: Full product docs
  url: https://docs.mallary.ai/
paths:
  /api/v1/drafts/{id}/submit:
    post:
      tags:
        - Drafts
      summary: Publish or schedule a saved draft
      description: >-
        Requires an explicit publishing or scheduling action and its current
        revision. Uses the normal publishing checks and quotas. Omit
        scheduled_at to publish now. The saved draft and all jobs commit
        together. Repeating the exact revision and schedule returns the same
        jobs; a different revision or schedule conflicts. Validation failures
        leave the draft unpublished. Available to all users. Requires
        mallary.publish for OAuth.
      operationId: submitDraft
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: profile_id
          in: query
          required: false
          schema:
            $ref: '#/components/schemas/ProfileId'
          description: >-
            Omit to use the default profile on lists. On reads, deletes and
            submissions, optionally verify the draft belongs to this profile.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SubmitDraftRequest'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreatePostResponse'
        '400':
          description: >-
            Invalid fields or publishing validation failed. The draft stays
            saved.
        '401':
          description: Authentication required
        '403':
          description: >-
            Required OAuth scope missing, or submission blocked by normal
            publishing or scheduling rules. Draft management is available to all
            users.
        '404':
          description: Draft or profile not found for this user
        '409':
          description: >-
            Draft changed or was submitted. Read it again before editing,
            deleting or submitting.
components:
  schemas:
    ProfileId:
      type: string
      pattern: ^[A-Za-z0-9]{6,32}$
      example: AbC123xYz90
      description: Random public connection profile ID returned by `GET /api/v1/profiles`.
    SubmitDraftRequest:
      type: object
      additionalProperties: false
      required:
        - expected_revision
      properties:
        expected_revision:
          type: integer
          minimum: 1
          description: Current revision from a draft read or save.
        scheduled_at:
          type: string
          minLength: 1
          maxLength: 80
          description: >-
            Omit to publish now. Absolute time or local time paired with
            scheduled_timezone.
        scheduled_timezone:
          type: string
          minLength: 1
          maxLength: 100
          description: >-
            IANA time zone for a local scheduled_at; paid scheduling rules
            apply.
    CreatePostResponse:
      type: object
      properties:
        status:
          type: string
          enum:
            - queued
        batch_id:
          type: string
        profile_id:
          type: string
          pattern: ^[A-Za-z0-9]{6,32}$
          nullable: true
        jobs:
          type: array
          items:
            type: object
            properties:
              platform:
                $ref: '#/components/schemas/Platform'
              jobId:
                type: string
              platform_post_id:
                type: string
                nullable: true
                description: >-
                  Platform-returned post ID. `null` until the queued job
                  publishes successfully.
              platform_post_url:
                type: string
                nullable: true
                description: >-
                  Public platform post URL when available. `null` until the
                  queued job publishes successfully or when the platform does
                  not expose a URL.
        warnings:
          type: array
          description: >-
            Non-blocking warnings about provider behavior. A queued post may
            still publish.
          items:
            type: object
            properties:
              platform:
                $ref: '#/components/schemas/Platform'
              code:
                type: string
              severity:
                type: string
                enum:
                  - warning
              message:
                type: string
    Platform:
      type: string
      description: Supported publishing platform identifier.
      enum:
        - twitter
        - x
        - facebook
        - instagram
        - linkedin
        - youtube
        - tiktok
        - pinterest
        - reddit
        - threads
        - bluesky
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'Use `Authorization: Bearer {api_key}`'

````

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