Swat.io Developer DocumentationSwat.io Developer Documentation
Home
Getting Started
  • Overview
  • Core Resources
  • Posts
  • Drafts
  • Campaigns
  • Asset Library
  • Inbox
  • Insights
  • Overview
  • Tools
Home
Getting Started
  • Overview
  • Core Resources
  • Posts
  • Drafts
  • Campaigns
  • Asset Library
  • Inbox
  • Insights
  • Overview
  • Tools
  • Working with Drafts

Working with Drafts

MCP supports listing, creating, updating, and deleting drafts. Its attachment handling has the same omission and replacement rules described below. See the MCP tool reference.

Drafts are a way to manage ideas not yet ready for a post, collaborate with teammates, or stage content for reuse. They support titles, statuses, due dates, user assignment, and media attachments.

Available fields

A draft exposes the following fields:

FieldTypeDescription
idIDUnique identifier
titleStringOptional title (max 100 characters)
messageStringThe draft's text content
statusDraftStatusWorkflow status: none, in_progress, paused, done, archived
assignedUserUserRelation to the assigned user. Select sub-fields (e.g. { id first_name last_name }). The scalar assigned_user_id is only an input argument on draftCreate / draftUpdate, not a selectable field.
due_dateDateOptional due date used for sorting
workspace_idIDThe workspace the draft belongs to
attachments[Attachment]Media attachments associated with this draft
createdByUserRelation to the user who created the draft. Select sub-fields.
updated_atDateTimeISO 8601 last-modified timestamp

Create

Only workspace_id is required. All other fields are optional. Attachments can also be provided on create - the input format is the same as for draftUpdate ( see Handling attachments below), minus the " existing-by-id" mode.

mutation draftCreate {
  draftCreate(
    workspace_id: <WORKSPACE_ID>
    title: "Q3 campaign copy"
    message: "Here's the draft text for our next campaign."
    status: in_progress
    assigned_user_id: <USER_ID>
    due_date: "2025-06-01"
  ) {
    id
    title
    message
    status
    assignedUser {
      id
      first_name
      last_name
    }
    due_date
  }
}

Update

All fields are optional. Only the fields you provide will be changed.

mutation draftUpdate {
  draftUpdate(
    id: <DRAFT_ID>
    title: "Q3 campaign copy - revised"
    message: "Updated draft text."
    status: done
    assigned_user_id: <USER_ID>
    due_date: "2025-06-15"
  ) {
    id
    title
    message
    status
    assignedUser {
      id
      first_name
      last_name
    }
    due_date
    updated_at
  }
}

Draft statuses

The status field reflects the draft's position in your team's workflow. The supported values are:

StatusDescription
noneNo status set (default)
in_progressActively being worked on
pausedWork temporarily stopped
doneReady for review or publishing
archivedSoft-removed; no longer active

Handling attachments

Drafts support media attachments. The attachment handling for draftUpdate follows specific rules that differ from posts:

  • Passing null (or omitting the attachments field entirely) leaves existing attachments untouched.
  • Passing an empty array [] removes all attachments.
  • Passing a list is treated as authoritative: any existing attachment not included in the list will be deleted.

There are two modes for items in the list:

ModeRequired fieldsNotes
New attachmentcategory, source_uploadedAdds a new attachment
Existing attachmentid onlyKeeps it in place; category and source_uploaded are not accepted and will cause an error

Adding an attachment to a draft

mutation draftAddAttachment {
  draftUpdate(
    id: <DRAFT_ID>
    attachments: [
      {
        category: photo
        source_uploaded: "<PUBLIC_URL_TO_IMAGE>"
      }
    ]
  ) {
    id
    attachments {
      id
      source_uploaded
    }
  }
}

Keeping existing attachments while adding a new one

Fetch the current attachment IDs first, then pass them alongside the new item. Omitting an existing attachment will delete it.

mutation draftAddSecondAttachment {
  draftUpdate(
    id: <DRAFT_ID>
    attachments: [
      { id: <EXISTING_ATTACHMENT_ID> }   # kept as-is
      {
        category: photo
        source_uploaded: "<PUBLIC_URL_TO_NEW_IMAGE>"
      }
    ]
  ) {
    id
    attachments {
      id
      source_uploaded
    }
  }
}

Removing all attachments

mutation draftRemoveAttachments {
  draftUpdate(
    id: <DRAFT_ID>
    attachments: []
  ) {
    id
    attachments {
      id
    }
  }
}

Finding a user ID for assignment

The assigned_user_id field requires a user ID, which is not visible in the Swat.io UI. Use the me query to retrieve the ID of the currently authenticated user:

query whoAmI {
  me {
    id
    email
    first_name
    last_name
  }
}

For a full example including curl, see User ID in the API overview.

List

Returns up to 50 drafts per call, sorted by last-updated descending.

query draftList {
  draftList(workspace_id: <WORKSPACE_ID>) {
    drafts {
      id
      message
      updated_at
    }
    pagination {
      after
    }
  }
}

Filtering and sorting drafts

draftList accepts the following optional arguments in addition to workspace_id:

ArgumentTypeNotes
statusDraftStatusFilter by workflow status.
assigned_to_meBooleanOnly drafts assigned to the authenticated user.
date_fromDateOnly drafts with a due_date from this date on. Must be used together with date_to.
date_toDateOnly drafts with a due_date up to this date. Must be used together with date_from.
search_termStringFull-text search in the draft's title.
sortDraftSortEnumSort by updated_at (default) or due_date.
orderSortOrderEnumSort direction. Defaults to desc.

Paginating through drafts

Use the pagination.after token from the previous response to fetch the next page. Pass the same workspace_id each time.

query draftListNextPage {
  draftList(
    workspace_id: <WORKSPACE_ID>
    after: "<AFTER_TOKEN>"
  ) {
    drafts {
      id
      message
    }
    pagination {
      after
    }
  }
}

When pagination.after is null, you have reached the last page.

Delete

mutation draftDelete {
  draftDelete(id: <DRAFT_ID>)
}

Converting a draft into a post

Drafts have no direct "publish" mutation - the intended workflow is to read the draft content and then create a post from it using postCreate. The draft is not automatically deleted and can be reused.

# Step 1 - fetch the draft content
query getDraft {
  draftList(workspace_id: <WORKSPACE_ID>) {
    drafts {
      id
      message
    }
  }
}
# Step 2 - create a post using the draft's message
mutation postFromDraft {
  postCreate(
    post: {
      category: text
      channel_id: "<CHANNEL_ID>"
      publication_at: "2024-04-16T14:00:00+02:00"
      message: "<MESSAGE FROM DRAFT>"
      status: suggested
    }
  ) {
    id
    status
  }
}
# Step 3 - optionally delete the draft once the post is created
mutation draftCleanup {
  draftDelete(id: <DRAFT_ID>)
}