Skip to content →
Sign upOpen app

Interaction Best Practices

Linear users have high expectations for the quality and consistency of the experience inside Linear. We aim to extend this to agents, which should act in a predictable and natural manner.

Recommendations

Upon receiving the created webhook, your agent should respond immediately with a thought activity to acknowledge that the agent has started working. This lets the user know right away that their prompt has been received.

The first response must be sent within 10 seconds of receiving the created event, or the agent will be shown as unresponsive.

Follow-up activities after the first response can still be sent for up to 30 minutes before the session is considered stale. Note that this stale state is recoverable by sending another agent activity.

If your agent is delegated to work on an issue that is not in a started, completed, or canceled status type, move the issue to the first status in started when your agent begins work.

If your agent is working on implementation and no delegate is currently set, it should set itself as the delegate to make the agent's role in the issue more explicit.

When work is complete, emit an AgentActivity with type response; or if you require additional actions from the user, emit an AgentActivity with type elicitation or error. We will automatically create a comment under the comment thread as well.

Agent Activities

query AgentSession($agentSessionId: String!) {
  agentSession(id: $agentSessionId) {
    activities {
      edges {
        node {
          updatedAt
          content {
            ... on AgentActivityThoughtContent {
              body
            }
            ... on AgentActivityActionContent {
              action
              parameter
              result
            }
            ... on AgentActivityElicitationContent {
              body
            }
            ... on AgentActivityResponseContent {
              body
            }
            ... on AgentActivityErrorContent {
              body
            }
	        ... on AgentActivityPromptContent {
              body
            }
          }
        }
      }
    }
  }
}

// @linear/sdk@^53.0.0
const agentSessionActivities = await agentSession.activities();
agentSessionActivities.nodes.forEach(activity => {
	switch (activity.content.__typename) {
		// type narrowing
		case "AgentActivityThoughtContent":
			const { body } = activity.content;
			...
			break;
		case "AgentActivityActionContent":
			const { action, parameter, result } = activity.content;
			...
			break;
		case "AgentActivityElicitationContent":
			const { body } = activity.content;
			...
			break;
		case "AgentActivityResponseContent":
			const { body } = activity.content;
			...
			break;
		case "AgentActivityErrorContent":
			const { body } = activity.content;
			...
			break;
		case "AgentActivityPromptContent":
			const { body } = activity.content;
			...
			break;
		default:
			throw Error("Not reachable")
	}
})

Comments may not be reliable to read from, as they are editable and may have changed since your agent’s last run. Agent Activities are frozen-in-time snapshots of user input. To reconstruct the full conversation, list the Agent Activities associated with the Agent Session instead—see above for examples.

Additional Webhooks

In addition to the core AgentSession webhooks, there are additional webhooks that your agent can listen to in order to build a richer agent experience within Linear. In addition, you can utilize any of the existing GraphQL APIs.

Inbox Notifications Webhooks

Inbox Notification events are triggered when something directly involves your app user—like when an agent is unassigned from an issue or a user reacts to a comment from the agent.

Enable this category by selecting Inbox Notifications in your OAuth app config.

The received webhook payload will have the following shape:

{
  type: "AppUserNotification",
  action: NotificationType,
  createdAt: string,
  organizationId: string,
  oauthClientId: string,
  appUserId: string,
  notification: Notification,
}

Here are a few action types that could be useful while developing your agent:

issueMention
issueEmojiReaction
issueCommentMention
issueCommentReaction
issueAssignedToYou
issueUnassignedFromYou
issueNewComment
issueStatusChanged

Permission Change Webhooks

Permission Change events are triggered when your agent gains or loses access to a team.

Enable this category by selecting Permission changes in your OAuth app config. The webhook will be of type PermissionChange with action teamAccessChanged.

The received webhook payload will have the following shape when team access is granted or removed:

{
  type: "PermissionChange",
  action: "teamAccessChanged",
  createdAt: string,
  organizationId: string,
  oauthClientId: string,
  appUserId: string,
  canAccessAllPublicTeams: boolean,
  addedTeamIds: string[],
  removedTeamIds: string[],
  webhookTimestamp: number,
  webhookId: string
}
 

You’ll receive a separate webhook when revoking your OAuth app:

{
  type: "OAuthApp",
  action: "revoked",
  createdAt: string,
  organizationId: string,
  oauthClientId: string,
  webhookTimestamp: number,
  webhookId: string
}
 

Existing integrations

When to build an integration or agent

If your integration primarily reads data from Linear or performs actions that should be attributed to individual team members, an integration is the right choice.

Build an agent if you want your application to appear as a distinct workspace member with its own identity and actions within Linear.

Convert an existing integration

If you have an existing Linear integration it can be converted to use the new authentication and gain the new functionality.

The new actor=app actor type works quite differently at the core to our legacy actor=application approach. However, if you are using actor=application today to request a token that is only used to create issues or comments as an app, then it is backwards compatible – you can simply change this parameter.

actor=application allows for dual-purpose authentication tokens that can be used both as the authenticating user in some circumstances and as an "app" in others. If you currently are using a token like this, then to migrate you will need to ask users to authenticate twice: once for their personal access and secondarily for the app installation.

Feedback, requests, questions

Please join the #api-agents channel in our community Slack to provide feedback on this guide, request API's, and interact with other engineers developing agentic integrations.