Skip to main content

Quickstart

A working call in a few minutes. You need an API key from Settings → Integrations → API access on the inbox you want to answer from.

1. Start a conversation​

curl -X POST https://app.trolleychat.ai/api/v1/conversations \
-H "Authorization: Bearer $TROLLEYCHAT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"user":{"id":"demo-user-1","name":"Demo"}}'

Save conversation.id from the response.

2. Send a message​

curl -X POST https://app.trolleychat.ai/api/v1/conversations/$CONVERSATION_ID/messages \
-H "Authorization: Bearer $TROLLEYCHAT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"content":"What is your shipping policy?"}'

reply.content is the assistant's answer, drawn from the inbox's knowledge base.

3. Read the conversation​

curl https://app.trolleychat.ai/api/v1/conversations/$CONVERSATION_ID/messages \
-H "Authorization: Bearer $TROLLEYCHAT_API_KEY"

A minimal server-side helper​

The key stays on your server. Your browser or app talks to your server; your server talks to TrolleyChat.

const BASE = 'https://app.trolleychat.ai'
const headers = {
Authorization: `Bearer ${process.env.TROLLEYCHAT_API_KEY}`,
'Content-Type': 'application/json',
}

export async function openConversation(user: { id: string; name?: string; metadata?: Record<string, string> }) {
const res = await fetch(`${BASE}/api/v1/conversations`, { method: 'POST', headers, body: JSON.stringify({ user }) })
if (!res.ok) throw await res.json()
return res.json() // { conversation, user, messages }
}

export async function sendMessage(conversationId: string, content: string, messageId: string) {
const res = await fetch(`${BASE}/api/v1/conversations/${conversationId}/messages`, {
method: 'POST',
headers,
body: JSON.stringify({ content, message_id: messageId }),
})
const body = await res.json()
if (!res.ok) {
if (body.error?.retryable) return sendMessage(conversationId, content, messageId) // same id: never answered twice
throw body
}
return body // { message, reply, mode }
}

export async function readSince(conversationId: string, since: string) {
const res = await fetch(`${BASE}/api/v1/conversations/${conversationId}/messages?since=${encodeURIComponent(since)}`, { headers })
if (!res.ok) throw await res.json()
return res.json() // { conversation, messages }
}

Generate messageId with crypto.randomUUID() when the user hits send, and reuse it on every retry of that message.

Handling a handoff​

When mode comes back as human, show the user that a person is picking up, then poll readSince with the timestamp of the last message you have. Stop polling when the user closes the panel; resume when they reopen it.