Build anything on top of Janore.
Slack bot. Mobile app. Custom CRM. Voice IVR. Discord bot. If it can speak HTTP, it can speak Janore.
Overview
The REST API is the universal back door — same engine as the embed widget and the messaging channels, exposed as a clean Bearer-auth JSON API. Use it when there is no off-the-shelf channel for your use case, or when you want full control over the UI.
Prerequisites
- An assistant created in the dashboard.
- A server (or serverless function) where you can store an API key safely. Never embed it in client-side code.
Step-by-step setup
Generate an API key
Open the dashboard and click Generate new API key. You'll see the full key once — copy it now and store it in your secret manager. It looks like: Dashboard → Channels → REST API.
sk_live_a1b2c3d4e5f6...
Treat it as a password. Server-side only — never expose it in client code.
Send your first message
curl -X POST https://janore.com/api/v1/chat \
-H "Authorization: Bearer {API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"session_id": "user-123",
"message": "Bonjour, comment ça marche ?",
"language": "fr"
}'
session_id is any stable string per user (a uuid, a phone number, an internal user id). Janore groups messages with the same session into one conversation. language is optional — if omitted, Janore auto-detects.
Read the response
{
"reply": "Bonjour ! …",
"suggestedActions": [
{ "label": "Voir les tarifs", "type": "link", "payload": "/pricing" }
],
"conversationId": "uuid",
"messageId": "uuid"
}
suggestedActions are optional CTAs — render them as buttons in your UI if you want. conversationId stays stable across the session; use it to fetch history.
Endpoints to register
Three endpoints cover 95% of use cases:
POST /api/v1/chat— Send a message and get a reply.GET /api/v1/conversations/:id— Fetch the full conversation history.POST /api/v1/conversations/:id/escalate— Manually escalate a conversation to a human.
Code samples
Node.js
const res = await fetch('https://janore.com/api/v1/chat', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.JANORE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
session_id: 'user-123',
message: 'Hello',
language: 'en',
}),
});
const data = await res.json();
console.log(data.reply);
Python
import os, requests
r = requests.post(
"https://janore.com/api/v1/chat",
headers={"Authorization": f"Bearer {os.environ['JANORE_API_KEY']}"},
json={"session_id": "user-123", "message": "Hello", "language": "en"},
)
print(r.json()["reply"])
PHP
<?php
$ch = curl_init('https://janore.com/api/v1/chat');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('JANORE_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'session_id' => 'user-123',
'message' => 'Hello',
'language' => 'en',
]),
]);
$res = json_decode(curl_exec($ch), true);
echo $res['reply'];
Test it
Run the curl call above against your live key. You should see a reply in the language matching the message. If you don't, the most common issue is a missing Authorization header.
Limits
- 60 requests/minute per API key by default. Higher tiers raise the limit.
- We add X-RateLimit-Remaining and Retry-After headers so you can back off gracefully.
Security & RGPD
Bearer token in the Authorization header, TLS 1.3 only. Rotate keys from the dashboard at any time — old keys revoke instantly. Each key is scoped to a single assistant.
Common errors
401 Unauthorized— missing or invalid API key. Check the Authorization header.422 Unprocessable Entity— payload validation failed. The body explains which field is wrong.429 Too Many Requests— rate limit hit. Wait the seconds in Retry-After.500 Internal Server Error— broke on our side. Retries are safe; we de-duplicate on session_id + message.