Postgres lookup
The Postgres tool gives your assistant a narrow, single-row lookup pointed at one specific table in your own database. A caller asks "what's the status of order ORD-12345?" — the assistant takes the order number, calls the tool, and gets back the matching row formatted as readable key/value lines. No SQL is generated by the model; the lookup shape is pinned at setup time.
This is intentionally not a general-purpose SQL tool. It's a fast, safe way to expose one piece of your live data — orders, customers, inventory, accounts — to the assistant without giving the model any ability to write queries on its own.
What you can do with this tool
- Look up one row by a key value that's matched against one or more pre-configured identifier columns (e.g. order number or customer email, both on the same table).
That's the whole surface. Multi-row queries, joins, aggregations, and writes aren't supported. For those, use a Custom tool backed by a narrow HTTP endpoint on your side.
Business use cases
Order-status lookup during support
An e-commerce company runs a customer-support chat widget. They expose the orders table to the assistant, configured with identifier columns order_number and customer_email. Customers ask "where's my order?", the assistant captures either the order number or their email, calls the lookup, and reads back the status and tracking URL in plain language: "Order ORD-12345 was shipped on May 10. Here's the tracking link: ..."
Account-lookup for a SaaS support agent
A SaaS company exposes their customers table — identifier columns email and phone. The chat assistant identifies the caller, calls the lookup, and gets back their plan, renewal date, and any open billing alerts. The assistant can then answer "you're on the Pro plan, renews June 15, no outstanding balance" without escalating to a human for basic account questions.
Live inventory check for a parts retailer
A specialty parts retailer exposes their inventory table with sku as the identifier. Callers ask "do you have SKU 4421 in stock?" — the assistant looks it up and reads back the quantity, price, and bin location. Phone calls that previously required a warehouse runback now resolve in one turn.
Product info pulled from your existing catalog
An appliance company has a product catalog in Postgres with thousands of SKUs. The voice agent's prompt is too small to hold them all. Instead, the catalog table is exposed via the lookup tool with model_number and sku as identifier columns. The assistant collects the model number, calls the lookup, and answers questions about that specific product using the fetched row.
How the lookup works
The query shape is fixed at setup. You configure:
- A table to look against (e.g.
orders). - One or more identifier columns that count as match targets (e.g.
order_number,customer_email).
When the assistant calls the tool with a single lookup_key, the tool searches across all configured identifier columns for an exact match and returns the first row it finds.
Connecting
Step-by-step
- Go to Tools & Integrations → Postgres → Add.
- Provide the connection details:
- Host
- Port
- Database name
- User
- Password
- Pick the lookup table from the dropdown (Insighto auto-populates this from your database).
- Pick the identifier columns — one or more columns the assistant can match its lookup key against.
- Save.
All connection details are stored encrypted. Each tool call opens a fresh connection.
Prerequisites
- Postgres reachable from Insighto's infrastructure (see "Network reachability" below).
- A dedicated read-only role for Insighto's connection (strongly recommended — see below).
- Indexes on every identifier column so lookups stay fast.
Read-only safety — do it at the database
The tool only generates SELECT statements today, but the safety net you should rely on is the Postgres role you connect with. Create a dedicated role on your side that can read the lookup table and nothing else:
CREATE ROLE insighto_readonly WITH LOGIN PASSWORD 'strong-random-password';
GRANT CONNECT ON DATABASE your_db TO insighto_readonly;
GRANT USAGE ON SCHEMA public TO insighto_readonly;
GRANT SELECT ON orders TO insighto_readonly;
-- Explicitly do NOT grant INSERT / UPDATE / DELETE / CREATE.
Connect Insighto as that role. Even if the lookup ever generated more than SELECT, the database itself would refuse anything else. Don't connect as a superuser.
A note on SQL injection
The lookup_key value is interpolated into the SQL query, so a malicious key containing quote characters could in theory attempt SQL injection against the role you connected with. Three layers of mitigation, in order of importance:
- Use a read-only role with
SELECT-only grants on the specific table. This is the strongest guarantee. - Validate the lookup key shape upstream when possible — in the assistant's prompt, instruct the model to only pass keys matching your expected format (e.g.
ORD-NNNNN). - For sensitive data, use a Custom tool instead — it gives you full control over parameterization on your side.
Don't connect this tool to a database you'd be unhappy about a bad actor reading. The model is also a vector — a prompt-injection attack against the assistant could try to make it call the tool with a hostile key.
Functions the assistant can call
lookup_value_one
Fetches the first matching row from the configured table.
- Arguments
lookup_key(string, required) — the value to search for. The tool matches it against all configured identifier columns.
- Returns — the matching row formatted as
col: value\n...lines. Returns"None found"when no row matches.
Example invocation
The assistant looks up an order:
{
"function": "lookup_value_one",
"arguments": {
"lookup_key": "ORD-12345"
}
}
Result returned (with lookup_table = orders and identifier columns [order_number, customer_email]):
id: 412
order_number: ORD-12345
customer_email: alice@example.com
status: shipped
total_cents: 4999
created_at: 2026-05-10 14:30:00
shipped_at: 2026-05-12 09:15:00
tracking_url: https://carrier.com/track/abc
The assistant reads this and answers the customer: "Your order ORD-12345 was shipped on May 12. Here's the tracking link: https://carrier.com/track/abc"
System prompt guidance
The model needs to know what the lookup key represents. Because the tool exposes one function with one parameter, the prompt has to spell out the contract:
Use
lookup_value_oneto look up a single order in our system. Thelookup_keyshould be either an order number (formatORD-NNNNN) or the email address on the order. When the customer asks about an order, capture one of those, then call the tool. If the result is "None found", apologize and ask the customer to double-check the order number. If you get a row back, summarize the status, ship date, and tracking link in plain language — don't read the raw fields.
Sharpen this for whatever your specific identifier columns and use case actually are.
Returned format
The result is a plain string formatted as col: val\n... lines, not JSON. A few things to know:
- Timestamps come back in their default string form (e.g.
2026-05-10 14:30:00). The model parses them fine when answering the user. - NULLs come back as the literal text
None. Tell the model in the prompt to read "I don't have that information" instead of literally saying "None" when it sees that. - Large columns (JSON blobs, base64 data) come back stringified and can eat into your token budget. Denormalize into narrower views or pick more specific columns.
Network reachability
Insighto needs to reach your Postgres from its infrastructure. Options:
- Public endpoint with IP allowlist — easiest, fine for most managed databases (RDS, Cloud SQL, Supabase, Neon). Whitelist Insighto's egress IPs.
- Bastion / SSH tunnel — for private VPC databases, expose via a bastion host.
- VPC peering — supported on enterprise plans for the strictest security postures.
For TLS, enforce it server-side via your pg_hba.conf rules (hostssl) so plaintext connections are refused at the DB level.
What this tool isn't
- Not a multi-row query tool. It returns one row.
- Not a join tool. It queries one table.
- Not a write tool. Only
SELECTis generated. - Not a SQL execution tool. The model doesn't write SQL; you configure the shape upfront.
For anything beyond that, build a Custom tool with a narrow HTTP endpoint on your side that wraps whatever query you actually need.
Failure modes
- Connection failure — wrong host, firewall closed, credentials rotated. The assistant gets an error result; the model usually apologizes and offers to take a message.
- Slow query / full table scan — there's no statement timeout. Add an index on every identifier column to keep lookups under 100ms.
- No match found — returns
"None found". The assistant should ask the customer to verify the identifier, not invent data. - Returned row is too large — long JSON blobs can blow up the context. Denormalize the lookup table or pick narrower identifier columns.
Where to next
- For multi-row queries, joins, aggregations, or writes, use a Custom tool.
- Combine with HubSpot to layer CRM data on top of live operational data.
- See the Tools overview for prompt patterns that apply across every integration.