Customer Account Lookup


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.

How it works

  1. Visitor opens the chat and provides their email (via the widget's customerInfo, a lead form, or by typing it).
  2. When the AI needs account context, it calls the get_customer_account tool.
  3. Boei sends a GET to your endpoint with the visitor's email and your shared bearer token.
  4. Your endpoint returns a JSON object describing the account.
  5. The AI uses those fields to answer the visitor's question.

The AI only calls the tool when it's actually useful (billing, plan, usage questions), not on every message.

Your endpoint

Host a single endpoint on your backend, for example:

GET https://yourapp.com/api/boei/customer-lookup?email={email}
Authorization: Bearer <shared-secret>

  • Read-only. Never accept writes on this endpoint.
  • Rate-limit it (e.g. 60 req/min per token) — the AI can call it multiple times per conversation.
  • Return 200 with {"found": false} if the email isn't a customer. Do not return 404.
  • Do not include other users' PII (colleagues, teammates, etc.). Only the identified visitor's own data.
  • Do not include secrets (passwords, API keys, session tokens, full credit card numbers).

Response shape

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": "[email protected]",
    "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:

  • identity — anchors the AI to the right account. Include signup_date so the AI can reason about "new vs long-time customer".
  • subscription — the single most useful section. status, plan, trial_ends_at, renews_at, cancel_at_period_end cover ~80% of billing questions.
  • usage — lets the AI answer "am I close to my limit?"
  • billingopen_invoice and past_due let the AI acknowledge payment issues instead of ignoring them.
  • activity — helps the AI adjust tone (new user vs power user).
  • flags / custom — anything else that helps triage. Feature flags, VIP status, assigned CSM, industry.
  • recent_events — 3-10 recent lifecycle events. Great for questions like "what happened to my account last week?".

Do not include: other users' emails, chat transcripts, support ticket bodies, uploaded files, or any content the visitor shouldn't see about themselves.

Not-found response

{ "found": false }

The AI will handle this gracefully ("I couldn't find an account for that email — could you double-check?").

Configure the tool in Boei

1. Store the shared secret

Go to Setup → Chatbot → Credentials and add a credential:

  • Name: customer_lookup_token
  • Value: your shared bearer token

Credentials are encrypted at rest and only referenced by name from tools.

2. Create the webhook tool

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.

3. Test it

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.

Identity strategies

Email lookup (default)

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.

  1. On page load, your backend signs {email, exp} with the shared secret (HMAC-SHA256, 5-minute expiry).
  2. Pass it to the widget:

window.Boei = window.Boei || {};
window.Boei.customerInfo = {
  email: "[email protected]",
  identity_token: "<hmac-signed-token>"
};

  1. In the tool config, forward the token:

"endpoint_url": "https://yourapp.com/api/boei/customer-lookup?email={{context.email}}&identity_token={{context.identity_token}}"

  1. Your endpoint verifies the token before returning data. Reject on failure.

This is the same pattern Intercom, Crisp, and Front use for "identity verification".

Security checklist

  • Use HTTPS.
  • Rotate the shared secret periodically.
  • Log requests server-side for audit (which email was queried, when, from which IP).
  • Rate-limit per token.
  • Never return other users' data.
  • Never return secrets (session tokens, API keys, full card numbers).
  • Consider signed identity if you expose billing amounts or portal URLs.

What the AI can do with this

Once the tool is wired up, the AI can answer questions like:

  • "When does my trial end?"
  • "What plan am I on and how much does it cost?"
  • "How many seats do I have left?"
  • "Is my last invoice paid?"
  • "Can you send me to the billing portal?" (returns billing_portal_url)
  • "When did I sign up?"
  • "Am I an admin on this account?"

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.