Workflows
Idiomatic patterns for common Connect integrations. The endpoint-by-endpoint references live under Resources; this page is the cookbook.
Bootstrap an integration
Section titled “Bootstrap an integration”Hit a few read endpoints once at startup and cache the IDs:
const headers = { Authorization: `Bearer ${TOKEN}` };
const [tables, calendars, appointmentTypes, resources] = await Promise.all([ fetch(`${API}/connect/tables/`, { headers }).then(r => r.json()), fetch(`${API}/connect/calendar/`, { headers }).then(r => r.json()), fetch(`${API}/connect/appointment_types/`, { headers }).then(r => r.json()), fetch(`${API}/connect/resources/`, { headers }).then(r => r.json()),]);
// For each table you'll write to, fetch its lead statesconst leadPool = tables.find(t => t.name === 'Inbound');const fullPool = await fetch(`${API}/connect/tables/${leadPool.id}`, { headers }).then(r => r.json());const initialState = fullPool.leadStates.find(s => s.default);Cache these — they don’t change often. Refresh on a schedule (daily) or invalidate when your integration hits a 404 on an ID.
CRM sync — push every new lead
Section titled “CRM sync — push every new lead”// Triggered when your CRM gets a new leadawait fetch(`${API}/connect/table_entries/`, { method: 'POST', headers, body: JSON.stringify({ tableId: leadPool.id, leadStateId: initialState.id, data: { firstName: lead.firstName, lastName: lead.lastName, email: lead.email, phone: lead.phone, }, customFieldData: { [crmIdFieldId]: lead.crmId, }, }),});The created entry fires table.entry.added and table.entry.leadState.changed — your automations run automatically.
For dedup strategies, see Race conditions → Duplicate creates.
Move a lead to a new state
Section titled “Move a lead to a new state”await fetch(`${API}/connect/table_entries/${entryId}`, { method: 'PATCH', headers, body: JSON.stringify({ leadStateId: newState.id }),});Fires table.entry.leadState.changed only. Other fields untouched (see Merge patch).
Book a slot after lead capture
Section titled “Book a slot after lead capture”The full call sequence:
// 1. Find an available slot in the requested windowconst url = `${API}/connect/availability/?calendarId=${cal}&appointmentTypeId=${apt}&start=${start}&end=${end}`;const { data } = await fetch(url, { headers }).then(r => r.json());const slot = data.find(s => s.available);if (!slot) throw new Error('No availability in requested window');
// 2. Create the lead (or use an existing one)const entry = await fetch(`${API}/connect/table_entries/`, { method: 'POST', headers, body: JSON.stringify({ tableId, leadStateId, data: leadData }),}).then(r => r.json());
// 3. Book the slot, linking to the leadawait fetch(`${API}/connect/calendar_bookings/`, { method: 'POST', headers, body: JSON.stringify({ calendarId: cal, appointmentTypeId: slot.appointmentTypeId, resourceId: slot.resourceId, resourceSlotId: slot.resourceSlotId, startDateTime: slot.startDateTime, endDateTime: slot.endDateTime, tableEntryId: entry.id, }),});Wrap the booking call in a refetch-and-retry loop in case the slot fills in step 3 — see Race conditions → Slot-fill races.
Reschedule
Section titled “Reschedule”There’s no reschedule endpoint. Delete + recreate:
await fetch(`${API}/connect/calendar_bookings/${oldId}`, { method: 'DELETE', headers });await fetch(`${API}/connect/calendar_bookings/`, { method: 'POST', headers, body: JSON.stringify(newBooking) });Fires calendar.appointment.deleted then calendar.appointment.booked — make your flows idempotent or use a transient lead state to suppress notifications during the swap.
Archive a custom field value
Section titled “Archive a custom field value”// Setting a custom field's value to null deletes that key.await fetch(`${API}/connect/table_entries/${entryId}`, { method: 'PATCH', headers, body: JSON.stringify({ customFieldData: { [oldFieldId]: null }, }),});See Merge patch for the full semantics.
Related
Section titled “Related”- Race conditions — how to make these patterns robust.
- Authentication — scopes you’ll need (
writefor these flows,adminif reschedules are in scope). - Resource references — endpoint-level docs with embedded schemas.