Give the AI chatbot live context about the signed-in visitor: their plan, trial status, seats, recent activity, open invoices, and any custom attributes. The AI can then answer account questions accurately ("when does my trial end?", "am I on Pro?", "why was I charged?") instead of falling back to generic replies.
You expose one read-only JSON endpoint on your backend. Boei calls it during the conversation via a webhook tool, using a shared bearer token for auth. No SDK changes needed for the basic setup.
How to get there: Go to Setup → Chatbot in the top menu → click your chatbot → Actions tab → Add Tool.
customerInfo, a lead form, or by typing it).get_customer_account tool.GET to your endpoint with the visitor's email and your shared bearer token.The AI only calls the tool when it's actually useful (billing, plan, usage questions), not on every message.
Host a single endpoint on your backend, for example:
GET https://yourapp.com/api/boei/customer-lookup?email={email}
Authorization: Bearer <shared-secret>
200 with {"found": false} if the email isn't a customer. Do not return 404.Return a JSON object. All fields are optional. Include only what you have. The richer the payload, the better the AI's answers, up to about 4 KB (Boei truncates responses at ~4000 chars).
{
"found": true,
"identity": {
"customer_id": "cus_9F3aQ",
"email": "sara@acme.com",
"name": "Sara de Vries",
"company": "Acme BV",
"phone": "+31 6 12345678",
"locale": "nl",
"timezone": "Europe/Amsterdam",
"signup_date": "2025-11-14",
"account_url": "https://yourapp.com/admin/customers/cus_9F3aQ"
},
"subscription": {
"status": "active",
"plan": "Pro",
"plan_interval": "monthly",
"price": 49,
"currency": "EUR",
"trial": false,
"trial_ends_at": null,
"renews_at": "2026-08-01",
"cancel_at_period_end": false,
"payment_method": "card_visa_4242",
"billing_portal_url": "https://billing.stripe.com/session/xyz"
},
"usage": {
"seats_used": 3,
"seats_limit": 10,
"projects": 12,
"storage_used_gb": 4.2,
"storage_limit_gb": 50,
"period_start": "2026-07-01",
"period_end": "2026-07-31"
},
"billing": {
"open_invoice": false,
"open_invoice_amount": 0,
"last_invoice_date": "2026-07-01",
"last_invoice_amount": 49,
"past_due": false,
"vat_number": "NL123456789B01"
},
"activity": {
"last_login_at": "2026-07-05T14:22:00Z",
"days_since_signup": 236,
"days_since_last_login": 2,
"active_last_30_days": true,
"onboarding_completed": true,
"onboarding_step": null
},
"role": {
"is_admin": true,
"is_owner": true,
"team_size": 4
},
"flags": {
"has_2fa": true,
"is_vip": false,
"beta_features": ["new-editor", "ai-summaries"],
"referral_source": "google"
},
"custom": {
"industry": "logistics",
"signup_utm_campaign": "spring-launch",
"csm_name": "Milan"
},
"recent_events": [
{ "type": "invoice_paid", "at": "2026-07-01", "detail": "€49" },
{ "type": "seat_added", "at": "2026-06-18", "detail": "user #3" },
{ "type": "plan_upgraded", "at": "2026-05-02", "detail": "Starter → Pro" }
]
}
Guidance on what to include:
signup_date so the AI can reason about "new vs long-time customer".status, plan, trial_ends_at, renews_at, cancel_at_period_end cover ~80% of billing questions.open_invoice and past_due let the AI acknowledge payment issues instead of ignoring them.Do not include: other users' emails, chat transcripts, support ticket bodies, uploaded files, or any content the visitor shouldn't see about themselves.
{ "found": false }
The AI will handle this gracefully ("I couldn't find an account for that email — could you double-check?").
Go to Setup → Chatbot → Credentials and add a credential:
customer_lookup_tokenCredentials are encrypted at rest and only referenced by name from tools.
Go to Setup → Chatbot → Actions → Add Tool and paste:
{
"name": "get_customer_account",
"description": "Look up the current visitor's account details (plan, trial status, seats, billing state, recent activity). Call this whenever the visitor asks anything about their subscription, billing, invoices, plan limits, usage, or account status. Only call this once you have the visitor's email — either from customerInfo, a lead form, or because they typed it. Do not call it for general product questions.",
"execution_type": "webhook",
"http_method": "GET",
"endpoint_url": "https://yourapp.com/api/boei/customer-lookup?email={{context.email}}",
"headers": {
"Authorization": "Bearer {{credential:customer_lookup_token}}",
"Accept": "application/json"
},
"parameters": [],
"response_mapping": {
"found": "found",
"plan": "subscription.plan",
"status": "subscription.status",
"trial_ends_at": "subscription.trial_ends_at",
"renews_at": "subscription.renews_at",
"past_due": "billing.past_due",
"seats_used": "usage.seats_used",
"seats_limit": "usage.seats_limit",
"last_login_at": "activity.last_login_at",
"billing_portal_url": "subscription.billing_portal_url"
},
"requires_confirmation": false,
"is_enabled": true
}
The response_mapping block extracts the fields the AI most often needs into flat keys. The AI still sees the full raw response, but flattened keys make prompt-side reasoning faster.
Open the widget preview, tell the bot your email, and ask "what plan am I on?" or "when does my trial end?". You should see the AI call get_customer_account in the trace and respond with real values.
The visitor's email is the lookup key. Simple, works today. Small risk on shared machines: if visitor A types visitor B's email, they'd see B's non-sensitive account fields. Mitigate by returning only summary fields (not full billing details or event logs).
If you want to expose more sensitive fields (open invoice amounts, billing portal URLs, event history), verify the visitor first.
{email, exp} with the shared secret (HMAC-SHA256, 5-minute expiry).window.Boei = window.Boei || {};
window.Boei.customerInfo = {
email: "sara@acme.com",
identity_token: "<hmac-signed-token>"
};
"endpoint_url": "https://yourapp.com/api/boei/customer-lookup?email={{context.email}}&identity_token={{context.identity_token}}"
This is the same pattern Intercom, Crisp, and Front use for "identity verification".
Once the tool is wired up, the AI can answer questions like:
billing_portal_url)It can also proactively adjust tone: greet long-time customers differently from someone who signed up yesterday, flag past-due accounts to a human agent, or skip generic onboarding tips for users who've completed onboarding.