The CRM integration uses an adapter pattern inside theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/gcsconsultores/gcs-website/llms.txt
Use this file to discover all available pages before exploring further.
sendToCrm() function in app/actions/lead-actions.ts. Once a lead passes Zod validation in submitLead(), the validated data is handed off to sendToCrm() — the single place where all CRM-specific HTTP logic lives. To connect a real CRM you only need to set two environment variables; no application code needs to change for standard integrations, and remapping field names to fit a provider’s schema requires editing just the body literal inside sendToCrm.
Required environment variables
The full endpoint URL for creating a contact or lead record in your CRM (e.g.
https://api.hubapi.com/crm/v3/objects/contacts). When this variable is absent, sendToCrm logs the lead to the server console and returns cleanly — no data is lost during development.The API key or Bearer token for your CRM. Sent as the
Authorization: Bearer <CRM_API_KEY> header on every request. For providers that use a different authentication header (e.g. api-key or X-Auth-Token), update the headers object inside sendToCrm.Payload schema
Every call tosendToCrm sends the following JSON body to CRM_API_URL. The outer properties wrapper matches HubSpot’s contact creation format; remap the keys for other providers (see per-CRM examples below).
submitted_at is generated server-side via new Date().toISOString() at the moment the action runs — it is not supplied by the browser.
Integration examples
- HubSpot
- Salesforce
- Zoho CRM
- Pipedrive
HubSpot’s Private App tokens use a The request lands in HubSpot as a new Contact with the properties listed above. Map custom properties in HubSpot’s object settings if
Bearer authorization header. The default properties wrapper in sendToCrm already matches HubSpot’s contact creation endpoint — no body changes are needed for a basic integration.full_name, area_of_interest, etc. are not yet defined as property keys in your portal.Customizing the request body
All property remapping is confined to thebody argument of the fetch call inside sendToCrm. Locate this section in app/actions/lead-actions.ts and edit only the keys inside properties (or replace the entire body shape) to match your CRM’s expected format:
lead argument is fully typed as LeadInput (inferred from leadSchema), so TypeScript will flag any accidental typos in field names.
Full sendToCrm function source
Error handling
sendToCrm is called inside a try/catch block in submitLead. If the fetch call throws (network timeout, DNS failure, etc.) or if the CRM returns a non-2xx status that causes fetch to throw, the error is caught and a user-facing ok: false response is returned — the raw error is never exposed to the browser.
fetch itself does not throw on non-2xx responses — it only throws on network-level failures. To treat 4xx/5xx CRM responses as errors, add a response status check inside sendToCrm:
When
CRM_API_URL is not set, sendToCrm returns immediately after logging — it does not throw. This means submitLead will still return ok: true to the user, confirming receipt of the form, while the lead data is safely captured in server logs until the CRM is configured.