Send your first message
This tutorial walks you through sending your first DM using the Inbox API. You’ll learn the core workflow: authenticate, find an account, locate or create a thread, and send a message.
Prerequisites
Set your API token as an environment variable:
export INBOX_API_TOKEN = "your_token_here"
Step 1: Verify authentication
Confirm your API token works by fetching your team information:
import axios from "axios" ;
const client = axios . create ({
baseURL: "https://inboxapp.com/api/v1" ,
headers: {
Authorization: `Bearer ${ process . env . INBOX_API_TOKEN } ` ,
"Content-Type" : "application/json" ,
},
});
const { data : team } = await client . get ( "/team" );
console . log ( "Connected to team:" , team . name );
Response:
{
"id" : "hzcai5t59nn9vsck3rbuepyg" ,
"name" : "Acme Corp" ,
"slug" : "acme-corp" ,
"createdAt" : "2024-01-15T10:30:00.000Z" ,
"updatedAt" : null ,
"currency" : "USD" ,
"allowSupportAccess" : false
}
Step 2: List your account links
Account links are X accounts connected to your team. You need one to send messages:
const { data : accountLinks } = await client . get ( "/account-links" );
console . log ( `Found ${ accountLinks . length } account(s)` );
const account = accountLinks [ 0 ];
console . log ( `Using account: @ ${ account . username } ` );
Response:
[
{
"id" : "df6jbw4h36qm5d9iu2sgn7kx" ,
"platform" : "twitter" ,
"platformId" : "1566123362161725440" ,
"name" : "Acme Corp" ,
"username" : "acmecorp" ,
"image" : "https://pbs.twimg.com/profile_images/..." ,
"createdAt" : "2024-06-01T12:00:00.000Z" ,
"status" : "active" ,
"syncedAt" : "2025-01-15T10:30:00.000Z"
}
]
Step 3: Find or create a thread
Option A: Lookup an existing thread
If you know the prospect’s X user ID:
const { data : thread } = await client . get ( "/threads/lookup" , {
params: {
externalPlatformId: "1876543210987654321" ,
accountLinkId: account . id ,
},
});
if ( thread ) {
console . log ( "Found existing thread:" , thread . id );
} else {
console . log ( "No thread exists yet" );
}
Option B: Create a new thread
const { data : thread } = await client . post ( "/threads" , {
externalPlatformId: "1876543210987654321" ,
accountLinkId: account . id ,
});
console . log ( "Created thread:" , thread . id );
Step 4: Send a message
Replying to contacts who have already messaged you works on all plans. Sending the first message to a new contact requires the Outbound Messages addon on a paid plan. See Working with messages for details.
const { data : message } = await client . post ( `/threads/ ${ thread . id } /messages` , {
content: "Hello! Thanks for reaching out." ,
});
console . log ( "Message sent:" , message . id );
Response:
{
"id" : "p8rvk2m5j0xn4wq7ybftcael" ,
"platform" : "twitter" ,
"platformId" : "1876543210987654322" ,
"threadId" : "l44e15irdq4db30i77cgphhx" ,
"teamId" : "hzcai5t59nn9vsck3rbuepyg" ,
"authorId" : "df6jbw4h36qm5d9iu2sgn7kx" ,
"userId" : "r3km7xj9wq5p2bvnhfdteoly" ,
"campaignId" : null ,
"content" : "Hello! Thanks for reaching out." ,
"origin" : "api" ,
"createdAt" : "2025-01-15T10:30:00.000Z" ,
"updatedAt" : null ,
"isEdited" : false ,
"entities" : null ,
"attachment" : null ,
"reactions" : [],
"replyData" : null ,
"forwardData" : null
}
Complete example
send-message.ts
send-message.js
cURL
import axios from "axios" ;
const client = axios . create ({
baseURL: "https://inboxapp.com/api/v1" ,
headers: {
Authorization: `Bearer ${ process . env . INBOX_API_TOKEN } ` ,
"Content-Type" : "application/json" ,
},
});
async function sendFirstMessage (
prospectPlatformId : string ,
messageContent : string ,
) {
// 1. Verify authentication
const { data : team } = await client . get ( "/team" );
console . log ( "Connected to:" , team . name );
// 2. Get account link
const { data : accountLinks } = await client . get ( "/account-links" );
const account = accountLinks [ 0 ];
console . log ( `Using account: @ ${ account . username } ` );
// 3. Lookup or create thread
let thread ;
const { data : existing } = await client . get ( "/threads/lookup" , {
params: {
externalPlatformId: prospectPlatformId ,
accountLinkId: account . id ,
},
});
if ( existing ) {
thread = existing ;
console . log ( "Found existing thread" );
} else {
const { data : created } = await client . post ( "/threads" , {
externalPlatformId: prospectPlatformId ,
accountLinkId: account . id ,
});
thread = created ;
console . log ( "Created new thread" );
}
// 4. Send message
const { data : message } = await client . post (
`/threads/ ${ thread . id } /messages` ,
{ content: messageContent },
);
console . log ( "Message sent:" , message . id );
return message ;
}
sendFirstMessage ( "1876543210987654321" , "Hello from the API!" ). catch (( error ) =>
console . error ( "Error:" , error . response ?. data ?? error . message ),
);
Quick send alternative
For one-off messages, quick send combines thread lookup/creation and sending in one request:
const { data } = await client . post ( "/threads/messages" , {
externalPlatformId: "1876543210987654321" ,
accountLinkId: account . id ,
content: "Hey, I saw your post and wanted to reach out!" ,
});
console . log ( "Message sent:" , data . message . id );
console . log ( "Thread:" , data . thread . id );
Response:
{
"message" : {
"id" : "p8rvk2m5j0xn4wq7ybftcael" ,
"platform" : "twitter" ,
"threadId" : "l44e15irdq4db30i77cgphhx" ,
"content" : "Hey, I saw your post and wanted to reach out!" ,
"origin" : "api" ,
"createdAt" : "2025-01-15T10:30:00.000Z"
},
"thread" : {
"id" : "l44e15irdq4db30i77cgphhx" ,
"platform" : "twitter" ,
"platformId" : "1566123362161725440:1876543210987654321"
}
}
Use quick send for simple scenarios. For more control over thread management,
use the standard create/lookup + send workflow.
Next steps
Core concepts Understand threads, prospects, and the data model
Managing threads Learn thread operations and filtering
Working with prospects Manage prospect data and context
Rate limits Understand API limits