Ellie Developer Docs
Everything you need to integrate Ellie into your dispensary website. From simple widget embeds to full API access.
Overview
Ellie provides two main integration methods:
Widget Embed
Drop a single script tag on your site. Ellie handles the rest — UI, conversations, and lead capture.
REST API
Build your own chat UI or integrate Ellie into your existing app with our JSON API.
Base URL: https://budbot-inky.vercel.app
Authentication
All API requests require an API key. You can create and manage keys from your Dashboard.
Key Format
ek_live_*Production key — enforces domain restrictionsek_test_*Test key — bypasses domain validation, doesn't count toward quotaUsing Your Key
For the widget, pass it as the data-key attribute. For the REST API, include it as a Bearer token:
Authorization: Bearer ek_live_a1b2c3d4e5f6...Widget Embed
The fastest way to add Ellie to your site. Just paste this script tag before your closing </body> tag:
<script
src="https://ellie.budbot.ai/widget.js"
data-key="YOUR_API_KEY"
></script>Customization Options
Use data attributes to customize the widget:
| Attribute | Type | Description |
|---|---|---|
data-key | string | Your API key (required) |
data-color | hex string | Primary widget color (default: #7b8cde) |
data-position | "left" | "right" | Widget position on page (default: right) |
data-greeting | string | Custom welcome message |
data-logo | URL | Your dispensary logo URL |
data-name | string | Custom assistant name (default: Ellie) |
Full Example
<script
src="https://ellie.budbot.ai/widget.js"
data-key="YOUR_API_KEY"
data-color="#7b8cde"
data-position="right"
data-greeting="Hey! I'm Ellie, your AI budtender 🌿"
></script>Chat API
Use the Chat API to build your own interface or integrate Ellie into an existing app.
/api/chatSend a message to Ellie and receive an AI-generated response.
Request
const response = await fetch("https://budbot-inky.vercel.app/api/chat", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_KEY"
},
body: JSON.stringify({
messages: [
{
role: "user",
content: "What's a good indica for sleep?"
}
],
sessionId: "optional-session-id"
})
});
const data = await response.json();
console.log(data.reply);Response
{
"reply": "For sleep, I'd recommend Granddaddy Purple — it's a classic indica known for its deeply relaxing effects. The myrcene and linalool terpenes give it sedative properties that many people find perfect for bedtime. Another great option is Northern Lights, which has a more mellow, dreamy effect. Would you like to know more about either of these?",
"sessionId": "abc123-def456-ghi789",
"usage": {
"tokensUsed": 187
}
}Parameters
| Field | Type | Required | Description |
|---|---|---|---|
messages | array | Yes | Array of message objects with role and content |
messages[].role | "user" | "assistant" | Yes | Who sent this message |
messages[].content | string | Yes | The message text |
sessionId | string | No | Session ID for conversation continuity |
/api/leadsCapture a lead (email, name, dispensary). Used by the widget automatically, but available for custom integrations too.
const response = await fetch("https://budbot-inky.vercel.app/api/leads", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
name: "Jane Smith",
email: "jane@example.com",
dispensary: "Green Valley",
source: "website_form"
})
});
const data = await response.json();
// { ok: true }Rate Limits
Rate limits depend on your plan and are applied per API key:
| Plan | Chats / Month | Requests / Min |
|---|---|---|
| Free | 100 | 10 |
| Pro | 1,000 | 30 |
| Business | Unlimited | 60 |
| Enterprise | Unlimited | 120+ |
When you exceed the rate limit, the API returns 429 Too Many Requests with a Retry-After header.
Error Codes
The API uses standard HTTP status codes. Errors include a JSON body with details:
{
"error": "Invalid API key",
"code": "INVALID_KEY",
"status": 401
}| Status | Code | Description |
|---|---|---|
| 400 | BAD_REQUEST | Missing or invalid request parameters |
| 401 | INVALID_KEY | API key is missing, invalid, or expired |
| 403 | DOMAIN_NOT_ALLOWED | Request origin not in allowed domains list |
| 404 | NOT_FOUND | Endpoint not found |
| 429 | RATE_LIMITED | Too many requests — slow down or upgrade plan |
| 500 | INTERNAL_ERROR | Server error — try again or contact support |
Ready to integrate?
Create your free account and get your API key in minutes.