Contacts
Contacts are people who have interacted with your workspace — by joining a room or booking a session. They are automatically created or updated when a participant joins a room or submits a booking. Contacts are scoped to a workspace and identified by email address.
All contacts endpoints require authentication (requireAuth). Access is scoped to workspace members.
The Contact Object
{
"id": 1,
"workspace_id": 2,
"name": "Alice Martin",
"email": "alice@example.com",
"event_count": 3,
"last_seen_at": 1711500000,
"created_at": 1710000000,
"updated_at": 1711500000
}
| Field | Type | Description |
|---|---|---|
id | integer | Unique contact ID |
workspace_id | integer | Owning workspace |
name | string | Contact's display name |
email | string/null | Contact's email address (unique per workspace) |
event_count | integer | Total number of events recorded for this contact |
last_seen_at | integer/null | Unix timestamp of the most recent event (null if none) |
created_at | integer | Unix timestamp when the contact was first seen |
updated_at | integer | Unix timestamp of the most recent upsert |
The ContactEvent Object
{
"id": 10,
"contact_id": 1,
"workspace_id": 2,
"event_type": "room_join",
"room_id": 5,
"room_name": "team-standup-1234",
"room_display_name": "Team Standup",
"booking_page_id": null,
"booking_page_title": null,
"booking_page_slug": null,
"metadata": null,
"created_at": 1711500000
}
| Field | Type | Description |
|---|---|---|
id | integer | Unique event ID |
contact_id | integer | Parent contact |
workspace_id | integer | Owning workspace |
event_type | string | Type of event — see table below |
room_id | integer/null | Associated room (null if not applicable or room deleted) |
room_name | string/null | Room slug |
room_display_name | string/null | Room display name |
booking_page_id | integer/null | Associated booking page (null if not applicable) |
booking_page_title | string/null | Booking page title |
booking_page_slug | string/null | Booking page slug |
metadata | string/null | Additional event data (JSON string) |
created_at | integer | Unix timestamp of the event |
Event types
event_type | Description |
|---|---|
room_join | Contact joined a video room |
booking | Contact submitted a booking via a booking page |
List Contacts
Returns a paginated list of contacts for the workspace, ordered by most recently seen. Any workspace member can list contacts.
GET /api/workspaces/:workspaceId/contacts
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
search | string | — | Filter by name or email (case-insensitive substring match) |
page | integer | 1 | Page number (min 1) |
limit | integer | 50 | Items per page (1–100) |
Response:
{
"contacts": [
{
"id": 1,
"workspace_id": 2,
"name": "Alice Martin",
"email": "alice@example.com",
"event_count": 3,
"last_seen_at": 1711500000,
"created_at": 1710000000,
"updated_at": 1711500000
}
],
"total": 1,
"page": 1,
"limit": 50
}
Get a Contact
Returns a single contact. Any workspace member can view contacts.
GET /api/workspaces/:workspaceId/contacts/:contactId
Response:
{
"contact": {
"id": 1,
"workspace_id": 2,
"name": "Alice Martin",
"email": "alice@example.com",
"created_at": 1710000000,
"updated_at": 1711500000
}
}
The single-contact endpoint does not include event_count or last_seen_at. Use the list endpoint or events endpoint if you need that data.
Errors:
| Status | Error |
|---|---|
404 | Contact not found |
Get Contact Timeline
Returns the full activity history for a contact, ordered by most recent first. Any workspace member can view contact events.
GET /api/workspaces/:workspaceId/contacts/:contactId/events
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number (min 1) |
limit | integer | 50 | Items per page (1–100) |
Response:
{
"events": [
{
"id": 10,
"contact_id": 1,
"workspace_id": 2,
"event_type": "room_join",
"room_id": 5,
"room_name": "team-standup-1234",
"room_display_name": "Team Standup",
"booking_page_id": null,
"booking_page_title": null,
"booking_page_slug": null,
"metadata": null,
"created_at": 1711500000
},
{
"id": 8,
"contact_id": 1,
"workspace_id": 2,
"event_type": "booking",
"room_id": null,
"room_name": null,
"room_display_name": null,
"booking_page_id": 3,
"booking_page_title": "30-min Intro Call",
"booking_page_slug": "intro-call",
"metadata": null,
"created_at": 1711000000
}
],
"total": 2,
"page": 1,
"limit": 50
}
Errors:
| Status | Error |
|---|---|
404 | Contact not found |
Delete a Contact
Permanently deletes a contact and all associated events. Owner or admin only.
DELETE /api/workspaces/:workspaceId/contacts/:contactId
Response:
{ "ok": true }
Deleting a contact is permanent. All contact events are deleted via cascade.
Errors:
| Status | Error |
|---|---|
403 | Only owners and admins can delete contacts |
404 | Contact not found |
This endpoint records an audit log entry and fires a contact.deleted webhook event.
Webhook Events
| Event | When fired | Payload fields |
|---|---|---|
contact.deleted | After a contact is deleted | id, name, email |
See Webhooks for payload format and signature verification.