Skip to main content

Documentation Index

Fetch the complete documentation index at: https://www.plain.com/docs/llms.txt

Use this file to discover all available pages before exploring further.

Using TypeScript? Check out our GraphQL SDK for a fully typed client.
Thread fields allow you to extend Plain’s thread data model. The thread fields which you want to support have to conform to a schema configured in SettingsThread fields. Thread fields can be nested and be either a boolean, text or a string enum. Thread fields can be required. When they are required, their value must be set in order for the thread to be marked as done. For interacting with thread fields via the API, every field has a key defined in its schema. Keys make it possible to quickly refer to a thread field without having to know its ID in the schema. For example if you have a field called “Product Area” the key you might choose for the key to be product_area.

Manage thread field schemas

Most teams configure thread field schemas in SettingsThread fields, but if you want to provision them programmatically you can do so via the API.

Get thread field schemas

Query
query getThreadFieldSchemas($first: Int = 50, $after: String) {
  threadFieldSchemas(first: $first, after: $after) {
    edges {
      node {
        id
        key
        label
        description
        type
        order
        isRequired
        enumValues
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
Variables
{
  "first": 50
}

Create a thread field schema

key must be unique within your workspace. type is one of STRING, BOOL, NUMBER, DATETIME, or ENUM (for enum types, populate enumValues). This operation requires the following permissions:
  • threadFieldSchema:create
Mutation
mutation createThreadFieldSchema($input: CreateThreadFieldSchemaInput!) {
  createThreadFieldSchema(input: $input) {
    threadFieldSchema {
      id
      key
      label
      type
      isRequired
      order
    }
    error {
      message
      type
      code
      fields {
        field
        message
        type
      }
    }
  }
}
Variables
{
  "input": {
    "key": "order_id",
    "label": "Order ID",
    "description": "The internal order ID this thread is about.",
    "type": "STRING",
    "enumValues": [],
    "order": 0,
    "isRequired": false,
    "isAiAutoFillEnabled": false
  }
}

Update a thread field schema

Field-level wrapper inputs apply — pass { "value": ... } for the fields you want to change. This operation requires the following permissions:
  • threadFieldSchema:edit
Mutation
mutation updateThreadFieldSchema($input: UpdateThreadFieldSchemaInput!) {
  updateThreadFieldSchema(input: $input) {
    threadFieldSchema {
      id
      label
      isRequired
    }
    error {
      message
      type
      code
      fields {
        field
        message
        type
      }
    }
  }
}
Variables
{
  "input": {
    "threadFieldSchemaId": "tfs_01HXXXXXXXXXXXXXXXXXXXXXXX",
    "label": { "value": "Order ID" },
    "isRequired": true
  }
}

Delete a thread field schema

Deleting a schema also removes any values stored against it on threads. This operation requires the following permissions:
  • threadFieldSchema:delete
Mutation
mutation deleteThreadFieldSchema($input: DeleteThreadFieldSchemaInput!) {
  deleteThreadFieldSchema(input: $input) {
    error {
      message
      type
      code
      fields {
        field
        message
        type
      }
    }
  }
}
Variables
{
  "input": {
    "threadFieldSchemaId": "tfs_01HXXXXXXXXXXXXXXXXXXXXXXX"
  }
}

Reorder thread field schemas

reorderThreadFieldSchemas updates the order of multiple schemas in a single call. You don’t need to include every schema — only the ones whose order is changing.
Mutation
mutation reorderThreadFieldSchemas($input: ReorderThreadFieldSchemasInput!) {
  reorderThreadFieldSchemas(input: $input) {
    threadFieldSchemas {
      id
      key
      order
    }
    error {
      message
      type
      code
      fields {
        field
        message
        type
      }
    }
  }
}
Variables
{
  "input": {
    "threadFieldSchemaOrders": [
      { "threadFieldSchemaId": "tfs_01HXXXXXXXXXXXXXXXXXXXXXXX", "order": 0 },
      { "threadFieldSchemaId": "tfs_01HYYYYYYYYYYYYYYYYYYYYYYY", "order": 1 }
    ]
  }
}

Manage thread field values

Upsert a thread field

To upsert a thread field you need an API key with the following permissions:
  • threadField:create
  • threadField:update
Mutation
mutation upsertThreadField($input: UpsertThreadFieldInput!) {
  upsertThreadField(input: $input) {
    result
    threadField {
      id
      key
      type
      threadId
      stringValue
      booleanValue
      isAiGenerated
      createdAt {
        iso8601
      }
      updatedAt {
        iso8601
      }
    }
    error {
      message
      type
      code
      fields {
        field
        message
        type
      }
    }
  }
}
Variables
{
  "input": {
    "identifier": {
      "threadId": "th_01HVNWFJS395XVPPBJNE6A8BHP",
      "key": "product_area"
    },
    "type": "STRING",
    "stringValue": "security"
  }
}

Delete a thread field

To delete a thread field you need an API key with the following permissions:
  • threadField:delete
Mutation
mutation deleteThreadField($input: DeleteThreadFieldInput!) {
  deleteThreadField(input: $input) {
    error {
      message
      type
      code
      fields {
        field
        message
        type
      }
    }
  }
}
Variables
{
  "input": {
    "identifier": {
      "threadId": "th_01HVNWFJS395XVPPBJNE6A8BHP",
      "key": "product_area"
    }
  }
}