Skip to page content
Make Agent Fast
  • Introduction
  • Quickstart
  • Core concepts
  • Dashboard tour
  • Build your agent
  • Add it to your website
  • Telegram: bots & groups
  • WhatsApp
  • Instagram: DMs & comments
  • Your inbox
  • Leads & sales pipeline
  • Analytics, team & billing
  • Messenger, Discord & KakaoTalk
  • Connect your AI assistant
  • Create an agent
  • Persona and instructions
  • Knowledge sources
  • FAQs and products
  • Lookups
  • Change actions
  • Booking with Cal.com
  • Google Calendar
  • Follow-ups and reminders
  • Page actions
  • Your own tools (MCP)
  • Voice and live calls
  • Display
  • Agent link
  • Custom domains
  • Embed overview
  • HTML and JavaScript
  • React and Next.js
  • Vue and Nuxt
  • SvelteKit
  • Astro
  • WordPress
  • Shopify
  • Webflow
  • Framer
  • Wix
  • Squarespace
  • Ghost
  • Notion and Linktree
  • Tilda
  • Imweb
  • Cafe24
  • Security and CSP
  • Connector overview
  • Telegram
  • WhatsApp
  • Messenger
  • Instagram
  • Discord
  • KakaoTalk
  • Conversations and leads
  • Analytics
  • Broadcasts
  • Notifications
  • Monetization
  • Use Claude and ChatGPT
  • Credits and usage
  • API overview
  • Credentials and tokens
  • Authentication
  • Scopes and errors
  • API quickstart
  • API recipes
  • API reference
  • Webhooks
  • SDK status
  • Rate limits
  • Plans and pricing
  • Security
  • AI provider keys
  • Privacy and data
  • Troubleshooting
  • Changelog
Docs
Log inAPI
Make Agent Fast documentation

Lookups

Read live customer records through signed requests to your business system.

At a glance

Read live customer records through signed requests to your business system.

Signed-in customersKnowledge sources

When to use a lookup#

Use a lookup for current order status, an existing booking or a customer's account record. Keep stable policies and product information in Knowledge. A lookup reads your system; it must not charge, cancel, reserve or otherwise change a record. Generic choice and confirmation cards only send a visitor message. For confirmed writes, use Change actions; for calendar reservations, use Booking with Cal.com. Only run-backed confirmation cards authorize those operations.

Configure the action#

Open Agent → Actions. Create the secret in Signed-in customers, store it on your server and implement customer identification. In Lookups, add a name such as order_status, explain when the agent should use it and enter your public HTTPS endpoint. Declare only the inputs you need, for example an order_id string. The agent sees the tool as lookup_order_status.

Keep Requires signed-in customer enabled for private records (the default). If disabled, requests can contain customer: null; return only information appropriate for an anonymous visitor. An ID mentioned in chat or extracted from a photo is an input, not authenticated identity.

Existing fields autosave; wait for the saved indicator before testing. You can enable/disable, edit or delete a lookup. The panel requires a configured secret. These actions are configured in the dashboard; wave 1 does not expose lookup management through the public API.

The request you receive#

Make Agent Fast sends a JSON POST to your configured URL. The examples below use placeholder signature values:

POST /agent/order-status HTTP/1.1
Content-Type: application/json
x-maf-timestamp: <unix-seconds>
x-maf-signature: v1=<64-lowercase-hex-characters>
{
  "version": 1,
  "action": "order_status",
  "requestId": "c5c1d94b-e88f-4bf6-8023-2dcd1e7ac67b",
  "siteId": "YOUR_SITE_ID",
  "input": { "order_id": "A128" },
  "customer": { "id": "customer_123", "email": "customer@example.com" }
}

action is the configured name without the lookup_ prefix. requestId identifies that attempt; siteId identifies your site. input contains only declared string parameters. customer is either null or the server-verified { id, email?, name? }; visitor/model inputs cannot replace it. Dashboard Test deliberately uses the sample customer entered by an authorized owner.

Verify the signature#

The signature is lowercase hexadecimal HMAC-SHA256 using your agent secret, prefixed by v1=. Sign exactly "maf-webhook-v1:" + timestamp + "." + rawBody. Preserve the received bytes; parsing and reserializing JSON before checking the signature can change them. This helper accepts a standard server-side Request, applies a five-minute freshness window and pins the site:

import { createHmac, timingSafeEqual } from "node:crypto";

export async function verifyLookupRequest(request, expectedSiteId) {
  const secret = process.env.MAF_SECRET_KEY;
  if (!secret) throw new Error("MAF_SECRET_KEY is required");
  const timestamp = request.headers.get("x-maf-timestamp");
  const signature = request.headers.get("x-maf-signature");
  const now = Math.floor(Date.now() / 1000);
  if (!timestamp || !/^\d+$/.test(timestamp) ||
      !Number.isSafeInteger(Number(timestamp)) ||
      Math.abs(now - Number(timestamp)) > 300) {
    throw new Error("Invalid timestamp");
  }
  if (!signature || !/^v1=[a-f0-9]{64}$/.test(signature)) {
    throw new Error("Invalid signature");
  }
  const rawBody = Buffer.from(await request.arrayBuffer());
  const expected = createHmac("sha256", secret)
    .update(`maf-webhook-v1:${timestamp}.`)
    .update(rawBody)
    .digest();
  const actual = Buffer.from(signature.slice(3), "hex");
  if (actual.length !== expected.length || !timingSafeEqual(actual, expected)) {
    throw new Error("Invalid signature");
  }
  const body = JSON.parse(rawBody.toString("utf8"));
  if (body?.version !== 1 || body.siteId !== expectedSiteId) {
    throw new Error("Invalid lookup scope");
  }
  return body;
}

Call it before your body parser consumes the request. Your handler should reject verification errors, validate the expected action and input shape, and check record ownership against body.customer.id before returning any private data. For example, select order A128 within that customer's orders, not by order ID alone. Never use input.customer_id, an email supplied in chat or a photo as authorization. Require a non-null customer for private endpoints. Limit incoming body size at your server, and track requestId within the freshness window if you require replay rejection; timestamp checking alone does not reject a replay within that window.

Use HTTPS and keep this endpoint read-only even though the transport is POST. After rotating the agent secret, update both your identity-signing server and lookup verifier.

Return a response#

Respond with a successful 2xx status and JSON matching this contract. The first example is a found record; the second is a normal no-match result:

{
  "found": true,
  "card": {
    "title": "Order #A128",
    "status": { "label": "Shipped", "tone": "success" },
    "fields": [{ "label": "Carrier", "value": "DHL" }],
    "reference": "A128",
    "asOf": "2026-10-12T09:00:00Z",
    "link": { "label": "Track", "url": "https://shop.example.com/orders/A128" }
  },
  "facts": { "order_id": "A128", "status": "shipped", "carrier": "DHL" }
}
{ "found": false }

found is required. For found: true, include card, facts, or both. A card requires title and fields (an empty array is allowed). Optional fields are status, reference, asOf and link. Do not add kind to the response card. Status tones are neutral, success, warning and danger. Use an ISO timestamp for asOf and an HTTPS link without embedded credentials. Invalid optional links are omitted.

facts is a flat object whose values are strings, finite numbers, booleans or null; nested objects and arrays are rejected. Unknown fields in the response/card schema are rejected. Return only the information needed to answer: the model receives escaped, bounded data marked as untrusted, not instructions. Card content is plain text, not HTML.

Limits and failure behavior#

ItemLimit
Lookups per agent5; unique names and IDs
Name^[a-z][a-z0-9_]{2,39}$; reserved action names are unavailable
Description300 characters
Declared inputs3; unique names matching ^[a-z][a-z0-9_]{1,31}$
Input descriptions / values300 / 200 characters; values are trimmed
EndpointPublic HTTPS, up to 500 characters, no credentials; private/internal addresses blocked; redirects not followed
Timeout / response body8 seconds / 32 KiB (32,768 bytes)
Model data2,000 characters, separate from the visitor card
Card title / labels / field values80 / 40 / 200 characters
Card fields8; at most 3 cards per agent turn

Missing customer identity produces a sign-in warning without calling your endpoint. Missing required inputs prompt the visitor for them. found: false shows a neutral no-match card. Timeouts, non-2xx statuses, invalid JSON/schema or oversized responses show a failure status and tell the model not to guess. Return found: false with 2xx for an ordinary missing record, rather than HTTP 404. Keep important facts concise: excess card strings and model data are clipped.

Test from the dashboard#

  1. Save the lookup and open Test. Enter a sample customer ID, optional email and all required inputs. Use an account you control.
  2. Run Test. This sends a real signed request, even if the lookup is disabled for visitors; ordinary rehearsal chat never calls the endpoint. The dashboard limits test attempts per owner.
  3. Inspect the validated card/summary or error, request ID, duration and HTTP status when available. Check your endpoint logs without recording secrets or customer tokens.
  4. Test found, not-found, wrong-account, missing input and timeout cases. Then test the real embed with two authenticated customers; a dashboard sample does not prove browser identity isolation or live model tool selection.

The widget shows status cards; generic choice/confirmation taps send their labels as messages. Run-backed change and booking confirmations use the protected execution flow instead. Connectors adapt cards to native text/cards and buttons, quick replies or lists, with text fallback subject to channel limits. Test each intended channel before relying on delivery.

PreviousFAQs and productsAdd structured answers and catalog information.NextChange actionsLet customers confirm a change, request owner approval and track the real outcome.
Was this page helpful?
On this page
  • When to use a lookup
  • Configure the action
  • The request you receive
  • Verify the signature
  • Return a response
  • Limits and failure behavior
  • Test from the dashboard
For AI systemsllms.txtllms-full.txt