CRM data
HAL CRM data is structured to keep pipeline context useful to the operator.
Companies, contacts, stages, and notes should support action, not just record-keeping.
Key objects
- Visitor: widget-side identity keyed by your external
visitor_id; can later be linked to a contact and company records - Contact: person identity with name, email, phone, notes, tags, metadata, and linked visitors
- Company: account-level record with stage, deal value, notes, metadata, and linked contacts
- CRM stage: project-scoped pipeline stage used for ordering and stage precedence decisions
Where data belongs
- Company: deal value, pipeline stage, domain, industry, enrichment fields, and account-level notes
- Contact: person identity, tags, notes, and contact-specific metadata such as role, plan, or owner
- Visitor: browser-session identity, widget-facing properties, and transient product context attached before or during chat
Where deal value lives
Deal value is stored on the company record, not the individual contact. This keeps opportunity context attached to the account even when multiple people from the same company talk to HAL.
- Widget sync:
window.HalWidget.setDeal({ deal_value, company_id })updates the active or explicitly targeted company after the visitor is identified - Account API: direct company create and update routes also accept
deal_value
Linking rules
identify()is the main path that turns a widget visitor into a richer CRM record- When identify includes an email or user ID, HAL can match or create the related contact
company.idorcompany_idscan link the contact to one or more existing companiescompany.idis also the recommended way to establish the active company context for later widget CRM writes- If you send a
companyobject, HAL can also merge company metadata and optionally move the company stage
Many-to-many model
Contacts and companies are linked through a junction model rather than a single foreign key.
- One contact can be linked to multiple companies
- One company can be linked to multiple contacts
- The dashboard often shows a primary company view for convenience, but the underlying model is many-to-many
- Widget-side writes such as
setStage()andsetDeal()use explicitcompany_idfirst, then the active company fromidentify(company.id), then a single linked company
Write semantics during identify
- If the visitor already has a linked contact, HAL reuses it instead of creating another contact
- If no matching contact exists for the email, HAL creates one and links the visitor to it
- If the contact has no companies yet, HAL creates or reuses a placeholder company so company-level CRM fields have somewhere to live
- If a real company ID is later linked, HAL can unlink and delete the placeholder when no other contacts depend on it
- If company metadata is provided, it is merged into the chosen primary company record
- If contact metadata is provided, it is merged into the linked contact record
Stage precedence
Widget-originated stage writes support two modes:
advance_only: default; prevents widget sync from moving a company backward if CRM already shows a later stageexact: applies the requested stage exactly and is best reserved for authoritative backend syncs
Manual route semantics
- Manual contact create and update routes write contact fields only
- Manual company create and update routes write company fields only
- Linking and unlinking contacts to companies is a separate operation on top of those base records
- Deleting a contact unlinks visitors and removes its company junction records, but does not delete the companies themselves
- Deleting a company removes its contact junction records, but does not delete the contacts themselves
Common sync pattern
await window.HalWidget.identify({
visitor_id: 'user_456',
email: 'alice@acme.com',
metadata: { plan: 'enterprise', role: 'admin' },
company: {
id: 'acme',
name: 'Acme Inc',
stage: 'Qualified',
metadata: { crm_owner: 'Sam' }
}
});
await window.HalWidget.setDeal({
company_id: 'acme',
deal_value: 12000,
stage_name: 'Qualified'
});How the operator uses it
CRM data becomes one of the inputs that can move the current focus lane toward sales when the pipeline deserves immediate attention.