Authentication Issues
401 Unauthorized
Symptom: All requests return 401 status.
Common causes:
- Missing
Authorization header
- Typo in token (extra spaces, newlines)
- Expired or revoked token
- Missing
Bearer prefix
Solutions:
// Check your header format
const headers = {
'Authorization': `Bearer ${process.env.INBOX_API_TOKEN}`, // Note the space after Bearer
'Content-Type': 'application/json'
};
// Verify token is loaded
if (!process.env.INBOX_API_TOKEN) {
throw new Error('INBOX_API_TOKEN environment variable not set');
}
// Test with a simple request
const response = await fetch('https://inboxapp.com/api/v1/team', { headers });
console.log('Status:', response.status);
Verification steps:
- Print your token (first/last 4 chars only) to verify it’s loaded
- Try the token in cURL to isolate the issue
- Generate a new token from the dashboard
403 Forbidden
Symptom: Token works for some endpoints but not others.
Common causes:
- Accessing a resource from another team
- Feature not available on your plan
- Attempting an admin-only action
Solutions:
- Verify the resource belongs to your team
- Check your plan in the dashboard
- Use a token from an admin account
Resource Not Found (404)
Thread Not Found
Symptom: THREAD_NOT_FOUND error when accessing a thread.
Common causes:
- Using platform ID instead of Inbox ID
- Thread was deleted
- Typo in thread ID
Solution:
// Wrong: Using platform ID
const threadPlatformId = '12345-67890';
await client.get(`/threads/${threadPlatformId}`); // 404!
// Correct: Use Inbox ID
const threadInboxId = 'thread_abc123';
await client.get(`/threads/${threadInboxId}`); // Works
// Or use lookup with platform ID
const { data } = await client.get('/threads/lookup', {
params: {
prospectPlatformId: '987654321',
accountLinkId: 'acc_abc123'
}
});
Prospect Not Found
Symptom: PROSPECT_NOT_FOUND when sending a message or looking up.
Common causes:
- Prospect has never interacted with your team
- Wrong platform ID format
- Prospect was deleted
Solutions:
// Verify prospect exists before operations
const { data } = await client.get('/prospects/lookup', {
params: { platformId: '987654321' }
});
if (!data.prospect) {
console.log('Prospect not in system. They need to message you first,');
console.log('or you need to start a conversation via /threads endpoint.');
}
Prospects are auto-created when they message you or when you create a thread with them. You cannot create prospects directly.
Account Link Not Found
Symptom: ACCOUNT_LINK_NOT_FOUND when sending messages.
Common causes:
- Using platform ID instead of Inbox ID
- Account was disconnected
- Typo in account link ID
Solution:
// List your account links to get valid IDs
const { data } = await client.get('/account-links');
console.log('Valid account link IDs:');
data.accountLinks.forEach((a: any) => {
console.log(` ${a.platformUsername}: ${a.id}`);
});
Rate Limiting
429 Too Many Requests
Symptom: Requests start failing with 429 after sending many messages.
Solutions:
// Implement retry with backoff
async function sendWithRetry(threadId: string, text: string) {
let retries = 0;
const maxRetries = 5;
while (retries < maxRetries) {
try {
return await client.post(`/threads/${threadId}/messages`, { text });
} catch (error) {
if (axios.isAxiosError(error) && error.response?.status === 429) {
const retryAfter = parseInt(
error.response.headers['retry-after'] || '60',
10
);
console.log(`Rate limited. Waiting ${retryAfter}s...`);
await new Promise(r => setTimeout(r, retryAfter * 1000));
retries++;
} else {
throw error;
}
}
}
throw new Error('Max retries exceeded');
}
// Add delays between bulk operations
for (const message of messages) {
await sendMessage(message);
await new Promise(r => setTimeout(r, 6000)); // 6 seconds between sends
}
See the Rate Limits guide for detailed limits.
Missing Data
Symptom: Not all threads/messages are returned.
Cause: Not handling pagination properly.
Solution:
// Always paginate through all results
async function getAllThreads() {
const threads = [];
let cursor = undefined;
do {
const { data } = await client.get('/threads', {
params: {
limit: 100,
...(cursor && {
'cursor[id]': cursor.id,
'cursor[timestamp]': cursor.timestamp
})
}
});
threads.push(...data.threads);
cursor = data.nextCursor;
} while (cursor);
return threads;
}
Invalid Cursor
Symptom: INVALID_CURSOR error when paginating.
Common causes:
- Cursor was modified
- Cursor from a different query
- Cursor format is wrong
Solutions:
- Use cursors exactly as returned (don’t modify)
- Start fresh if cursor errors persist
- Check cursor encoding in URLs
// Correct cursor encoding
const { data } = await client.get('/threads', {
params: {
'cursor[id]': nextCursor.id,
'cursor[timestamp]': nextCursor.timestamp
}
});
Message Sending Issues
Message Not Delivered
Symptom: API returns success but message doesn’t appear on X.
Possible causes:
- Platform-level restrictions on your X account
- Recipient has blocked you
- Temporary platform issues
Diagnostic steps:
- Check the thread in the Inbox dashboard
- Verify the message appears there
- Try sending from the X app directly
- Contact support if the issue persists
Empty Message Error
Symptom: VALIDATION_ERROR when sending a message.
Solution:
function validateMessage(text: string) {
if (!text?.trim()) {
throw new Error('Message cannot be empty');
}
if (text.length > 10000) {
throw new Error('Message exceeds 10,000 character limit');
}
}
// Always validate before sending
validateMessage(messageText);
await client.post(`/threads/${threadId}/messages`, { text: messageText });
Filter Issues
Filters Not Working
Symptom: Filters return unexpected results.
Common causes:
- Wrong parameter format
- Incorrect filter combination
Solutions:
// Correct filter format (bracket notation)
const { data } = await client.get('/threads', {
params: {
'filter[tagIds][0]': 'tag_abc',
'filter[tagIds][1]': 'tag_xyz'
}
});
// Wrong: passing array directly
const { data } = await client.get('/threads', {
params: {
'filter[tagIds]': ['tag_abc', 'tag_xyz'] // Won't work!
}
});
See the Query Parameters guide for encoding rules.
Data Sync Issues
Stale Prospect Data
Symptom: Prospect profile data (followers, bio) seems outdated.
Explanation: Prospect profile data is synced periodically from the platform, not in real-time.
Solutions:
- Profile data updates on each interaction
- For critical decisions, fetch directly from X API
- Don’t rely on real-time accuracy for follower counts
Missing Threads
Symptom: Conversations visible in Inbox UI don’t appear in API.
Possible causes:
- Pagination not complete
- Filtering out results
- Different inbox views
Diagnostic steps:
// Check all inbox views
const views = ['default', 'no-reply', 'requests', 'archived'];
for (const view of views) {
const { data } = await client.get('/threads', {
params: { inboxView: view, limit: 1 }
});
console.log(`${view}: ${data.threads.length} threads`);
}
Quick Diagnostic Script
Run this to verify your setup:
async function diagnose() {
console.log('=== Inbox API Diagnostic ===\n');
// 1. Check authentication
console.log('1. Testing authentication...');
try {
const { data: team } = await client.get('/team');
console.log(` ✓ Connected to team: ${team.name}`);
} catch (error) {
console.log(` ✗ Auth failed: ${error.message}`);
return;
}
// 2. Check account links
console.log('\n2. Checking account links...');
const { data: accounts } = await client.get('/account-links');
console.log(` ✓ ${accounts.accountLinks.length} account(s) connected`);
accounts.accountLinks.forEach((a: any) => {
console.log(` - @${a.platformUsername} (${a.id})`);
});
// 3. Check threads
console.log('\n3. Checking threads...');
const { data: threads } = await client.get('/threads', {
params: { limit: 5 }
});
console.log(` ✓ ${threads.threads.length} recent threads`);
// 4. Check rate limit status
console.log('\n4. Rate limit status...');
// Make a request and check headers
const response = await client.get('/team');
const remaining = response.headers['x-ratelimit-remaining'];
const limit = response.headers['x-ratelimit-limit'];
console.log(` ✓ ${remaining}/${limit} requests remaining`);
console.log('\n=== Diagnostic Complete ===');
}
diagnose().catch(console.error);
Getting Help
If you’re still stuck:
- Check the error code in the Error Codes reference
- Review the API reference for the specific endpoint
- Contact support at helpcenter.inboxapp.com
- Email kevin@inboxapp.com for urgent issues
When contacting support, include:
- Error message and code
- Request endpoint and parameters
- Timestamp of the issue
- Your team ID (from
/team response)