API
Business hours schedules
- Added
businessHoursScheduleandbusinessHoursSchedules, which read the named schedules in your workspace. Both need thebusinessHours:readpermission. - Added
createBusinessHoursSchedule,updateBusinessHoursSchedule, anddeleteBusinessHoursSchedule. Overlapping and adjacent slots are merged when you write them. - SLA types expose
businessHoursSchedules, so you can read which schedules an SLA is tracked against. An empty list means it is tracked 24/7. businessHoursScheduleIdsonServiceLevelAgreementInputandUpdateServiceLevelAgreementInputnow takes IDs you can create, so you can point an SLA at a specific schedule.
- Added
lastTriggeredAtonWorkflow, andLAST_TRIGGERED_ATonWorkflowsSortField. Workflow.orderis the 1-based dispatch priority among published event workflows with a start step.moveWorkflowupdates it.
- Added
imageUrlonBroadcastReactionCount, so you can render a custom emoji.
DiscussionsFilter.isWorkflowTaskseparates the Sidekick tasks generated fromask_sidekickworkflow steps from the discussions that people join. Passfalsefor a human-facing list.
- Replace
businessHoursSlotswithbusinessHoursSchedules. - Replace
syncBusinessHoursSlotswithcreateBusinessHoursScheduleorupdateBusinessHoursSchedule. It errors when the workspace has more than one schedule. - Replace
useBusinessHoursOnlywithbusinessHoursScheduleswhen you read an SLA, and withbusinessHoursScheduleIdswhen you write one.
API
Slack
- Added
createThreadFromSlackMessage, so you can create a thread from a top-level message in a connected customer Slack channel. It is the trigger for API-only ingestion, and it works in every other ingestion mode too. - Added
API_ONLYtoSlackIngestionMode.
- Added
aiFeedback, so you can list the feedback your team has left on Ari replies and other Plain AI features. Filter byfeatures,sentiments, andcreatedAt. RequiresaiFeatureFeedback:read.
MachineUser.isAssignableToThreadsreports whether custom-agent pricing allows assigning that machine user to a thread.
API
Broadcasts
- Added
broadcastAudience,broadcastAudiences,createBroadcastAudience,updateBroadcastAudience, anddeleteBroadcastAudience, so you can save and reuse broadcast audiences. - Added
broadcastSendTargetRecipients, so you can see who a send target’sscope,filters,recipients, andexcludeRecipientsresolve to before you save or send. - Added
sendTestBroadcast, so you can post a draft to up to 10 named Slack channels without changing the broadcast’s status.
Reply as a user
replyToThreadacceptsimpersonation.asUser, so an API key can reply as a team member.impersonationtakes exactly one ofasCustomerorasUser.createApiKeyandupdateApiKeyacceptimpersonationAllowList, andApiKey.impersonationAllowListreturns it. It names the users, roles and custom roles a key may reply as.TimelineEntry.createdByreturns whose credentials wrote an entry, which is the machine user for a reply sent as a team member, whileactorstays the team member. It is null on entries created before this was recorded.
Workspace.isSSOEnabledandWorkspace.isDirectoryEnabledreport an active SSO connection and a configured directory, andUser.isManagedByDirectorymarks the users the directory manages.WorkflowsFilter.createdByUserIdsfilters workflows by creator, andsortByacceptsNAME,CREATED_ATandPUBLISHED_AT.
- Added
discussion.turn_stop_requested, sent when someone requests that an agent stop its current turn. The payload containsdiscussion,requestedBy, andrequestedAt.
API
Broadcasts
- Broadcasts expose sends, deliveries, reactions, reply threads,
SLACK_BLOCK_KITcontent, and link unfurling. scheduleBroadcast.scheduledAtis optional, so you can return a scheduled broadcast to draft.
Task.sourceLinkslists linked knowledge gaps.knowledgeGapsacceptsfilters, including status.moveWorkflowplaces a workflow after another, or first whenafterWorkflowIdis null. Read where it sits from lexicographicposition, and sortworkflowswithsortBy.EmailEntry.inlineAttachmentsandImportThreadMessageInput.emailMessageIdare available.Thread.broadcastandThreadsFilter.broadcastIdsrelate reply threads to a broadcast.changeThreadDiscussionStatusresolves and reopens a discussion.
- Replace
BroadcastSendTarget.channelsandBroadcastSendTargetInput.channelswithscope,filters,recipients, andexcludeRecipients. - Replace
ThreadDiscussionAgentStatus.NEEDS_INPUTwithTOOL_CALL_APPROVAL_PENDING. - Replace
isSuccessonThreadDiscussionToolCallEntryPayloadwithstatus(DiscussionToolCallStatus).serviceandopare optional. - Remove
DiscussionsFilter.hasAgentSession. Filter withagentTypesandagentMachineUserIds. - Replace
orderon workflow inputs withmoveWorkflow. Settingorderno longer affects ordering, andWorkflow.orderis deprecated in favor ofposition. - Replace
markThreadDiscussionAsResolvedwithchangeThreadDiscussionStatus, which moves a discussion betweenOPENandRESOLVED.
- Added
task.task_created,task.task_updated,task.task_status_transitioned, andtask.task_deleted. A status change fires bothtask.task_updatedandtask.task_status_transitioned. - A task raised by Plain’s AI agent for a knowledge gap has a
sourceLinksentry withsourceType: "knowledge_gap".
- Added
discussion.tool_call_approval_requestedanddiscussion.tool_call_approval_resolvedfor agent tool-call approval changes. - Added
agentStatusto discussions indiscussion.message_created.
API
GraphQL schema
- Added
createBroadcast,updateBroadcast,deleteBroadcast, andscheduleBroadcastmutations, plusbroadcast,broadcasts, andsearchBroadcastsqueries, so you can manage broadcasts programmatically.
- The Broadcasts guide now documents using the API, including the permissions your API key needs to create, update, and send broadcasts.
Added
workspaceFiles to messages in discussion.message_created.Webhook versions · JSON schemaAdded
discussion.discussion_created, sent when a discussion is started on a thread. Existing event payloads did not change.Webhook versions · JSON schemaAdded
thread.thread_locked, sent when a thread is locked. Existing event payloads did not change.Webhook versions · JSON schemaDiscussion
status is now OPEN or RESOLVED. Agent activity moved to agentStatus (UNKNOWN, IDLE, and related values). If you filter or switch on the old discussion status values (IDLE, IN_PROGRESS, APPROVAL_REQUESTED), update those clients.Added the discussion.message_created webhook event, sent when a message is posted in a discussion. Existing event payloads did not change.Discussions · Webhook versions · JSON schemaAPI
Added
isCustomAgent on MachineUser. true when the machine user is an agent the workspace built itself, rather than an ordinary API integration.Machine users- Added
thread.note_mention_createdwhen a note mentions a machine user (for example an agent). Payload includesthread,note, andmentions(an array ofmachineUser). - Added
attioandemail_domaintotenant.sourceonthread.tenant_updated.
API
Added
createTenant. It fails if a tenant already exists with the given externalId. Use upsertTenant when you want create-or-update. Requires tenant:create.Added
attio and email_domain to tenant.source on thread.tenant_updated.Webhook versions · JSON schemaAPI
- Added
threadsByExternalIdto list every thread with a givenexternalId, across customers.threadByExternalIdstill returns a single thread for one customer. - Added
knowledgeSourceCitationsByThreadfor the knowledge sources cited by AI replies on a thread.
API
Added
updateThreadExternalId. Pass externalId: null to clear it. Requires thread:edit.Updating threads- Added
WAITING_INDEFINITELYtostatusDetail.typeonthread(snoozed with no duration). The same value is available on the thread type in the API. componentUser.usermay be amachineUseras well as auserwhen a UI component references a machine user.
API
Added
importThread and importThreadMessages for backfilling historical threads without firing SLAs or autoresponders. Each externalId is idempotent (NOOP on replay). Requires thread:import.Importing threadsAdded
dateTime and user UI component types to custom timeline entries.Webhook versions · JSON schemaAPI
Added a paginated
discussions query with filters for user and discussion type.Fetch discussions- Added
thread.thread_tenant_updated, sent when a thread’s tenant changes. - Added
reactionChangeonthread.slack_message_updated.
API
Added
webhookDeliveryAttempts so you can inspect delivery attempts, including response status and body, without leaving the API.Delivery attemptsAPI
Added
createDiscussion, sendDiscussionMessage, and the single discussion query, so you can open a side-conversation on a thread and post into it programmatically.Create a discussion · Send a messageAPI
Added
importCustomers, importTenants, and importTenantFieldSchemas for bulk backfills from another system. Each is idempotent on externalId and returns added, updated, and skipped counts.Added the
workflowButton UI component type to custom timeline entries.Webhook versions · JSON schemaAdded
changeType on thread.slack_message_updated.Webhook versions · JSON schema- Added
dateValueonthreadField. - Added
DATEandCURRENCYtothreadField.type.
Added
updateNote for editing an existing note on a thread.Added numberValue on threadField and NUMBER to threadField.type.Notes · Webhook versions · JSON schemaAPI
Added
lockThread to freeze a thread so non-admin users cannot reply or make changes.API
Added
updateThreadAgentStatus to set a thread’s AI agent status to IN_PROGRESS, HANDED_OFF, or HANDLED.Building agentsAPI
Tasks are now available over the API:
createTask, updateTask, deleteTask, plus task, taskByRef, and a filterable tasks query.TasksAPI
Added
labelTypeByExternalId, so you can look up a label type by the ID it has in your own system.Label typesAPI
Added
deleteThread for permanently deleting a thread.Deleting threadsAPI
Added
searchKnowledgeSources to search the knowledge your agents draw on.Searching knowledgeAPI
Added
upsertTenantField, deleteTenantField, and deleteTenantFieldSchema, completing tenant field management over the API.Tenant fieldsAPI
Added the
tenantFieldSchemas query and upsertTenantFieldSchema mutation, including field visibility.Tenant fieldsAPI
Added
deleteTenant. Deleting a tenant unlinks it from all customers and removes its fields.Deleting tenantsAPI
Added the
knowledgeSources query and deleteKnowledgeSource mutation.Searching knowledge- Added
additionalAssigneesonthread. - Added
externalIdandisExcludedFromAionlabelType.

