The Contacts page
What a contact is
A contact record is created the first time a visitor's interaction carries an identity signal:
an email address (captured by a skill, or passed via setUser()) or a verified external_id
from your own system. A fully anonymous visitor who never provides either doesn't get a contact
record; their conversation exists, but isn't linked to a contact.
Once a contact exists, AskVault keeps deduplicating against it:
- Email match. Same email = same contact.
- External ID match. Same verified
external_id(from identity verification) = same contact.
New display fields (name, phone, plan) fill in empty slots on the existing record, and custom attributes merge in (new keys win on conflict) rather than overwriting the whole profile.
Adding contacts yourself
Contacts appear on their own as people talk to your agent, but you don't have to wait for that. If the Add contact and Import CSV buttons aren't on your Contacts page yet, this is still rolling out to accounts.
Import a CSV
Import CSV takes a file with a header row. These columns map onto contact fields, matched
case-insensitively with spaces and hyphens treated as underscores: so External ID, external-id
and external_id all work:
| Column | Goes to |
|---|---|
external_id | The contact's ID in your own system |
email | Email address |
name | Display name |
phone | Phone number |
plan | Plan label |
Every other column is kept as a custom attribute. A loyalty_tier column in your export stays
with the contact and is available to segments.
Limits per file: 1,000 rows and 5 MB. Split a larger export into several files. The file has to
parse as CSV and its header must contain at least one of external_id, email, name or phone:
renaming a spreadsheet to .csv isn't enough.
Each row needs at least one of external ID, email or phone. Rows without one, and rows with an address that isn't an email, are skipped and listed back to you by row number; the rest of the file still imports.
Re-importing is safe. An import doesn't create a second copy of someone who is already there: it matches on email, then external ID, then phone, and updates the record it finds. The result summary tells you how many were added versus updated.
Add one contact
Add contact takes external ID, email, name and phone. At least one of external ID, email or phone is required, and the same matching rules apply: if the person is already a contact, you update them rather than create a duplicate.
Via the API
POST /api/workspaces/{workspace_id}/contacts accepts one contact object or an array of up to
1,000 per request, with the same fields plus an attributes object. It returns counts of
created, updated and skipped rows, and a per-row reason for anything skipped.
What the Contacts page shows
A searchable list with:
- Name and email.
- Plan. From your own system, if you pass it.
- Conversation count. Total linked conversations.
- First seen / last seen. Timestamps.
Search matches name, email, or external_id. You can also filter by a saved segment (see below).
Contact detail view
Click any contact to see:
- Profile. Name, email, phone, plan, and any custom attributes passed via
setUser()or the API. - Linked conversations. Every conversation tied to this contact, across every channel, most recent first: each row shows the channel, status, message count, and last-message time.
Editing a contact from this view lets you update name, phone, and plan.
Saved segments
A segment is a named, reusable filter over your contact list, evaluated live (not a static snapshot): so a segment's membership is always current. A segment can combine:
- Plan equals X.
- Email contains X.
- A custom attribute key/value.
- Last seen within N days.
- Minimum conversation count.
Useful for building a working list: e.g., "plan=enterprise, last seen within 30 days": without re-typing the filter every time.
Custom attributes
Whatever you pass via setUser(), a CSV import, or the API lands in the contact's attribute set
and merges across interactions (a later call adding a new key doesn't erase earlier ones). Values
are stored as-is: they aren't type-validated or coerced.
Manage attributes lets you declare the attributes this workspace tracks, each with a key, a display label and a type (text, number, date or boolean), up to 50 of them. This list is a naming convention for your team, not a filter: an import keeps every column whether or not you've declared it, and an undeclared attribute is still searchable in segments.
Privacy
AskVault stores only what a workspace's own integration passes in: email, name, phone, plan, and whatever custom attributes you choose to send. There's no third-party enrichment. For account- and workspace-level data deletion, see account deletion; there isn't a dedicated per-contact delete endpoint on this page today.
Planned features (on the roadmap)
Documented for accuracy: none of the following exist yet:
- Contact-level tags, separate from conversation tags.
- CRM sync status (synced/pending/error) shown per contact.
- A manual merge action for contacts that didn't auto-deduplicate.
- Bulk operations (bulk tag, bulk export, bulk CRM re-sync) from the contact list.
- A dedicated contact-deletion endpoint for per-contact GDPR erasure requests.
Limits
- Contacts per workspace. No hard cap.
- List page size. Up to 200 contacts per request.
- Linked conversations shown. Up to 100 most recent per contact.
Common pitfalls
Duplicate contacts for the same person. Neither interaction carried a matching email or external_id, so AskVault had nothing to link them on. There's no manual merge today: the duplicates stay separate.
Contact missing expected fields. Only what you actively pass via setUser() or the API gets
stored. AskVault doesn't infer or enrich fields on its own.
Anonymous visitor doesn't show up here. Expected. A contact record only exists once an email or verified external_id is captured.
FAQ
What's the difference between a contact and a lead?
A contact is the durable, cross-channel person record. A lead is captured sales intent tied to a conversation. They can refer to the same person without being the same record.
Can I import contacts from a CSV?
CSV import is rolling out (see Import a CSV above). Until it reaches your account, contacts are created automatically as visitors identify themselves.
Do anonymous visitors show as contacts?
No. A contact is only created once an email or a verified external_id is available. Until then, the conversation exists without a linked contact.
Can I bulk-edit or bulk-delete contacts?
Not from this page today.
Does AskVault store sensitive customer attributes?
Only what you pass. There's no enrichment from third-party sources: if you don't send a field, it isn't stored.