Skip to main content

Send Your First Message

This tutorial walks you through sending your first DM using the Inbox Enterprise API. You’ll learn the core workflow: authenticate, find an account, locate or create a thread, and send a message.
Before starting, make sure you have an API token. See the Authentication guide to get one.

Prerequisites

npm install axios
# or use fetch (built-in to Node.js 18+)
Set your API token as an environment variable:
export INBOX_API_TOKEN="your_token_here"

Step 1: Verify Authentication

First, 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'
  }
});

async function verifyAuth() {
  try {
    const { data: team } = await client.get('/team');
    console.log('✓ Connected to team:', team.name);
    return team;
  } catch (error) {
    console.error('✗ Authentication failed:', error.message);
    throw error;
  }
}

await verifyAuth();
Expected output:
✓ Connected to team: Acme Corp
Account links represent X accounts connected to your team. You need one to send messages:
async function getAccountLinks() {
  const { data } = await client.get('/account-links');
  console.log(`Found ${data.accountLinks.length} account(s)`);

  const account = data.accountLinks[0];
  console.log(`Using account: @${account.platformUsername}`);

  return account;
}

const account = await getAccountLinks();
Response:
{
  "accountLinks": [
    {
      "id": "acc_abc123",
      "platformId": "123456789",
      "platformUsername": "acmecorp",
      "platform": "x"
    }
  ]
}

Step 3: Find or Create a Thread

Option A: Lookup an Existing Thread

If you know the X user’s platform ID or username:
async function lookupThread(prospectPlatformId: string, accountLinkId: string) {
  const { data } = await client.get('/threads/lookup', {
    params: {
      prospectPlatformId,
      accountLinkId
    }
  });

  if (data.thread) {
    console.log('✓ Found existing thread:', data.thread.id);
    return data.thread;
  }

  console.log('No thread found, will create one');
  return null;
}

const thread = await lookupThread('987654321', account.id);

Option B: Create a New Thread

async function createThread(prospectPlatformId: string, accountLinkId: string) {
  const { data } = await client.post('/threads', {
    prospectPlatformId,
    accountLinkId
  });

  console.log('✓ Created thread:', data.thread.id);
  return data.thread;
}

const newThread = await createThread('987654321', account.id);

Step 4: Send a Message

Now send a message in the thread:
async function sendMessage(threadId: string, text: string) {
  const { data } = await client.post(`/threads/${threadId}/messages`, {
    text
  });

  console.log('✓ Message sent:', data.message.id);
  return data.message;
}

await sendMessage(thread.id, 'Hello! Thanks for reaching out.');
Response:
{
  "message": {
    "id": "msg_xyz789",
    "threadId": "thread_abc123",
    "text": "Hello! Thanks for reaching out.",
    "createdAt": "2025-11-23T10:30:00.000Z",
    "direction": "outbound"
  }
}

Complete Example

Here’s the full workflow in one script:
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, messageText: string) {
  // 1. Verify authentication
  const { data: team } = await client.get('/team');
  console.log('✓ Connected to:', team.name);

  // 2. Get account link
  const { data: accountsData } = await client.get('/account-links');
  const account = accountsData.accountLinks[0];
  console.log(`✓ Using account: @${account.platformUsername}`);

  // 3. Lookup or create thread
  let thread;
  const { data: lookupData } = await client.get('/threads/lookup', {
    params: {
      prospectPlatformId,
      accountLinkId: account.id
    }
  });

  if (lookupData.thread) {
    thread = lookupData.thread;
    console.log('✓ Found existing thread');
  } else {
    const { data: createData } = await client.post('/threads', {
      prospectPlatformId,
      accountLinkId: account.id
    });
    thread = createData.thread;
    console.log('✓ Created new thread');
  }

  // 4. Send message
  const { data: messageData } = await client.post(
    `/threads/${thread.id}/messages`,
    { text: messageText }
  );

  console.log('✓ Message sent successfully!');
  return messageData.message;
}

// Usage
sendFirstMessage('987654321', 'Hello from the API!')
  .then(message => console.log('Message ID:', message.id))
  .catch(error => console.error('Error:', error.message));

Quick Send Alternative

For one-off messages, use the quick send endpoint that combines thread lookup/creation and sending:
async function quickSend(prospectPlatformId: string, text: string, accountLinkId: string) {
  const { data } = await client.post('/threads/messages', {
    prospectPlatformId,
    accountLinkId,
    text
  });

  console.log('✓ Message sent via quick send');
  return data;
}

await quickSend('987654321', 'Quick message!', account.id);
Use quick send for simple scenarios. For more control over thread management, use the standard create/lookup + send workflow.

Common Issues

”Prospect not found”

The prospect must exist in your team’s database first. They’re usually auto-created when they message you, or you can create them by starting a conversation. Make sure you’re using an account link ID from the /account-links endpoint, not a platform ID.

Rate limiting

If you’re sending many messages, add delays between requests to avoid hitting rate limits:
await new Promise(resolve => setTimeout(resolve, 1000)); // Wait 1 second

Next Steps