Overview
Threads are the core of conversation management in Inbox. This guide covers creating, retrieving, updating, and organizing threads.
Listing Threads
Retrieve threads with filtering and pagination:
const { data } = await client . get ( '/threads' , {
params: {
limit: 50 ,
inboxView: 'default' ,
accountLinkId: 'acc_abc123'
}
});
console . log ( `Found ${ data . threads . length } threads` );
data . threads . forEach ( thread => {
console . log ( `Thread ${ thread . id } with ${ thread . prospect . platformUsername } ` );
});
Response structure:
{
"threads" : [
{
"id" : "thread_abc123" ,
"platformId" : "12345-67890" ,
"accountLinkId" : "acc_abc" ,
"prospectId" : "prospect_xyz" ,
"done" : false ,
"assignedToMemberId" : null ,
"createdAt" : "2025-11-20T10:00:00.000Z" ,
"updatedAt" : "2025-11-23T15:30:00.000Z" ,
"lastMessageAt" : "2025-11-23T15:30:00.000Z" ,
"prospect" : {
"id" : "prospect_xyz" ,
"platformId" : "987654321" ,
"platformUsername" : "johndoe" ,
"name" : "John Doe"
}
}
],
"nextCursor" : {
"id" : "thread_xyz789" ,
"timestamp" : "2025-11-23T15:30:00.000Z"
}
}
Filtering Threads
The API supports sophisticated filtering to find exactly the threads you need.
By Inbox View
// Active conversations
const active = await client . get ( '/threads' , {
params: { inboxView: 'default' }
});
// Awaiting replies
const noReply = await client . get ( '/threads' , {
params: { inboxView: 'no-reply' }
});
// New message requests
const requests = await client . get ( '/threads' , {
params: { inboxView: 'requests' }
});
// Archived (done)
const archived = await client . get ( '/threads' , {
params: { inboxView: 'archived' }
});
By Account Link
Filter threads for a specific connected account:
const { data } = await client . get ( '/threads' , {
params: {
accountLinkId: 'acc_abc123'
}
});
Find threads with prospects that have specific tags:
// Prospects with ANY of these tags
const { data } = await client . get ( '/threads' , {
params: {
'filter[tagIds][0]' : 'tag_hot_lead' ,
'filter[tagIds][1]' : 'tag_customer'
}
});
// Prospects with NO tags
const { data : untagged } = await client . get ( '/threads' , {
params: {
'filter[noTags]' : true
}
});
By Status
// Threads with prospects in "qualified" status
const { data } = await client . get ( '/threads' , {
params: {
'filter[statusIds][0]' : 'status_qualified'
}
});
// Prospects with no status
const { data : noStatus } = await client . get ( '/threads' , {
params: {
'filter[noStatus]' : true
}
});
By Assignee
// Assigned to specific member
const { data } = await client . get ( '/threads' , {
params: {
'filter[assignedToMemberIds][0]' : 'member_abc123'
}
});
// Unassigned threads
const { data : unassigned } = await client . get ( '/threads' , {
params: {
'filter[noAssignee]' : true
}
});
Combined Filters
Combine multiple filters for precise results:
const { data } = await client . get ( '/threads' , {
params: {
inboxView: 'default' ,
accountLinkId: 'acc_abc' ,
'filter[statusIds][0]' : 'status_qualified' ,
'filter[assignedToMemberIds][0]' : 'member_xyz' ,
limit: 20
}
});
// Returns: Active threads from acc_abc, with qualified prospects, assigned to member_xyz
Use cursor-based pagination to retrieve all threads:
async function getAllThreads () {
const allThreads = [];
let cursor = undefined ;
do {
const { data } = await client . get ( '/threads' , {
params: {
cursor: cursor ? {
id: cursor . id ,
timestamp: cursor . timestamp
} : undefined ,
limit: 50
}
});
allThreads . push ( ... data . threads );
cursor = data . nextCursor ;
} while ( cursor );
return allThreads ;
}
Looking Up a Thread
Find an existing thread between an account and a prospect:
const { data } = await client . get ( '/threads/lookup' , {
params: {
prospectPlatformId: '987654321' , // X user ID
accountLinkId: 'acc_abc123'
}
});
if ( data . thread ) {
console . log ( 'Found thread:' , data . thread . id );
} else {
console . log ( 'No thread exists yet' );
}
You can also lookup by prospectId (Inbox ID) instead of prospectPlatformId.
Creating a Thread
Create a new conversation thread:
const { data } = await client . post ( '/threads' , {
prospectPlatformId: '987654321' ,
accountLinkId: 'acc_abc123'
});
console . log ( 'Created thread:' , data . thread . id );
When to create threads:
When starting a new conversation
After lookup returns no existing thread
For proactive outreach
Creating a thread doesn’t send a message. Use the messages endpoint to actually send a DM.
Getting Thread Details
Retrieve full details for a specific thread:
const { data } = await client . get ( `/threads/ ${ threadId } ` );
console . log ( 'Thread:' , data . thread );
console . log ( 'Prospect:' , data . thread . prospect );
console . log ( 'Last message:' , data . thread . lastMessageAt );
Updating Threads
Modify thread properties like assignment and done status:
// Assign thread to a team member
await client . patch ( `/threads/ ${ threadId } ` , {
assignedToMemberId: 'member_abc123'
});
// Mark thread as done (archives it)
await client . patch ( `/threads/ ${ threadId } ` , {
done: true
});
// Unassign and reopen
await client . patch ( `/threads/ ${ threadId } ` , {
assignedToMemberId: null ,
done: false
});
Deleting Threads
Permanently delete a thread and its messages:
await client . delete ( `/threads/ ${ threadId } ` );
console . log ( 'Thread deleted' );
Deletion is permanent and cannot be undone. Consider using done: true to archive instead.
Common Workflows
Get Threads Needing Follow-Up
// Threads where we sent last message but no reply
const { data } = await client . get ( '/threads' , {
params: {
inboxView: 'no-reply' ,
limit: 50
}
});
console . log ( ` ${ data . threads . length } threads need follow-up` );
Assign Incoming Requests Round-Robin
const members = [ 'member_1' , 'member_2' , 'member_3' ];
let currentIndex = 0 ;
async function assignNewRequest ( threadId ) {
const assigneeId = members [ currentIndex ];
await client . patch ( `/threads/ ${ threadId } ` , {
assignedToMemberId: assigneeId
});
currentIndex = ( currentIndex + 1 ) % members . length ;
console . log ( `Assigned to ${ assigneeId } ` );
}
Archive Completed Conversations
async function archiveThread ( threadId ) {
// Mark as done and unassign
await client . patch ( `/threads/ ${ threadId } ` , {
done: true ,
assignedToMemberId: null
});
console . log ( 'Thread archived' );
}
Find High-Value Prospects
const { data } = await client . get ( '/threads' , {
params: {
'filter[tagIds][0]' : 'tag_enterprise' ,
'filter[statusIds][0]' : 'status_qualified' ,
inboxView: 'default'
}
});
console . log ( ` ${ data . threads . length } enterprise qualified leads` );
Best Practices
Check for existing threads before creating
Always use /threads/lookup before creating to avoid duplicates: // Lookup first
const { data : lookup } = await client . get ( '/threads/lookup' , {
params: { prospectPlatformId , accountLinkId }
});
// Create only if needed
const thread = lookup . thread ?? (
await client . post ( '/threads' , {
prospectPlatformId ,
accountLinkId
})
). data . thread ;
Use appropriate page sizes
Default: 50 threads per page
For fast scans: 100 threads
For detailed processing: 20-30 threads
const { data } = await client . get ( '/threads' , {
params: { limit: 50 }
});
Leverage combined filters
Be specific with filters to reduce API calls and get exactly what you need.
Use done: true to archive threads unless you need permanent deletion. Archived threads can be restored.
Next Steps