GraphQL
- Introduction
- Authentication
- Schema
- Customers
- Companies
- Tenants
- Threads
- Tiers
- Events
- Labels
- Messaging
- Pagination
- Error handling
- Error codes
- API Explorer
- Typescript SDK
Reference
- Customer cards
- Webhooks
- Request signing
- mTLS
- UI Components
- Attachments
Create threads
Creating a thread is useful in scenarios where you want to programmatically start a support interaction.
You can do this in many different scenarios but the most common use-cases are when a contact form is submitted or when you want to provide proactive support off the back of some event or error happening in your product.
A thread is created with an initial ‘message’ composed out of UI components. You have full control over the structure and appearance of the message in Plain.
To create a thread you need a customerId
. You can get a customer id by creating the customer in Plain first.
Since the Typescript SDK expands a lot of fields you will need an API key with the following permissions:
label:create
label:read
labelType:read
machineUser:read
customer:read
user:read
thread:create
thread:edit
thread:read
threadField:create
threadField:update
threadField:read
import { PlainClient, ThreadFieldSchemaType } from '@team-plain/typescript-sdk';
const client = new PlainClient({ apiKey: 'plainApiKey_xxx' });
const res = await client.createThread({
title: 'Bug Report',
customerIdentifier: {
// You can use the email:
emailAddress: 'jane@acme.com',
// ...or if you set external id on customers:
// externalId: '',
// ...or you can use the customer's id in Plain:
// customerId: 'c_123'
},
components: [
{
componentText: {
text: "The login button is not working, it doesn't do anything.",
},
},
],
// Label types are created in settings where you can also copy
// their ID.
labelTypeIds: ['lt_01HB924PME9C0YWKW1N4AK3BZA'],
// Thread fields are created in settings where you can also copy
// their key.
threadFields: [
{
key: 'my_string_field',
type: ThreadFieldSchemaType.String,
stringValue: 'any value',
},
],
// You can also set other thread field types like boolean or enum.
// threadFields: [{
// key: 'my_enum_field',
// type: ThreadFieldSchemaType.Enum,
// stringValue: 'any specified value',
// }]
//
// threadFields: [{
// key: 'my_bool_field',
// type: ThreadFieldSchemaType.Bool,
// booleanValue: true,
// }],
});
if (res.error) {
console.error(res.error);
} else {
// The full thread is returned as res.data
console.log(`Thread created with id=${res.data.id}`);
}
Where result.data
is:
{
"__typename": "Thread",
"id": "th_01HB924RWAW8H3Q8KZDFWYBJHZ",
"externalId": null,
"customer": {
"id": "c_01H14DFQ4PDYBH398J1E99TWSS"
},
"status": "TODO",
"statusChangedAt": {
"__typename": "DateTime",
"iso8601": "2023-09-26T15:36:23.690Z",
"unixTimestamp": "1695742583690"
},
"title": "Bug Report",
"previewText": "The login button is not working, it doesn't do anything.",
"priority": 2,
"labels": [
{
"__typename": "Label",
"id": "l_01HBZMPM4FWANWKB25NWP8Q1FS",
"labelType": {
"__typename": "LabelType",
"id": "lt_01HB924PME9C0YWKW1N4AK3BZA",
"name": "Bug report",
"icon": "bug",
"isArchived": false,
"archivedAt": null,
"archivedBy": null,
"createdAt": {
"__typename": "DateTime",
"iso8601": "2023-09-26T15:36:21.390Z",
"unixTimestamp": "1695742581390"
},
"createdBy": {
"__typename": "SystemActor",
"systemId": "job"
},
"updatedAt": {
"__typename": "DateTime",
"iso8601": "2023-09-26T15:36:21.390Z",
"unixTimestamp": "1695742581390"
},
"updatedBy": {
"__typename": "SystemActor",
"systemId": "job"
}
},
"createdAt": {
"__typename": "DateTime",
"iso8601": "2023-10-05T10:04:00.527Z",
"unixTimestamp": "1696500240527"
},
"createdBy": {
"__typename": "UserActor",
"userId": "u_01FSVKMHFDHJ3H5XFM20EMCBQN"
},
"updatedAt": {
"__typename": "DateTime",
"iso8601": "2023-10-05T10:04:00.527Z",
"unixTimestamp": "1696500240527"
},
"updatedBy": {
"__typename": "UserActor",
"userId": "u_01FSVKMHFDHJ3H5XFM20EMCBQN"
}
}
],
"assignedAt": null,
"assignedTo": null,
"createdAt": {
"__typename": "DateTime",
"iso8601": "2023-09-26T15:36:23.690Z",
"unixTimestamp": "1695742583690"
},
"createdBy": {
"__typename": "MachineUserActor",
"machineUserId": "mu_01HBZM0TZAKAZPJ47NX7X7XMDY"
},
"updatedAt": {
"__typename": "DateTime",
"iso8601": "2023-10-05T10:10:04.785Z",
"unixTimestamp": "1696500604785"
},
"updatedBy": {
"__typename": "MachineUserActor",
"machineUserId": "mu_01HBZM0TZAKAZPJ47NX7X7XMDY"
}
}
Since the Typescript SDK expands a lot of fields you will need an API key with the following permissions:
label:create
label:read
labelType:read
machineUser:read
customer:read
user:read
thread:create
thread:edit
thread:read
threadField:create
threadField:update
threadField:read
import { PlainClient, ThreadFieldSchemaType } from '@team-plain/typescript-sdk';
const client = new PlainClient({ apiKey: 'plainApiKey_xxx' });
const res = await client.createThread({
title: 'Bug Report',
customerIdentifier: {
// You can use the email:
emailAddress: 'jane@acme.com',
// ...or if you set external id on customers:
// externalId: '',
// ...or you can use the customer's id in Plain:
// customerId: 'c_123'
},
components: [
{
componentText: {
text: "The login button is not working, it doesn't do anything.",
},
},
],
// Label types are created in settings where you can also copy
// their ID.
labelTypeIds: ['lt_01HB924PME9C0YWKW1N4AK3BZA'],
// Thread fields are created in settings where you can also copy
// their key.
threadFields: [
{
key: 'my_string_field',
type: ThreadFieldSchemaType.String,
stringValue: 'any value',
},
],
// You can also set other thread field types like boolean or enum.
// threadFields: [{
// key: 'my_enum_field',
// type: ThreadFieldSchemaType.Enum,
// stringValue: 'any specified value',
// }]
//
// threadFields: [{
// key: 'my_bool_field',
// type: ThreadFieldSchemaType.Bool,
// booleanValue: true,
// }],
});
if (res.error) {
console.error(res.error);
} else {
// The full thread is returned as res.data
console.log(`Thread created with id=${res.data.id}`);
}
Where result.data
is:
{
"__typename": "Thread",
"id": "th_01HB924RWAW8H3Q8KZDFWYBJHZ",
"externalId": null,
"customer": {
"id": "c_01H14DFQ4PDYBH398J1E99TWSS"
},
"status": "TODO",
"statusChangedAt": {
"__typename": "DateTime",
"iso8601": "2023-09-26T15:36:23.690Z",
"unixTimestamp": "1695742583690"
},
"title": "Bug Report",
"previewText": "The login button is not working, it doesn't do anything.",
"priority": 2,
"labels": [
{
"__typename": "Label",
"id": "l_01HBZMPM4FWANWKB25NWP8Q1FS",
"labelType": {
"__typename": "LabelType",
"id": "lt_01HB924PME9C0YWKW1N4AK3BZA",
"name": "Bug report",
"icon": "bug",
"isArchived": false,
"archivedAt": null,
"archivedBy": null,
"createdAt": {
"__typename": "DateTime",
"iso8601": "2023-09-26T15:36:21.390Z",
"unixTimestamp": "1695742581390"
},
"createdBy": {
"__typename": "SystemActor",
"systemId": "job"
},
"updatedAt": {
"__typename": "DateTime",
"iso8601": "2023-09-26T15:36:21.390Z",
"unixTimestamp": "1695742581390"
},
"updatedBy": {
"__typename": "SystemActor",
"systemId": "job"
}
},
"createdAt": {
"__typename": "DateTime",
"iso8601": "2023-10-05T10:04:00.527Z",
"unixTimestamp": "1696500240527"
},
"createdBy": {
"__typename": "UserActor",
"userId": "u_01FSVKMHFDHJ3H5XFM20EMCBQN"
},
"updatedAt": {
"__typename": "DateTime",
"iso8601": "2023-10-05T10:04:00.527Z",
"unixTimestamp": "1696500240527"
},
"updatedBy": {
"__typename": "UserActor",
"userId": "u_01FSVKMHFDHJ3H5XFM20EMCBQN"
}
}
],
"assignedAt": null,
"assignedTo": null,
"createdAt": {
"__typename": "DateTime",
"iso8601": "2023-09-26T15:36:23.690Z",
"unixTimestamp": "1695742583690"
},
"createdBy": {
"__typename": "MachineUserActor",
"machineUserId": "mu_01HBZM0TZAKAZPJ47NX7X7XMDY"
},
"updatedAt": {
"__typename": "DateTime",
"iso8601": "2023-10-05T10:10:04.785Z",
"unixTimestamp": "1696500604785"
},
"updatedBy": {
"__typename": "MachineUserActor",
"machineUserId": "mu_01HBZM0TZAKAZPJ47NX7X7XMDY"
}
}
To create a thread, you need an API key with the following permissions:
thread:create
thread:read
mutation createThread($input: CreateThreadInput!) {
createThread(input: $input) {
thread {
id
externalId
customer {
id
}
status
statusChangedAt {
iso8601
unixTimestamp
}
title
previewText
priority
threadFields {
id
key
type
stringValue
booleanValue
}
}
error {
message
type
code
fields {
field
message
type
}
}
}
}
{
"input": {
"title": "Bug Report",
"customerIdentifier": {
"customerId": "c_01H14DFQ4PDYBH398J1E99TWSS"
},
"components": [
{
"componentText": {
"text": "The login button is not working, it doesn't do anything."
}
}
],
"labelTypeIds": ["lt_01HB924PME9C0YWKW1N4AK3BZA"],
"threadFields": [
{
"key": "my_string_field",
"type": "STRING",
"stringValue": "any value"
}
]
// You can also set other thread field types like boolean or enum.
// "threadFields": [{
// "key": "my_enum_field",
// "type": "ENUM",
// "stringValue": "any specified value",
// }],
//
// "threadFields": [{
// "key": "my_bool_field",
// "type": "BOOL",
// "booleanValue": true,
// }],
}
}
Was this page helpful?