Developer docs
Talking to an agent
One request sends a customer message to an agent. The agent may look things up with its tools before it answers.
Send a message
Request (HTTP)POST https://api.safecoin.online/v1/agents/{agentId}/messages| Field | Required | Meaning |
|---|---|---|
message | Yes | The customer’s text, 1 to 20,000 characters. |
conversationId | No | The id from an earlier reply, to continue that conversation. Leave it out to start a new one. |
agentId is the agent’s catalogue id: support_agent, sales_lead_agent or operations_agent. No other fields are accepted; unknown fields are rejected with invalid_request.
Continue a conversation (curl)curl https://api.safecoin.online/v1/agents/support_agent/messages \
-H "Authorization: Bearer $HAVEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"message": "It is order 1042", "conversationId": "7d0f6c1e-5b0a-4a7e-8f55-0c3a6a0b9d11"}'The response
| Field | Meaning |
|---|---|
conversationId | Send this back to continue the conversation. |
reply | The agent’s answer, as plain text. |
pendingApprovals | Actions the agent wants to take that wait for a person to approve: [{ approvalId, tool }]. See approvals. |
toolCalls | What the agent did while answering: [{ name, status }]. |
stopReason | Why the agent stopped, for example end_turn when it finished its answer. |
iterations | How many model calls the answer took (at most 8). |
usage | Your message allowance: used, cap, remaining, periodEnd and warning (set once you pass 80%). |
Each message you send uses one message from your plan, however many tools the agent uses to answer it. When you pass 80% of your allowance the response also carries the header X-Haven-Usage-Warning.
Stream the answer live
For a typing effect use the streaming route. It takes the same body and sends text/event-stream events as the agent works:
Streaming route (HTTP)POST https://api.safecoin.online/v1/agents/{agentId}/chat| Event | Data |
|---|---|
conversation | The conversation id, sent first. |
text | A piece of the reply. Join the pieces in order. |
tool | The agent used a tool: name, status and, for actions that wait for approval, approvalId. |
done | The finished result, with the same fields as the JSON response. |
error | error and message. The stream ends. |
Read the stream in Node.js (Node.js)const res = await fetch('https://api.safecoin.online/v1/agents/support_agent/chat', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.HAVEN_API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ message: 'Hello' }),
});
if (!res.ok) throw new Error((await res.json()).message);
const decoder = new TextDecoder();
for await (const chunk of res.body) {
process.stdout.write(decoder.decode(chunk, { stream: true })); // raw "event: …" / "data: …" lines
}The streaming route does not take an Idempotency-Key. If you need safe retries, use the JSON route.
When an agent cannot answer
Before any model is called, Haven checks that the agent is allowed to answer. If not, you get an error and no message is used:
| Status and code | Meaning and what to do |
|---|---|
402 agent_paused | The subscription is not active, ran out of messages, or is on hold. Read reason and message; renew or upgrade in the dashboard. |
409 agent_not_configured | Finish the agent’s setup in the dashboard first. |
404 agent_not_found | The agent id is wrong. |
409 conversation_busy | The conversation is still answering your previous message. Wait for it, then send the next one. |
409 conversation_full | The conversation has grown too long. Start a new one (leave out conversationId). |
502 model_unavailable | The AI service could not complete the request. Retry with the same Idempotency-Key. |
429 rate_limited | Wait retryAfterSeconds and retry. |
For 402 agent_paused the reason is one of not_subscribed, payment_pending, subscription_expired, subscription_canceled, credits_exhausted, billing_review, account_suspended, refunded or paused. The message explains it in plain words.
Good habits
- Set a generous timeout (two minutes). An answer that uses several tools can take a while.
- Send one message at a time per conversation.
- Never show raw error codes to your customers; show your own friendly text.
- Always send an
Idempotency-Keywhen your code may retry; see Retries and idempotency.