route_lead
Routes lead data through a ChiliPiper Concierge router and returns a booking calendar URL. Requires lead email and router slug.
Instructions
Route a lead through a ChiliPiper Concierge router. Submits lead/form data and returns a booking calendar URL.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| Yes | Lead's email address (required) | ||
| router | Yes | Router name/slug to route through | |
| first_name | No | Lead's first name | |
| last_name | No | Lead's last name | |
| company | No | Lead's company name | |
| phone | No | Lead's phone number | |
| title | No | Lead's job title | |
| redirect_url | No | URL to redirect after booking | |
| locale | No | Language locale (e.g. en-US) | |
| account_id | No | Salesforce Account ID to associate | |
| meeting_type_id | No | Force a specific meeting type by UUID | |
| extra_fields | No | Additional form fields as key-value pairs |
Implementation Reference
- index.js:37-124 (registration)The tool 'route_lead' is registered via server.tool() on line 37 with name 'route_lead' and description.
server.tool( "route_lead", "Route a lead through a ChiliPiper Concierge router. Submits lead/form data and returns a booking calendar URL.", { email: z.string().describe("Lead's email address (required)"), router: z.string().describe("Router name/slug to route through"), first_name: z.string().optional().describe("Lead's first name"), last_name: z.string().optional().describe("Lead's last name"), company: z.string().optional().describe("Lead's company name"), phone: z.string().optional().describe("Lead's phone number"), title: z.string().optional().describe("Lead's job title"), redirect_url: z .string() .optional() .describe("URL to redirect after booking"), locale: z.string().optional().describe("Language locale (e.g. en-US)"), account_id: z .string() .optional() .describe("Salesforce Account ID to associate"), meeting_type_id: z .string() .optional() .describe("Force a specific meeting type by UUID"), extra_fields: z .record(z.string()) .optional() .describe("Additional form fields as key-value pairs"), }, async ({ email, router, first_name, last_name, company, phone, title, redirect_url, locale, account_id, meeting_type_id, extra_fields, }) => { if (!DOMAIN) { return { content: [ { type: "text", text: "Error: CHILIPIPER_DOMAIN environment variable is not set.", }, ], }; } const form = { PersonEmail: email, ...(first_name && { FirstName: first_name }), ...(last_name && { LastName: last_name }), ...(company && { Company: company }), ...(phone && { Phone: phone }), ...(title && { Title: title }), ...(extra_fields || {}), }; const options = { router, ...(redirect_url && { dynamicRedirectLink: redirect_url }), ...(locale && { locale }), ...(account_id && { accountId: account_id }), ...(meeting_type_id && { meetingTypeId: meeting_type_id }), trigger: "ThirdPartyForm", }; try { const result = await cpFetch(`${BASE_URL}/marketing/${DOMAIN}`, { method: "POST", body: JSON.stringify({ form, options }), }); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }], }; } catch (err) { return { content: [{ type: "text", text: `Error: ${err.message}` }], }; } } ); - index.js:40-65 (schema)Zod schema definitions for all input parameters of the route_lead tool (email, router, first_name, last_name, company, phone, title, redirect_url, locale, account_id, meeting_type_id, extra_fields).
{ email: z.string().describe("Lead's email address (required)"), router: z.string().describe("Router name/slug to route through"), first_name: z.string().optional().describe("Lead's first name"), last_name: z.string().optional().describe("Lead's last name"), company: z.string().optional().describe("Lead's company name"), phone: z.string().optional().describe("Lead's phone number"), title: z.string().optional().describe("Lead's job title"), redirect_url: z .string() .optional() .describe("URL to redirect after booking"), locale: z.string().optional().describe("Language locale (e.g. en-US)"), account_id: z .string() .optional() .describe("Salesforce Account ID to associate"), meeting_type_id: z .string() .optional() .describe("Force a specific meeting type by UUID"), extra_fields: z .record(z.string()) .optional() .describe("Additional form fields as key-value pairs"), }, - index.js:66-123 (handler)The async handler function that executes the route_lead tool logic: builds form/options payload, calls cpFetch POST to the ChiliPiper marketing API endpoint, and returns the result.
async ({ email, router, first_name, last_name, company, phone, title, redirect_url, locale, account_id, meeting_type_id, extra_fields, }) => { if (!DOMAIN) { return { content: [ { type: "text", text: "Error: CHILIPIPER_DOMAIN environment variable is not set.", }, ], }; } const form = { PersonEmail: email, ...(first_name && { FirstName: first_name }), ...(last_name && { LastName: last_name }), ...(company && { Company: company }), ...(phone && { Phone: phone }), ...(title && { Title: title }), ...(extra_fields || {}), }; const options = { router, ...(redirect_url && { dynamicRedirectLink: redirect_url }), ...(locale && { locale }), ...(account_id && { accountId: account_id }), ...(meeting_type_id && { meetingTypeId: meeting_type_id }), trigger: "ThirdPartyForm", }; try { const result = await cpFetch(`${BASE_URL}/marketing/${DOMAIN}`, { method: "POST", body: JSON.stringify({ form, options }), }); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }], }; } catch (err) { return { content: [{ type: "text", text: `Error: ${err.message}` }], }; } } - index.js:13-29 (helper)The cpFetch helper utility used by the route_lead handler to make authenticated HTTP requests to the ChiliPiper API.
async function cpFetch(url, options = {}) { const headers = { "Content-Type": "application/json", ...(API_KEY ? { "x-api-token": API_KEY } : {}), ...options.headers, }; const res = await fetch(url, { ...options, headers }); const text = await res.text(); if (!res.ok) { throw new Error(`ChiliPiper API ${res.status}: ${text}`); } try { return JSON.parse(text); } catch { return text; } }