CRM & Webhooks
Connect your agents to customer data and external systems. The Get User tool hydrates the agent with caller identity at the start of every conversation and on demand mid-call. Webhooks push data out to any external service in real time.Get User Tool
Get User pulls caller / visitor information from one or more sources, normalises it into a set of{{variable}} slots that substitute into your greeting + system prompt, and exposes the same data to the agent’s get_user() function for mid-conversation lookups.
Four sources, multi-select
You can enable any combination — they run in priority order and later sources can use earlier sources’ values.The Database source connects to your own Postgres only. ThinnestAI’s platform tables are not queryable from your agents — your data stays in your control.
Search By
You decide which fields the agent is allowed to use as the lookup identifier:- Name — agent passes the caller’s name to
get_user("Sarah Johnson"). - Contact Number — agent passes the caller’s phone.
- Other — add as many labelled fields as you need (Customer ID, Email, Account Number, Loyalty Number, …). Each becomes its own searchable key.
{{variable}} slots in your greeting and system prompt. Even if you don’t enable any DB/API/Webhook lookup, just declaring “Customer ID” in Search By + capturing it from the embed URL means you can write Hello {{customer_id}}! in your greeting.
Setting up the tool
- Navigate to your agent → Tools → Add Tool → Get User.
- Search By: tick Name and/or Contact Number, and add Other rows for any custom identifiers your CRM uses.
- Get User Details From: enable one or more sources. Click each source in the sidebar to configure it.
- Save.
Search By, the timing options, or any of the four sources in the left rail; the editor for the selected item fills the right pane.
When the lookup runs
The first item in the sidebar — Get Details / User Data — controls when enabled sources execute. Two independent toggles:
Enable either, both, or neither — most setups want both on.
Source 1 — URL (Web Embed)
For the chat widget and try-voice-call panel, the embed URL’s query params travel with the conversation. For phone calls, the same field carries outbound-campaign custom variables. Config:
Embed URL example:
{{customer_id}} = C-987, {{email}} = jane@x.com, {{plan}} = Pro.
Outbound campaign example: when you launch a campaign, each contact row’s custom variables (e.g. {"customer_id": "C-987", "plan": "Pro"}) ride along with the dispatched call and land in the same URL-source slot.
Source 2 — Webhook (CRM lookup)
FiresPOST <your-url> with {"identifier": "<lookup>"} at conversation start. Response JSON’s top-level fields become {{variables}}.
Config:
Request:
{{name}}, {{email}}, {{account_type}}, {{account_status}}, {{last_order}}.
Source 3 — API (generic REST)
The full power of HTTP. Use this when your CRM expects aGET with the identifier in the URL, or a custom JSON body, or you need to call the same endpoint with different params per session.
Config:
Placeholders available inside templates:
{lookup}— what the agent passed toget_user()(or the caller’s phone at conversation start){contact_no},{email},{customer_id},{name}, … — anything supplied by earlier sources (URL, Webhook) or that the embed/dispatch provided- Missing placeholders collapse to empty string — your endpoint should tolerate it
Source 4 — Database (your own Postgres)
Connect the agent to your own Postgres database for direct lookups. The agent never writes SQL — you define query templates with named parameters, and the agent only supplies values. Security model:- Connection is opened read-only for every query.
- Write keywords (
INSERT,UPDATE,DELETE,DROP,CREATE,ALTER,TRUNCATE,GRANT,REVOKE,COPY ... FROM, …) are rejected before the query reaches your DB. - Only a single SQL statement per template — stacked statements are blocked.
- Statement timeout caps every query at 5 seconds.
- Results are capped to 50 rows per call.
- Values are bound as parameters — there is no string interpolation into SQL.
- Credentials are stored encrypted in the platform.
Click Test Connection to verify the agent can reach your DB.
Query templates:
Each template binds the agent’s lookup arg to one of your Search By keys.
Visual builder: if you’d rather not write SQL, switch to Visual mode. Pick the table from a searchable dropdown (populated from your DB’s
information_schema — type to filter when you have hundreds of tables), multi-select columns with search + Select all, add WHERE conditions with operator + bound parameter, set ORDER BY + LIMIT. The generated SQL preview updates live and is validated against your DB on every change.
Bulk-add tables
If your schema has many tables and you want one query per table — for example, an agent that should be able to read fromusers, orders, wallets, subscriptions, and a dozen more — use the Bulk button next to + Add in the Queries list.
- Click Bulk → the right pane swaps to the bulk-add view.
- Search for tables and/or click Select all to grab everything visible (the toggle respects your current filter — type
audit_then click Select all to grab everyaudit_*table at once). - (Optional) Configure Apply this WHERE to every query:
- Column — autocompletes from the union of columns across every selected table (so picking 87 tables surfaces every column name you might want).
- Op —
=,!=,LIKE,ILIKE,IN. Defaults to=. - Bind to — pick which Search By key to bind the value to (e.g.
:email_id,:contact_no,:customer_id). - A live coverage badge tells you how many of the picked tables actually have the column you typed (green = all match, amber = partial, red = none).
- Click Add N queries — one query template gets created per selected table.
Each generated query starts on the visual builder, with the table set, columns empty (
SELECT *), and the WHERE row populated where applicable. The first newly-added query is selected automatically so you land on something useful instead of staring at the sidebar.
SQL example — search by email:
get_user("jane@x.com") and the active template’s Search By is email, the value is bound to %(email)s automatically. You don’t need to plumb the agent’s input anywhere — it’s wired by the Search By config.
How the identifier reaches the lookup
Variables in greeting + system prompt
Every Search By field and every key in a source’s response map shows up in the{{ }} autocomplete inside your greeting and system prompt editors.
Greeting:
{"name": "there"}).
Source chaining — concrete example
A bank wants the agent to greet the caller by name AND check their account balance. Setup:- Search By: Customer ID (key=
customer_id), Contact Number - URL source: enabled,
allowed_keys: customer_id - Database source: enabled, query template:
- Search By:
customer_id - SQL:
SELECT name, account_status, current_balance FROM customers WHERE customer_id = %(customer_id)s LIMIT 1 - Response map:
name → name,status → account_status,balance → current_balance
- Search By:
- Greeting:
Hi {{name}}! Your current balance is ₹{{balance}} and your account is {{status}}.
- Caller dials in. The phone number is on file in
campaign_contacts, so the dispatcher attaches theircustomer_idto the call. - URL source captures
customer_id = "C-987". - Database source runs
WHERE customer_id = %(customer_id)s→ returnsname,status,balance. - Greeting interpolates → “Hi Jane! Your current balance is ₹45,200 and your account is Active.”
Using lookup data in the conversation
Once Get User has populated the variables, the agent can reference them naturally in its instructions:Custom Webhook Integration
Beyond CRM lookups, you can use webhooks to send data from your agent to any external system.Sending Data to External Systems
Create a custom webhook tool that pushes data to your backend: Common webhook use cases:Setting Up an Outbound Webhook
- Go to Tools > Add Tool > Custom Tool (API).
- Configure your webhook endpoint:
- Define the parameters the agent will fill in:
- The agent will call this webhook when it determines a ticket should be created.
Webhook Authentication
Secure your webhooks with one of these methods:Webhook Response Handling
Your webhook should return a JSON response that the agent can use:Receiving Webhook Events
You can also trigger agent actions from external events by sending webhooks to the thinnestAI API.Use Cases
- New lead in CRM — Trigger the agent to send a welcome email.
- Payment received — Notify the agent to update the customer’s account status.
- Support ticket updated — Have the agent follow up with the customer.
Sending Events to thinnestAI
Example: Full CRM-Connected Voice Agent
Build a voice agent that looks up callers, handles requests, and logs everything to your CRM.Agent Setup
Agent Instructions
Best Practices
CRM Integration
- Cache responses — If your CRM lookup is slow, consider caching frequent lookups.
- Handle missing users — Tell the agent what to do if the user isn’t found in the CRM (e.g., collect their info and create a new record).
- Keep data fresh — CRM data can change. The agent fetches it live on each interaction.
Webhook Reliability
- Return quickly — Your webhook endpoint should respond within 5 seconds. For longer operations, accept the webhook and process asynchronously.
- Return meaningful errors — If something goes wrong, return an error message the agent can relay to the user.
- Idempotency — Design your webhooks to handle duplicate calls gracefully.
Security
- Validate webhook signatures on your server to ensure requests come from thinnestAI.
- Use HTTPS for all webhook endpoints.
- Limit data exposure — Only return the CRM fields your agent actually needs.
Webhook Tools (Zapier / Make.com / n8n)
Send data from your agent to any automation platform. Three tiles cover the common platforms:
All three share the same runtime behaviour (the agent POSTs a JSON payload with
{event, source, data}). The separate tiles exist for discoverability and platform-specific config hints. You can use multiple simultaneously in one agent (e.g. one Make scenario + one n8n workflow).
Setting Up (generic Webhook)
- Go to Tools > Add Tool > Webhook.
- Paste your webhook URL from Zapier or any custom endpoint.
- Optionally name it (e.g., “Zapier CRM”) and add a webhook secret.
What the Agent Can Do
The agent has two functions:send_webhook(data, event_type)— Send any JSON data with an event typesend_event(event_name, customer_name, email, phone, notes)— Send structured CRM-style events
Example: Zapier Lead Capture
Payload Format
Every webhook receives this JSON structure:Platform-Specific Setup
Composio (500+ App Integrations)
Connect your agent to 500+ SaaS apps using Composio — including CRMs (Zoho, Pipedrive, Freshsales), productivity tools, and more. Composio handles authentication and API complexity automatically.Setting Up
- Sign up at composio.dev and get your API key.
- Go to Tools > Add Tool > Composio.
- Paste your Composio API key.
- The agent can now access any app you’ve connected in your Composio dashboard.
Supported Apps
Composio connects to 500+ apps including:When to Use Composio vs. Direct Tools
Built-in CRM Tools
thinnestAI includes direct integrations for popular CRMs. These are deeper integrations with full CRUD operations.
To add a CRM tool: Tools > Add Tool > select the CRM > enter your API credentials.
Next Steps
- Custom Tools — Build more complex API integrations.
- SMS — Send text confirmations and follow-ups.
- Tools Overview — Browse all available tools.

