API Reference
Introduction
The Uplevel API gives you programmatic access to your workspace: contacts, deals, tasks, activities, listings, and webhooks.
https://api.uplevelre.comAuthentication
Authenticate every request with an API key, sent as a bearer token:
Create and manage keys in the dashboard under Settings → API Keys (workspace admins only). A key's secret is shown once at creation — store it somewhere safe. Keys can be scoped per resource (for example read_contacts or write_deals); a write scope always includes the matching read scope, and full_access grants everything.
Keep keys out of client-side code. If a key leaks, revoke it in Settings and create a new one.
Authorization: Bearer ul_live_…What a key can see
A key acts for the whole workspace, not for one teammate. Within its scopes it reads and changes every record in the workspace, including contacts a teammate keeps private in the dashboard. Records from other workspaces are never visible, and ids that belong to another workspace return 404. Give keys only to integrations you trust with all of the workspace's data, and choose the narrowest scopes that work.
Errors
The API uses conventional HTTP status codes and returns a consistent error envelope:
| Status | error.type | Meaning |
|---|---|---|
| 400 | invalid_request_error | Malformed request or invalid field. |
| 401 | authentication_error | Missing, revoked, or expired API key. |
| 403 | permission_error | The key lacks a scope, or the plan excludes the feature. |
| 404 | invalid_request_error | The requested object does not exist. |
| 415 | invalid_request_error | The request has a body but no Content-Type: application/json header. |
| 429 | rate_limit_error | Rate limit exceeded — see Retry-After. |
| 5xx | api_error | Something failed on our side. Safe to retry with backoff. |
{
"error": {
"type": "invalid_request_error",
"message": "First and last name are required",
"param": "first_name"
}
}Pagination
List endpoints return at most 100 objects per call and share one envelope:
Pass next_cursor back as ?cursor= to fetch the following page. Results are ordered newest-first.
Send each query parameter once. A request that repeats a parameter (for example ?limit=10&limit=100) returns 400 rather than choosing one of the values.
{ "data": [ … ], "has_more": true, "next_cursor": "…", "total_count": 128 }Rate limits
Requests are limited per workspace (all keys combined), 120 requests per minute by default. Every response reports the window state in X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (Unix seconds); a rejected request returns 429 with Retry-After in seconds. Need a higher limit? Contact support.
Webhooks
Webhooks push JSON events to your servers as data changes in the workspace — no polling. Register endpoints in the dashboard under Settings → Webhooks, or with the webhook endpoints; each endpoint subscribes to the event types it cares about, or * for everything. Endpoints must use https://.
Verifying an endpoint
A new endpoint receives nothing until you prove you control it. Click Verify in Settings → Webhooks, or call POST /v1/webhooks/{webhook_id}/verify: Uplevel POSTs a signed webhook.verification event whose data.challenge is a random value, and the endpoint is verified when it answers with a 2xx status and that value in the response body.
Changing an endpoint's address clears its verification; verify it again.
Every delivery is an HTTP POST with the same JSON envelope: the event's id (stable across retries and endpoints), its type, created_at, and the object itself in data — the same shape the corresponding GET endpoint returns (deletion events carry only the object's id).
Each request carries these headers:
| Header | Value |
|---|---|
X-Uplevel-Event | The event type, e.g. contact.created. |
X-Uplevel-Event-Id | The event id, shared by every endpoint the event fanned out to. |
X-Uplevel-Delivery-Id | Unique per endpoint and event; constant across retries — deduplicate on it. |
X-Uplevel-Signature | t=<unix seconds>,v1=<hex HMAC-SHA256> — see Verifying deliveries. |
Respond with any 2xx status within 10 seconds to acknowledge receipt. A failed attempt (any other status, or a timeout) is retried up to 5 times with exponential backoff, and an endpoint that fails 20 consecutive attempts is disabled automatically — re-enable it in Settings → Webhooks, where Send test also delivers an on-demand ping event through the full pipeline to a verified endpoint.
if (event.type === "webhook.verification") {
return res.json({ challenge: event.data.challenge });
}{
"id": "evt_1f8b4c9d2e0a4b7f9c3d5e6f7a8b9c0d",
"type": "contact.created",
"created_at": "2026-07-02T16:20:00Z",
"data": {
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"first_name": "Dana",
"last_name": "Alvarez",
"email": "dana@example.com",
"stage": { "id": "…", "name": "New Lead" }
}
}Verifying deliveries
Verify the X-Uplevel-Signature header to confirm a delivery came from Uplevel and was not modified in transit. The signing key is the endpoint's whsec_… secret, verbatim: it is shown once when the endpoint is created, in the dashboard or by POST /v1/webhooks, and again whenever you rotate it in Settings → Webhooks.
An endpoint created in the dashboard before secrets were generated still signs with its code word: the key is the 64-character lowercase hex SHA-256 digest of the code word. Rotate its secret in Settings → Webhooks to move it to a whsec_… secret.
Automation Send webhook steps sign the same way, with the workspace's automation signing secret (reveal it in Settings → Webhooks), and post only to addresses verified in the step.
Split the header into t (Unix seconds) and v1 (hex HMAC). Recompute HMAC-SHA256 over the string "<t>.<raw request body>" with your signing key and compare it to v1 in constant time. The timestamp is part of what is signed, so it can't be changed without breaking the signature: reject any delivery whose t is more than 5 minutes from your clock, so a captured request can't be replayed. Uplevel signs each attempt when it is sent, so retries carry a fresh t.
import { createHmac, timingSafeEqual } from "node:crypto";
const key = process.env.UPLEVEL_WEBHOOK_SECRET; // whsec_…
function verify(signatureHeader, rawBody) {
const { t, v1 } = Object.fromEntries(
signatureHeader.split(",").map((part) => part.split("=")),
);
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false; // stale
const expected = createHmac("sha256", key).update(`${t}.${rawBody}`).digest();
return timingSafeEqual(expected, Buffer.from(v1, "hex"));
}Retrieve the calling key
GET/v1/me
Returns the workspace, scopes, and rate limit associated with the API key that made the request. Use it to verify a key is configured correctly.
Returns
200The calling key's identity.401Missing or invalid API key.Response attributes
workspaceobjectrequiredWorkspace the key belongs to.
Show child attributesHide child attributes
idstringrequirednamestringrequiredslugstringrequiredapi_keyobjectrequiredThe key itself (never the secret).
Show child attributesHide child attributes
idstringrequiredkey_prefixstringrequiredIdentifying fragment of the secret, as shown in Settings.
scopesarray of stringsrequiredScopes granted to this key.
rate_limit_per_minuteintegerrequiredRequests per minute this workspace may make, across all keys.
curl "https://api.uplevelre.com/v1/me" \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"workspace": {
"id": "b7a8cbb5-6a5e-4b52-9d0e-2a4dbb9b61a4",
"name": "Acme Realty",
"slug": "acme-realty"
},
"api_key": {
"id": "f3b1c2d4-8f0a-4f1b-a2c3-d4e5f6a7b8c9",
"key_prefix": "ul_live_1a2b3c4d",
"scopes": [
"READ_CONTACTS",
"WRITE_CONTACTS"
]
},
"rate_limit_per_minute": 120
}Contacts
People in your CRM: leads, clients, and past clients. Contacts carry addresses, stages, sources, tags, assigned teammates, and custom fields.
List contacts
GET/v1/contacts
Returns the workspace's contacts, newest first. All filters combine with AND.
Query parameters
limitintegerObjects per page, 1–100.
cursorstringOpaque cursor from a previous response's next_cursor; returns results strictly after it.
qstringFree-text search over name, email, phone, and company.
stage_idstringOnly contacts in this stage (see /v1/contact-stages).
lead_source_idstringOnly contacts from this lead source (see /v1/lead-sources).
owner_idstringOnly contacts assigned to this member (see /v1/members).
tag_idstringOnly contacts carrying this tag (see /v1/tags).
emailstringOnly contacts with this exact email.
created_aftertimestampOnly contacts created at or after this RFC 3339 timestamp.
created_beforetimestampOnly contacts created at or before this RFC 3339 timestamp.
updated_aftertimestampOnly contacts updated at or after this RFC 3339 timestamp — useful for incremental syncs.
Returns
200One page of contacts.401Missing or invalid API key.403The key lacks the read_contacts scope.Response attributes
dataarray of objectsrequiredShow child attributesHide child attributes
idstringrequiredfirst_namestringrequiredlast_namestringrequiredemailnullable stringrequiredphonenullable stringrequiredemailsarray of objectsrequiredEvery ordered email address; email above remains the primary shortcut.
Show child attributesHide child attributes
idstringrequiredvaluestringrequiredlabelstringrequiredHome | Work | Other
is_primarybooleanrequiredpositionintegerrequiredphonesarray of objectsrequiredEvery ordered phone number; phone above remains the primary shortcut.
Show child attributesHide child attributes
idstringrequiredvaluestringrequiredlabelstringrequiredMobile | Home | Work | Fax | Other
is_primarybooleanrequiredpositionintegerrequiredaddressnullable stringrequiredcitynullable stringrequiredstatenullable stringrequiredzip_codenullable stringrequiredcompanynullable stringrequiredjob_titlenullable stringrequirednotesnullable stringrequiredFree-form notes shown on the contact record.
stagenullable objectrequiredPipeline stage of the contact, from /v1/contact-stages.
Show child attributesHide child attributes
idstringrequirednamestringrequiredlead_sourcenullable objectrequiredWhere the contact came from, from /v1/lead-sources.
Show child attributesHide child attributes
idstringrequirednamestringrequiredownernullable objectrequiredTeam member the contact is assigned to.
Show child attributesHide child attributes
idstringrequirednamestringrequiredtagsarray of objectsrequiredWorkspace tags on the contact.
Show child attributesHide child attributes
idstringrequirednamestringrequiredcolornullable stringrequiredcustom_fieldsobjectrequiredValues for the workspace's custom fields, keyed by field id.
created_attimestamprequiredupdated_attimestamprequiredlast_activity_atnullable timestamprequiredLast time an activity touched this contact.
has_morebooleanrequiredWhether another page exists after this one.
next_cursornullable stringPass as ?cursor= to fetch the next page. Left out on the last page.
total_countintegerrequiredTotal objects matching the query across all pages.
curl "https://api.uplevelre.com/v1/contacts?limit=25&q=dana" \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"data": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"first_name": "Dana",
"last_name": "Whitaker",
"email": "dana@example.com",
"phone": "+12065550123",
"emails": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"value": "…",
"label": "…",
"is_primary": true,
"position": 0
}
],
"phones": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"value": "…",
"label": "…",
"is_primary": true,
"position": 0
}
],
"address": null,
"city": null,
"state": null,
"zip_code": null,
"company": null,
"job_title": null,
"notes": null,
"stage": null,
"lead_source": null,
"owner": null,
"tags": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Buyer",
"color": "#26c2e7"
}
],
"custom_fields": {},
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z",
"last_activity_at": null
}
],
"has_more": true,
"next_cursor": null,
"total_count": 42
}Create a contact
POST/v1/contacts
Adds a person to the CRM. Automations subscribed to contact created and webhooks subscribed to contact.created fire as if the contact had been added in the dashboard.
Body parameters
first_namestringrequiredlast_namestringrequiredemailnullable stringphonenullable stringemailsnullable array of objectsFull email list. When omitted, email becomes the sole primary row.
Show child attributesHide child attributes
valuestringrequiredlabelstringrequiredHome | Work | Other
idnullable stringId of an existing row to keep; leave it out for a new one.
is_primarynullable booleanpositionnullable integerphonesnullable array of objectsFull phone list. When omitted, phone becomes the sole primary row.
Show child attributesHide child attributes
valuestringrequiredlabelstringrequiredMobile | Home | Work | Fax | Other
idnullable stringId of an existing row to keep; leave it out for a new one.
is_primarynullable booleanpositionnullable integeraddressnullable stringcitynullable stringstatenullable stringzip_codenullable stringcompanynullable stringjob_titlenullable stringnotesnullable stringstage_idnullable stringStage id from /v1/contact-stages.
lead_source_idnullable stringLead source id from /v1/lead-sources.
owner_idnullable stringMember id from /v1/members to assign the contact to. Omit to leave the contact unassigned.
custom_fieldsnullable objectValues for custom fields, keyed by field id.
Returns
201The created contact.400A field failed validation.401Missing or invalid API key.403The key lacks the write_contacts scope.Response attributes
idstringrequiredfirst_namestringrequiredlast_namestringrequiredemailnullable stringrequiredphonenullable stringrequiredemailsarray of objectsrequiredEvery ordered email address; email above remains the primary shortcut.
Show child attributesHide child attributes
idstringrequiredvaluestringrequiredlabelstringrequiredHome | Work | Other
is_primarybooleanrequiredpositionintegerrequiredphonesarray of objectsrequiredEvery ordered phone number; phone above remains the primary shortcut.
Show child attributesHide child attributes
idstringrequiredvaluestringrequiredlabelstringrequiredMobile | Home | Work | Fax | Other
is_primarybooleanrequiredpositionintegerrequiredaddressnullable stringrequiredcitynullable stringrequiredstatenullable stringrequiredzip_codenullable stringrequiredcompanynullable stringrequiredjob_titlenullable stringrequirednotesnullable stringrequiredFree-form notes shown on the contact record.
stagenullable objectrequiredPipeline stage of the contact, from /v1/contact-stages.
Show child attributesHide child attributes
idstringrequirednamestringrequiredlead_sourcenullable objectrequiredWhere the contact came from, from /v1/lead-sources.
Show child attributesHide child attributes
idstringrequirednamestringrequiredownernullable objectrequiredTeam member the contact is assigned to.
Show child attributesHide child attributes
idstringrequirednamestringrequiredtagsarray of objectsrequiredWorkspace tags on the contact.
Show child attributesHide child attributes
idstringrequirednamestringrequiredcolornullable stringrequiredcustom_fieldsobjectrequiredValues for the workspace's custom fields, keyed by field id.
created_attimestamprequiredupdated_attimestamprequiredlast_activity_atnullable timestamprequiredLast time an activity touched this contact.
curl "https://api.uplevelre.com/v1/contacts" \
-H "Authorization: Bearer $UPLEVEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"first_name": "Dana",
"last_name": "Whitaker",
"email": "dana@example.com",
"phone": "+12065550123"
}'{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"first_name": "Dana",
"last_name": "Whitaker",
"email": "dana@example.com",
"phone": "+12065550123",
"emails": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"value": "…",
"label": "…",
"is_primary": true,
"position": 0
}
],
"phones": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"value": "…",
"label": "…",
"is_primary": true,
"position": 0
}
],
"address": null,
"city": null,
"state": null,
"zip_code": null,
"company": null,
"job_title": null,
"notes": null,
"stage": null,
"lead_source": null,
"owner": null,
"tags": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Buyer",
"color": "#26c2e7"
}
],
"custom_fields": {},
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z",
"last_activity_at": null
}Retrieve a contact
GET/v1/contacts/{contact_id}
Path parameters
contact_idstringrequiredId of the contact.
Returns
200The contact.401Missing or invalid API key.404No contact with that id.Response attributes
idstringrequiredfirst_namestringrequiredlast_namestringrequiredemailnullable stringrequiredphonenullable stringrequiredemailsarray of objectsrequiredEvery ordered email address; email above remains the primary shortcut.
Show child attributesHide child attributes
idstringrequiredvaluestringrequiredlabelstringrequiredHome | Work | Other
is_primarybooleanrequiredpositionintegerrequiredphonesarray of objectsrequiredEvery ordered phone number; phone above remains the primary shortcut.
Show child attributesHide child attributes
idstringrequiredvaluestringrequiredlabelstringrequiredMobile | Home | Work | Fax | Other
is_primarybooleanrequiredpositionintegerrequiredaddressnullable stringrequiredcitynullable stringrequiredstatenullable stringrequiredzip_codenullable stringrequiredcompanynullable stringrequiredjob_titlenullable stringrequirednotesnullable stringrequiredFree-form notes shown on the contact record.
stagenullable objectrequiredPipeline stage of the contact, from /v1/contact-stages.
Show child attributesHide child attributes
idstringrequirednamestringrequiredlead_sourcenullable objectrequiredWhere the contact came from, from /v1/lead-sources.
Show child attributesHide child attributes
idstringrequirednamestringrequiredownernullable objectrequiredTeam member the contact is assigned to.
Show child attributesHide child attributes
idstringrequirednamestringrequiredtagsarray of objectsrequiredWorkspace tags on the contact.
Show child attributesHide child attributes
idstringrequirednamestringrequiredcolornullable stringrequiredcustom_fieldsobjectrequiredValues for the workspace's custom fields, keyed by field id.
created_attimestamprequiredupdated_attimestamprequiredlast_activity_atnullable timestamprequiredLast time an activity touched this contact.
curl "https://api.uplevelre.com/v1/contacts/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"first_name": "Dana",
"last_name": "Whitaker",
"email": "dana@example.com",
"phone": "+12065550123",
"emails": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"value": "…",
"label": "…",
"is_primary": true,
"position": 0
}
],
"phones": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"value": "…",
"label": "…",
"is_primary": true,
"position": 0
}
],
"address": null,
"city": null,
"state": null,
"zip_code": null,
"company": null,
"job_title": null,
"notes": null,
"stage": null,
"lead_source": null,
"owner": null,
"tags": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Buyer",
"color": "#26c2e7"
}
],
"custom_fields": {},
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z",
"last_activity_at": null
}Update a contact
PATCH/v1/contacts/{contact_id}
Partial update: only the fields present in the body change. Stage changes fire stage changed automations and contact.updated webhooks.
Path parameters
contact_idstringrequiredId of the contact.
Body parameters
first_namenullable stringlast_namenullable stringemailnullable stringphonenullable stringemailsnullable array of objectsReplaces the full email list when present.
Show child attributesHide child attributes
valuestringrequiredlabelstringrequiredHome | Work | Other
idnullable stringId of an existing row to keep; leave it out for a new one.
is_primarynullable booleanpositionnullable integerphonesnullable array of objectsReplaces the full phone list when present.
Show child attributesHide child attributes
valuestringrequiredlabelstringrequiredMobile | Home | Work | Fax | Other
idnullable stringId of an existing row to keep; leave it out for a new one.
is_primarynullable booleanpositionnullable integeraddressnullable stringcitynullable stringstatenullable stringzip_codenullable stringcompanynullable stringjob_titlenullable stringnotesnullable stringstage_idnullable stringStage id from /v1/contact-stages; empty string clears the stage.
lead_source_idnullable stringLead source id from /v1/lead-sources; empty string clears it.
owner_idnullable stringMember id from /v1/members; empty string unassigns the contact.
custom_fieldsnullable objectReplaces custom field values wholesale when provided.
Returns
200The updated contact.400A field failed validation.401Missing or invalid API key.404No contact with that id.Response attributes
idstringrequiredfirst_namestringrequiredlast_namestringrequiredemailnullable stringrequiredphonenullable stringrequiredemailsarray of objectsrequiredEvery ordered email address; email above remains the primary shortcut.
Show child attributesHide child attributes
idstringrequiredvaluestringrequiredlabelstringrequiredHome | Work | Other
is_primarybooleanrequiredpositionintegerrequiredphonesarray of objectsrequiredEvery ordered phone number; phone above remains the primary shortcut.
Show child attributesHide child attributes
idstringrequiredvaluestringrequiredlabelstringrequiredMobile | Home | Work | Fax | Other
is_primarybooleanrequiredpositionintegerrequiredaddressnullable stringrequiredcitynullable stringrequiredstatenullable stringrequiredzip_codenullable stringrequiredcompanynullable stringrequiredjob_titlenullable stringrequirednotesnullable stringrequiredFree-form notes shown on the contact record.
stagenullable objectrequiredPipeline stage of the contact, from /v1/contact-stages.
Show child attributesHide child attributes
idstringrequirednamestringrequiredlead_sourcenullable objectrequiredWhere the contact came from, from /v1/lead-sources.
Show child attributesHide child attributes
idstringrequirednamestringrequiredownernullable objectrequiredTeam member the contact is assigned to.
Show child attributesHide child attributes
idstringrequirednamestringrequiredtagsarray of objectsrequiredWorkspace tags on the contact.
Show child attributesHide child attributes
idstringrequirednamestringrequiredcolornullable stringrequiredcustom_fieldsobjectrequiredValues for the workspace's custom fields, keyed by field id.
created_attimestamprequiredupdated_attimestamprequiredlast_activity_atnullable timestamprequiredLast time an activity touched this contact.
curl "https://api.uplevelre.com/v1/contacts/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
-X PATCH \
-H "Authorization: Bearer $UPLEVEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"first_name": "…",
"last_name": "…",
"email": "dana@example.com"
}'{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"first_name": "Dana",
"last_name": "Whitaker",
"email": "dana@example.com",
"phone": "+12065550123",
"emails": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"value": "…",
"label": "…",
"is_primary": true,
"position": 0
}
],
"phones": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"value": "…",
"label": "…",
"is_primary": true,
"position": 0
}
],
"address": null,
"city": null,
"state": null,
"zip_code": null,
"company": null,
"job_title": null,
"notes": null,
"stage": null,
"lead_source": null,
"owner": null,
"tags": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Buyer",
"color": "#26c2e7"
}
],
"custom_fields": {},
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z",
"last_activity_at": null
}Delete a contact
DELETE/v1/contacts/{contact_id}
Permanently removes the contact, its timeline, and its texts, emails, call transcripts, voicemails, lead emails and website history. Opt-outs are kept, so the person stays unsubscribed if they are added again. This cannot be undone.
Path parameters
contact_idstringrequiredId of the contact.
Returns
200Deletion confirmation.401Missing or invalid API key.404No contact with that id.Response attributes
idstringrequiredId of the deleted object.
deletedbooleanrequiredcurl "https://api.uplevelre.com/v1/contacts/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
-X DELETE \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"deleted": true
}Add a tag to a contact
PUT/v1/contacts/{contact_id}/tags/{tag_id}
Tags must already exist as workspace tags — see /v1/tags. Adding a tag the contact already has is a no-op.
Path parameters
contact_idstringrequiredId of the contact.
tag_idstringrequiredId of the workspace tag.
Returns
200The contact with the tag applied.401Missing or invalid API key.404No such contact or tag.Response attributes
idstringrequiredfirst_namestringrequiredlast_namestringrequiredemailnullable stringrequiredphonenullable stringrequiredemailsarray of objectsrequiredEvery ordered email address; email above remains the primary shortcut.
Show child attributesHide child attributes
idstringrequiredvaluestringrequiredlabelstringrequiredHome | Work | Other
is_primarybooleanrequiredpositionintegerrequiredphonesarray of objectsrequiredEvery ordered phone number; phone above remains the primary shortcut.
Show child attributesHide child attributes
idstringrequiredvaluestringrequiredlabelstringrequiredMobile | Home | Work | Fax | Other
is_primarybooleanrequiredpositionintegerrequiredaddressnullable stringrequiredcitynullable stringrequiredstatenullable stringrequiredzip_codenullable stringrequiredcompanynullable stringrequiredjob_titlenullable stringrequirednotesnullable stringrequiredFree-form notes shown on the contact record.
stagenullable objectrequiredPipeline stage of the contact, from /v1/contact-stages.
Show child attributesHide child attributes
idstringrequirednamestringrequiredlead_sourcenullable objectrequiredWhere the contact came from, from /v1/lead-sources.
Show child attributesHide child attributes
idstringrequirednamestringrequiredownernullable objectrequiredTeam member the contact is assigned to.
Show child attributesHide child attributes
idstringrequirednamestringrequiredtagsarray of objectsrequiredWorkspace tags on the contact.
Show child attributesHide child attributes
idstringrequirednamestringrequiredcolornullable stringrequiredcustom_fieldsobjectrequiredValues for the workspace's custom fields, keyed by field id.
created_attimestamprequiredupdated_attimestamprequiredlast_activity_atnullable timestamprequiredLast time an activity touched this contact.
curl "https://api.uplevelre.com/v1/contacts/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21/tags/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
-X PUT \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"first_name": "Dana",
"last_name": "Whitaker",
"email": "dana@example.com",
"phone": "+12065550123",
"emails": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"value": "…",
"label": "…",
"is_primary": true,
"position": 0
}
],
"phones": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"value": "…",
"label": "…",
"is_primary": true,
"position": 0
}
],
"address": null,
"city": null,
"state": null,
"zip_code": null,
"company": null,
"job_title": null,
"notes": null,
"stage": null,
"lead_source": null,
"owner": null,
"tags": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Buyer",
"color": "#26c2e7"
}
],
"custom_fields": {},
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z",
"last_activity_at": null
}Remove a tag from a contact
DELETE/v1/contacts/{contact_id}/tags/{tag_id}
Path parameters
contact_idstringrequiredId of the contact.
tag_idstringrequiredId of the workspace tag.
Returns
200The contact with the tag removed.401Missing or invalid API key.404No such contact.Response attributes
idstringrequiredfirst_namestringrequiredlast_namestringrequiredemailnullable stringrequiredphonenullable stringrequiredemailsarray of objectsrequiredEvery ordered email address; email above remains the primary shortcut.
Show child attributesHide child attributes
idstringrequiredvaluestringrequiredlabelstringrequiredHome | Work | Other
is_primarybooleanrequiredpositionintegerrequiredphonesarray of objectsrequiredEvery ordered phone number; phone above remains the primary shortcut.
Show child attributesHide child attributes
idstringrequiredvaluestringrequiredlabelstringrequiredMobile | Home | Work | Fax | Other
is_primarybooleanrequiredpositionintegerrequiredaddressnullable stringrequiredcitynullable stringrequiredstatenullable stringrequiredzip_codenullable stringrequiredcompanynullable stringrequiredjob_titlenullable stringrequirednotesnullable stringrequiredFree-form notes shown on the contact record.
stagenullable objectrequiredPipeline stage of the contact, from /v1/contact-stages.
Show child attributesHide child attributes
idstringrequirednamestringrequiredlead_sourcenullable objectrequiredWhere the contact came from, from /v1/lead-sources.
Show child attributesHide child attributes
idstringrequirednamestringrequiredownernullable objectrequiredTeam member the contact is assigned to.
Show child attributesHide child attributes
idstringrequirednamestringrequiredtagsarray of objectsrequiredWorkspace tags on the contact.
Show child attributesHide child attributes
idstringrequirednamestringrequiredcolornullable stringrequiredcustom_fieldsobjectrequiredValues for the workspace's custom fields, keyed by field id.
created_attimestamprequiredupdated_attimestamprequiredlast_activity_atnullable timestamprequiredLast time an activity touched this contact.
curl "https://api.uplevelre.com/v1/contacts/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21/tags/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
-X DELETE \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"first_name": "Dana",
"last_name": "Whitaker",
"email": "dana@example.com",
"phone": "+12065550123",
"emails": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"value": "…",
"label": "…",
"is_primary": true,
"position": 0
}
],
"phones": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"value": "…",
"label": "…",
"is_primary": true,
"position": 0
}
],
"address": null,
"city": null,
"state": null,
"zip_code": null,
"company": null,
"job_title": null,
"notes": null,
"stage": null,
"lead_source": null,
"owner": null,
"tags": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Buyer",
"color": "#26c2e7"
}
],
"custom_fields": {},
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z",
"last_activity_at": null
}Activities
The timeline on a contact: notes, calls, emails, and system events. Notes can be created through the API; the rest of the timeline is read-only.
List a contact's activities
GET/v1/contacts/{contact_id}/activities
Returns the contact's timeline, newest first. Private notes are excluded. Email synced from a mailbox its owner keeps private reads as "Private email exchange", with no description, details or actor, unless the team member who created the API key owns that mailbox.
Path parameters
contact_idstringrequiredId of the contact.
Query parameters
limitintegerObjects per page, 1–100.
cursorstringOpaque cursor from a previous response's next_cursor; returns results strictly after it.
Returns
200One page of activities.401Missing or invalid API key.404No contact with that id.Response attributes
dataarray of objectsrequiredShow child attributesHide child attributes
idstringrequiredtypestringrequiredKind of entry: note, call, email, contact_created, contact_updated, stage_changed, owner_changed, and similar system types.
titlestringrequireddescriptionnullable stringrequiredmetadatanullable objectrequiredEntry-specific details (for example the fields an update changed).
actor_namenullable stringrequiredTeam member who performed the action; null for automated entries and API writes.
created_attimestamprequiredhas_morebooleanrequiredWhether another page exists after this one.
next_cursornullable stringPass as ?cursor= to fetch the next page. Left out on the last page.
total_countintegerrequiredTotal objects matching the query across all pages.
curl "https://api.uplevelre.com/v1/contacts/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21/activities?limit=25" \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"data": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"type": "note",
"title": "Note added",
"description": null,
"metadata": null,
"actor_name": null,
"created_at": "2026-07-02T16:20:00Z"
}
],
"has_more": true,
"next_cursor": null,
"total_count": 42
}Add a note to a contact
POST/v1/contacts/{contact_id}/notes
Appends a note to the contact's timeline and updates the contact's last-activity time.
Path parameters
contact_idstringrequiredId of the contact.
Body parameters
bodystringrequiredThe note text, up to 10,000 characters.
Returns
201The created note.400The note is empty or too long.401Missing or invalid API key.404No contact with that id.Response attributes
idstringrequiredtypestringrequiredKind of entry: note, call, email, contact_created, contact_updated, stage_changed, owner_changed, and similar system types.
titlestringrequireddescriptionnullable stringrequiredmetadatanullable objectrequiredEntry-specific details (for example the fields an update changed).
actor_namenullable stringrequiredTeam member who performed the action; null for automated entries and API writes.
created_attimestamprequiredcurl "https://api.uplevelre.com/v1/contacts/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21/notes" \
-H "Authorization: Bearer $UPLEVEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"body": "Spoke on the phone — wants to tour 3BR homes in Ballard this weekend."
}'{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"type": "note",
"title": "Note added",
"description": null,
"metadata": null,
"actor_name": null,
"created_at": "2026-07-02T16:20:00Z"
}Transactions
Closing workflows, milestones, commission and actual revenue. Won deals count contracts; closed transactions count revenue.
List transactions
GET/v1/transactions
Returns the workspace's transactions with counts per semantic status. Pages by offset: advance offset by the number returned.
Query parameters
statusstringOnly transactions with this status: active, pending, closed, or fell_through.
sidestringOnly transactions on this side: buyer, seller, or both.
searchstringCase-insensitive match against the name, listing label, or contact name.
contact_idstringOnly transactions linked to this contact.
deal_idstringOnly transactions linked to this deal.
stage_idstringOnly transactions in this closing stage.
closing_fromstringOnly transactions projected or actually closing on or after this YYYY-MM-DD date.
closing_tostringOnly transactions projected or actually closing on or before this YYYY-MM-DD date.
limitintegerTransactions per page, up to 200. Leave it out for the default.
offsetintegerMatching transactions to skip; advance it by the number returned.
Returns
200Matching transactions in data, with semantic status counts. Up to 200 records per page; advance offset by the number returned.400A query parameter is not a 32-bit integer.401Missing or invalid API key.403The key lacks the read_transactions scope.Response attributes
countsobjectrequiredTransactions per semantic status across every match, ignoring paging. Counts are 64-bit integers encoded as strings.
Show child attributesHide child attributes
activestringrequiredclosedstringrequiredfell_throughstringrequiredpendingstringrequireddataarray of objectsrequiredShow child attributesHide child attributes
actual_close_datestringrequiredClosing date, YYYY-MM-DD; set when the transaction closes.
appraisal_datestringrequiredAppraisal deadline, YYYY-MM-DD; empty when not set.
brokerage_split_ratestringrequiredBrokerage split as a percent of GCI after the referral fee.
commission_ratestringrequiredCommission rate as a percent, e.g. 3.00.
contact_emailstringrequiredcontact_first_namestringrequiredcontact_idstringrequiredLinked contact; empty when there is none.
contact_last_namestringrequiredcontract_datestringrequiredContract date, YYYY-MM-DD; empty when not set.
created_attimestamprequireddeal_idstringrequiredLinked deal; empty when there is none.
deal_namestringrequireddeal_statusstringrequiredThe linked deal's open, won, or lost status.
document_countintegerrequiredNumber of documents stored on the transaction.
earnest_money_due_datestringrequiredEarnest money deadline, YYYY-MM-DD; empty when not set.
fell_through_reasonstringrequiredWhy the transaction fell through; empty otherwise.
financing_datestringrequiredFinancing deadline, YYYY-MM-DD; empty when not set.
gci_overridebooleanrequiredWhether gross_commission was entered directly instead of derived.
gross_commissionstringrequiredGross commission income, as a decimal string. Derived from sale_price × commission_rate unless gci_override is set.
idstringrequiredinspection_datestringrequiredInspection deadline, YYYY-MM-DD; empty when not set.
listing_keystringrequiredMLS listing key; empty unless the property is an MLS listing.
listing_labelstringrequiredThe property's address or label.
listing_photo_pathstringrequiredPath to the property's primary photo; empty when there is none.
namestringrequirednet_commissionstringrequiredWhat the agent keeps, as a decimal string: (GCI − referral fee) × (1 − brokerage split − team split) − transaction fees. Always derived.
notesstringrequiredpossession_datestringrequiredPossession date, YYYY-MM-DD; empty when not set.
projected_close_datestringrequiredExpected closing date, YYYY-MM-DD; empty when not set.
referral_feestringrequiredReferral fee taken off the top, as a decimal string.
sale_pricestringrequiredSale price, as a decimal string.
sidestringrequiredbuyer, seller, or both.
stage_idstringrequiredClosing stage the transaction sits in.
stage_namestringrequiredstatusstringrequiredactive, pending, closed, or fell_through, from the closing stage the transaction sits in.
team_split_ratestringrequiredTeam split as a percent of GCI after the referral fee.
transaction_feesstringrequiredFlat transaction fees, as a decimal string.
updated_attimestamprequiredwalkthrough_datestringrequiredFinal walkthrough, YYYY-MM-DD; empty when not set.
curl "https://api.uplevelre.com/v1/transactions" \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"counts": {
"active": "4",
"closed": "17",
"fell_through": "1",
"pending": "2"
},
"data": [
{
"actual_close_date": "2026-09-15",
"appraisal_date": "…",
"brokerage_split_rate": "20.00",
"commission_rate": "3.00",
"contact_email": "dana@example.com",
"contact_first_name": "Dana",
"contact_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"contact_last_name": "Whitaker",
"contract_date": "…",
"created_at": "2026-07-02T16:20:00Z",
"deal_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"deal_name": "…",
"deal_status": "…",
"document_count": 0,
"earnest_money_due_date": "…",
"fell_through_reason": "…",
"financing_date": "…",
"gci_override": true,
"gross_commission": "21750.00",
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"inspection_date": "…",
"listing_key": "…",
"listing_label": "1420 Terry Ave #1903",
"listing_photo_path": "…",
"name": "1420 Terry Ave — Whitaker purchase",
"net_commission": "…",
"notes": "…",
"possession_date": "…",
"projected_close_date": "…",
"referral_fee": "…",
"sale_price": "725000.00",
"side": "buyer",
"stage_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"stage_name": "Under contract",
"status": "pending",
"team_split_rate": "…",
"transaction_fees": "…",
"updated_at": "2026-07-02T16:20:00Z",
"walkthrough_date": "…"
}
]
}Create a transaction
POST/v1/transactions
Opens a transaction. Money is decimal strings; dates are YYYY-MM-DD.
Body parameters
namenullable stringLeave empty to name it after the listing, the deal, or the contact.
sidenullable stringbuyer, seller, or both. Defaults to buyer.
statusnullable stringactive, pending, closed, or fell_through. Defaults to active.
deal_idnullable stringDeal to link (see /v1/deals).
contact_idnullable stringContact to link (see /v1/contacts).
listing_keynullable stringMLS listing key of the property.
sale_pricenullable stringcommission_ratenullable stringPercent, e.g. 3.00.
projected_close_datenullable stringnotesnullable stringstage_idnullable stringClosing stage to start in (see /v1/transaction-settings).
checklist_template_idnullable stringChecklist template to apply (see /v1/transaction-settings).
idempotency_keynullable stringReuse the same key to retry one creation safely.
Returns
200The created transaction.400A field failed validation.401Missing or invalid API key.403The key lacks the write_transactions scope.Response attributes
actual_close_datestringrequiredClosing date, YYYY-MM-DD; set when the transaction closes.
appraisal_datestringrequiredAppraisal deadline, YYYY-MM-DD; empty when not set.
brokerage_split_ratestringrequiredBrokerage split as a percent of GCI after the referral fee.
commission_ratestringrequiredCommission rate as a percent, e.g. 3.00.
contact_emailstringrequiredcontact_first_namestringrequiredcontact_idstringrequiredLinked contact; empty when there is none.
contact_last_namestringrequiredcontract_datestringrequiredContract date, YYYY-MM-DD; empty when not set.
created_attimestamprequireddeal_idstringrequiredLinked deal; empty when there is none.
deal_namestringrequireddeal_statusstringrequiredThe linked deal's open, won, or lost status.
document_countintegerrequiredNumber of documents stored on the transaction.
earnest_money_due_datestringrequiredEarnest money deadline, YYYY-MM-DD; empty when not set.
fell_through_reasonstringrequiredWhy the transaction fell through; empty otherwise.
financing_datestringrequiredFinancing deadline, YYYY-MM-DD; empty when not set.
gci_overridebooleanrequiredWhether gross_commission was entered directly instead of derived.
gross_commissionstringrequiredGross commission income, as a decimal string. Derived from sale_price × commission_rate unless gci_override is set.
idstringrequiredinspection_datestringrequiredInspection deadline, YYYY-MM-DD; empty when not set.
listing_keystringrequiredMLS listing key; empty unless the property is an MLS listing.
listing_labelstringrequiredThe property's address or label.
listing_photo_pathstringrequiredPath to the property's primary photo; empty when there is none.
namestringrequirednet_commissionstringrequiredWhat the agent keeps, as a decimal string: (GCI − referral fee) × (1 − brokerage split − team split) − transaction fees. Always derived.
notesstringrequiredpossession_datestringrequiredPossession date, YYYY-MM-DD; empty when not set.
projected_close_datestringrequiredExpected closing date, YYYY-MM-DD; empty when not set.
referral_feestringrequiredReferral fee taken off the top, as a decimal string.
sale_pricestringrequiredSale price, as a decimal string.
sidestringrequiredbuyer, seller, or both.
stage_idstringrequiredClosing stage the transaction sits in.
stage_namestringrequiredstatusstringrequiredactive, pending, closed, or fell_through, from the closing stage the transaction sits in.
team_split_ratestringrequiredTeam split as a percent of GCI after the referral fee.
transaction_feesstringrequiredFlat transaction fees, as a decimal string.
updated_attimestamprequiredwalkthrough_datestringrequiredFinal walkthrough, YYYY-MM-DD; empty when not set.
curl "https://api.uplevelre.com/v1/transactions" \
-H "Authorization: Bearer $UPLEVEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sale_price": "725000.00",
"commission_rate": "3.00",
"projected_close_date": "2026-09-30"
}'{
"actual_close_date": "2026-09-15",
"appraisal_date": "…",
"brokerage_split_rate": "20.00",
"commission_rate": "3.00",
"contact_email": "dana@example.com",
"contact_first_name": "Dana",
"contact_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"contact_last_name": "Whitaker",
"contract_date": "…",
"created_at": "2026-07-02T16:20:00Z",
"deal_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"deal_name": "…",
"deal_status": "…",
"document_count": 0,
"earnest_money_due_date": "…",
"fell_through_reason": "…",
"financing_date": "…",
"gci_override": true,
"gross_commission": "21750.00",
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"inspection_date": "…",
"listing_key": "…",
"listing_label": "1420 Terry Ave #1903",
"listing_photo_path": "…",
"name": "1420 Terry Ave — Whitaker purchase",
"net_commission": "…",
"notes": "…",
"possession_date": "…",
"projected_close_date": "…",
"referral_fee": "…",
"sale_price": "725000.00",
"side": "buyer",
"stage_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"stage_name": "Under contract",
"status": "pending",
"team_split_rate": "…",
"transaction_fees": "…",
"updated_at": "2026-07-02T16:20:00Z",
"walkthrough_date": "…"
}Retrieve a transaction
GET/v1/transactions/{id}
Path parameters
idstringrequiredTransaction ID
Returns
200Transaction with stage, financials, key dates and linked records.401Missing or invalid API key.404No transaction with that id.Response attributes
actual_close_datestringrequiredClosing date, YYYY-MM-DD; set when the transaction closes.
appraisal_datestringrequiredAppraisal deadline, YYYY-MM-DD; empty when not set.
brokerage_split_ratestringrequiredBrokerage split as a percent of GCI after the referral fee.
commission_ratestringrequiredCommission rate as a percent, e.g. 3.00.
contact_emailstringrequiredcontact_first_namestringrequiredcontact_idstringrequiredLinked contact; empty when there is none.
contact_last_namestringrequiredcontract_datestringrequiredContract date, YYYY-MM-DD; empty when not set.
created_attimestamprequireddeal_idstringrequiredLinked deal; empty when there is none.
deal_namestringrequireddeal_statusstringrequiredThe linked deal's open, won, or lost status.
document_countintegerrequiredNumber of documents stored on the transaction.
earnest_money_due_datestringrequiredEarnest money deadline, YYYY-MM-DD; empty when not set.
fell_through_reasonstringrequiredWhy the transaction fell through; empty otherwise.
financing_datestringrequiredFinancing deadline, YYYY-MM-DD; empty when not set.
gci_overridebooleanrequiredWhether gross_commission was entered directly instead of derived.
gross_commissionstringrequiredGross commission income, as a decimal string. Derived from sale_price × commission_rate unless gci_override is set.
idstringrequiredinspection_datestringrequiredInspection deadline, YYYY-MM-DD; empty when not set.
listing_keystringrequiredMLS listing key; empty unless the property is an MLS listing.
listing_labelstringrequiredThe property's address or label.
listing_photo_pathstringrequiredPath to the property's primary photo; empty when there is none.
namestringrequirednet_commissionstringrequiredWhat the agent keeps, as a decimal string: (GCI − referral fee) × (1 − brokerage split − team split) − transaction fees. Always derived.
notesstringrequiredpossession_datestringrequiredPossession date, YYYY-MM-DD; empty when not set.
projected_close_datestringrequiredExpected closing date, YYYY-MM-DD; empty when not set.
referral_feestringrequiredReferral fee taken off the top, as a decimal string.
sale_pricestringrequiredSale price, as a decimal string.
sidestringrequiredbuyer, seller, or both.
stage_idstringrequiredClosing stage the transaction sits in.
stage_namestringrequiredstatusstringrequiredactive, pending, closed, or fell_through, from the closing stage the transaction sits in.
team_split_ratestringrequiredTeam split as a percent of GCI after the referral fee.
transaction_feesstringrequiredFlat transaction fees, as a decimal string.
updated_attimestamprequiredwalkthrough_datestringrequiredFinal walkthrough, YYYY-MM-DD; empty when not set.
curl "https://api.uplevelre.com/v1/transactions/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"actual_close_date": "2026-09-15",
"appraisal_date": "…",
"brokerage_split_rate": "20.00",
"commission_rate": "3.00",
"contact_email": "dana@example.com",
"contact_first_name": "Dana",
"contact_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"contact_last_name": "Whitaker",
"contract_date": "…",
"created_at": "2026-07-02T16:20:00Z",
"deal_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"deal_name": "…",
"deal_status": "…",
"document_count": 0,
"earnest_money_due_date": "…",
"fell_through_reason": "…",
"financing_date": "…",
"gci_override": true,
"gross_commission": "21750.00",
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"inspection_date": "…",
"listing_key": "…",
"listing_label": "1420 Terry Ave #1903",
"listing_photo_path": "…",
"name": "1420 Terry Ave — Whitaker purchase",
"net_commission": "…",
"notes": "…",
"possession_date": "…",
"projected_close_date": "…",
"referral_fee": "…",
"sale_price": "725000.00",
"side": "buyer",
"stage_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"stage_name": "Under contract",
"status": "pending",
"team_split_rate": "…",
"transaction_fees": "…",
"updated_at": "2026-07-02T16:20:00Z",
"walkthrough_date": "…"
}Update a transaction
PATCH/v1/transactions/{id}
Partial update: only the fields present in the body change. Fell-through on a won deal requires deal_disposition (reopen, lost, leave_won), with reopen_stage_id for a selected open stage. No automatic deal changes; reopen and lost also need the write_deals scope.
Path parameters
idstringrequiredTransaction ID
Body parameters
namenullable stringsidenullable stringstatusnullable stringfell_through_reasonnullable stringdeal_idnullable stringDeal to link; empty string unlinks.
contact_idnullable stringContact to link; empty string unlinks.
listing_keynullable stringMLS listing key; empty string unlinks the property.
sale_pricenullable stringcommission_ratenullable stringgross_commissionnullable stringA value pins the gross commission (gci_override); an empty string derives it from sale_price × commission_rate again.
referral_feenullable stringbrokerage_split_ratenullable stringteam_split_ratenullable stringtransaction_feesnullable stringcontract_datenullable stringearnest_money_due_datenullable stringinspection_datenullable stringappraisal_datenullable stringfinancing_datenullable stringwalkthrough_datenullable stringprojected_close_datenullable stringactual_close_datenullable stringpossession_datenullable stringnotesnullable stringstage_idnullable stringClosing stage to move to (see /v1/transaction-settings).
deal_dispositionnullable stringRequired when a linked won deal's transaction falls through: reopen, lost, or leave_won. No deal changes without it.
reopen_stage_idnullable stringThe open deal stage to reopen the deal into, with reopen.
deal_lost_reasonnullable stringWhy the deal was lost, with lost.
Returns
200The updated transaction.400A field failed validation.401Missing or invalid API key.403The key lacks a scope the change needs.404No transaction with that id.Response attributes
actual_close_datestringrequiredClosing date, YYYY-MM-DD; set when the transaction closes.
appraisal_datestringrequiredAppraisal deadline, YYYY-MM-DD; empty when not set.
brokerage_split_ratestringrequiredBrokerage split as a percent of GCI after the referral fee.
commission_ratestringrequiredCommission rate as a percent, e.g. 3.00.
contact_emailstringrequiredcontact_first_namestringrequiredcontact_idstringrequiredLinked contact; empty when there is none.
contact_last_namestringrequiredcontract_datestringrequiredContract date, YYYY-MM-DD; empty when not set.
created_attimestamprequireddeal_idstringrequiredLinked deal; empty when there is none.
deal_namestringrequireddeal_statusstringrequiredThe linked deal's open, won, or lost status.
document_countintegerrequiredNumber of documents stored on the transaction.
earnest_money_due_datestringrequiredEarnest money deadline, YYYY-MM-DD; empty when not set.
fell_through_reasonstringrequiredWhy the transaction fell through; empty otherwise.
financing_datestringrequiredFinancing deadline, YYYY-MM-DD; empty when not set.
gci_overridebooleanrequiredWhether gross_commission was entered directly instead of derived.
gross_commissionstringrequiredGross commission income, as a decimal string. Derived from sale_price × commission_rate unless gci_override is set.
idstringrequiredinspection_datestringrequiredInspection deadline, YYYY-MM-DD; empty when not set.
listing_keystringrequiredMLS listing key; empty unless the property is an MLS listing.
listing_labelstringrequiredThe property's address or label.
listing_photo_pathstringrequiredPath to the property's primary photo; empty when there is none.
namestringrequirednet_commissionstringrequiredWhat the agent keeps, as a decimal string: (GCI − referral fee) × (1 − brokerage split − team split) − transaction fees. Always derived.
notesstringrequiredpossession_datestringrequiredPossession date, YYYY-MM-DD; empty when not set.
projected_close_datestringrequiredExpected closing date, YYYY-MM-DD; empty when not set.
referral_feestringrequiredReferral fee taken off the top, as a decimal string.
sale_pricestringrequiredSale price, as a decimal string.
sidestringrequiredbuyer, seller, or both.
stage_idstringrequiredClosing stage the transaction sits in.
stage_namestringrequiredstatusstringrequiredactive, pending, closed, or fell_through, from the closing stage the transaction sits in.
team_split_ratestringrequiredTeam split as a percent of GCI after the referral fee.
transaction_feesstringrequiredFlat transaction fees, as a decimal string.
updated_attimestamprequiredwalkthrough_datestringrequiredFinal walkthrough, YYYY-MM-DD; empty when not set.
curl "https://api.uplevelre.com/v1/transactions/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
-X PATCH \
-H "Authorization: Bearer $UPLEVEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "…",
"side": "…",
"status": "…"
}'{
"actual_close_date": "2026-09-15",
"appraisal_date": "…",
"brokerage_split_rate": "20.00",
"commission_rate": "3.00",
"contact_email": "dana@example.com",
"contact_first_name": "Dana",
"contact_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"contact_last_name": "Whitaker",
"contract_date": "…",
"created_at": "2026-07-02T16:20:00Z",
"deal_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"deal_name": "…",
"deal_status": "…",
"document_count": 0,
"earnest_money_due_date": "…",
"fell_through_reason": "…",
"financing_date": "…",
"gci_override": true,
"gross_commission": "21750.00",
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"inspection_date": "…",
"listing_key": "…",
"listing_label": "1420 Terry Ave #1903",
"listing_photo_path": "…",
"name": "1420 Terry Ave — Whitaker purchase",
"net_commission": "…",
"notes": "…",
"possession_date": "…",
"projected_close_date": "…",
"referral_fee": "…",
"sale_price": "725000.00",
"side": "buyer",
"stage_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"stage_name": "Under contract",
"status": "pending",
"team_split_rate": "…",
"transaction_fees": "…",
"updated_at": "2026-07-02T16:20:00Z",
"walkthrough_date": "…"
}Delete a transaction
DELETE/v1/transactions/{id}
Path parameters
idstringrequiredTransaction ID
Returns
200Deletion confirmation.401Missing or invalid API key.404No transaction with that id.Response attributes
deleted_idstringrequiredId of the deleted transaction.
successbooleanrequiredcurl "https://api.uplevelre.com/v1/transactions/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
-X DELETE \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"deleted_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"success": true
}Retrieve a transaction's closing workflow
GET/v1/transactions/{id}/workflow
Path parameters
idstringrequiredTransaction ID
Returns
200Closing checklist, parties, timeline, available reopen stages and default stage.401Missing or invalid API key.404No transaction with that id.Response attributes
activitiesarray of objectsrequiredThe transaction's timeline.
Show child attributesHide child attributes
created_attimestamprequireddescriptionstringrequiredidstringrequiredtitlestringrequireddefault_reopen_stage_idstringrequiredThe deal stage a reopened deal moves to by default; empty when there is none.
partiesarray of objectsrequiredPeople on the transaction.
Show child attributesHide child attributes
contact_idstringrequiredidstringrequirednamestringrequiredrelationship_label_idstringrequiredThe typed relationship the party was added with; empty for another client.
rolestringrequiredreopen_stagesarray of objectsrequiredOpen deal stages the linked deal can reopen into.
Show child attributesHide child attributes
idstringrequirednamestringrequiredtasksarray of objectsrequiredThe closing checklist.
Show child attributesHide child attributes
completedbooleanrequireddue_datestringrequiredYYYY-MM-DD; empty when the task has no deadline.
idstringrequiredmilestonestringrequiredThe transaction date the task is due relative to; empty when it has none.
offset_daysintegerrequiredDays from the milestone to the due date.
titlestringrequiredcurl "https://api.uplevelre.com/v1/transactions/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21/workflow" \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"activities": [
{
"created_at": "2026-07-02T16:20:00Z",
"description": "…",
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"title": "…"
}
],
"default_reopen_stage_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"parties": [
{
"contact_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "…",
"relationship_label_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"role": "…"
}
],
"reopen_stages": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Negotiation"
}
],
"tasks": [
{
"completed": true,
"due_date": "…",
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"milestone": "…",
"offset_days": 0,
"title": "…"
}
]
}Retrieve closing settings
GET/v1/transaction-settings
Returns
200Closing stages and checklist templates.401Missing or invalid API key.Response attributes
checklist_templatesarray of objectsrequiredShow child attributesHide child attributes
idstringrequireditemsarray of objectsrequiredShow child attributesHide child attributes
idstringrequiredmilestonestringrequiredTransaction date field the item is due relative to; empty means no deadline.
offset_daysintegerrequiredtitlestringrequirednamestringrequiredsidestringrequiredbuyer, seller, or both.
stagesarray of objectsrequiredClosing stages, in board order.
Show child attributesHide child attributes
archivedbooleanrequiredidstringrequirednamestringrequiredsemantic_statusstringrequiredactive, pending, closed, or fell_through.
sort_orderintegerrequiredcurl "https://api.uplevelre.com/v1/transaction-settings" \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"checklist_templates": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"items": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"milestone": "…",
"offset_days": 0,
"title": "…"
}
],
"name": "…",
"side": "…"
}
],
"stages": [
{
"archived": true,
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Under contract",
"semantic_status": "…",
"sort_order": 0
}
]
}Deals
Deals moving through your pipelines. Each deal sits in one pipeline stage and can link a contact and a listing.
List deals
GET/v1/deals
Returns the workspace's deals, newest first.
Query parameters
limitintegerObjects per page, 1–100.
cursorstringOpaque cursor from a previous response's next_cursor; returns results strictly after it.
pipeline_idstringOnly deals in this pipeline (see /v1/pipelines).
stage_idstringOnly deals in this stage.
contact_idstringOnly deals linked to this contact.
statusstringOnly deals with this status: open, won, or lost.
Returns
200One page of deals.401Missing or invalid API key.403The key lacks the read_deals scope.Response attributes
dataarray of objectsrequiredShow child attributesHide child attributes
idstringrequirednamestringrequiredvaluenullable stringrequiredDeal value in workspace currency, as a decimal string.
statusstringrequiredopen, won, or lost — derived from the stage's type.
pipelineobjectrequiredShow child attributesHide child attributes
idstringrequirednamestringrequiredstageobjectrequiredShow child attributesHide child attributes
idstringrequirednamestringrequiredtypestringrequiredOPEN, CLOSED_WON, or CLOSED_LOST.
contact_idnullable stringrequiredContact the deal belongs to, if linked.
listing_labelnullable stringrequiredListing linked to the deal, if any (read-only through the API).
expected_close_datenullable timestamprequiredclosed_atnullable timestamprequiredlost_reasonnullable stringrequiredWhy the deal was lost, when it sits in a closed-lost stage.
notesnullable stringrequiredcreated_attimestamprequiredupdated_attimestamprequiredhas_morebooleanrequiredWhether another page exists after this one.
next_cursornullable stringPass as ?cursor= to fetch the next page. Left out on the last page.
total_countintegerrequiredTotal objects matching the query across all pages.
curl "https://api.uplevelre.com/v1/deals?limit=25&status=open" \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"data": [
{
"id": "6b9f1a2c-3d4e-5f60-7a8b-9c0d1e2f3a4b",
"name": "1420 Terry Ave — Whitaker purchase",
"value": "725000.00",
"status": "open",
"pipeline": {
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Sales Pipeline"
},
"stage": {
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Negotiation",
"type": "OPEN"
},
"contact_id": null,
"listing_label": null,
"expected_close_date": null,
"closed_at": null,
"lost_reason": null,
"notes": null,
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z"
}
],
"has_more": true,
"next_cursor": null,
"total_count": 42
}Create a deal
POST/v1/deals
Body parameters
namestringrequiredstage_idstringrequiredStage to create the deal in (see /v1/pipelines); determines the pipeline and initial status.
valuenullable stringDeal value as a decimal string, up to 2 decimal places.
contact_idnullable stringContact to link (see /v1/contacts).
expected_close_datenullable stringRFC 3339 timestamp or YYYY-MM-DD date.
notesnullable stringReturns
201The created deal.400A field failed validation.401Missing or invalid API key.403The key lacks the write_deals scope.Response attributes
idstringrequirednamestringrequiredvaluenullable stringrequiredDeal value in workspace currency, as a decimal string.
statusstringrequiredopen, won, or lost — derived from the stage's type.
pipelineobjectrequiredShow child attributesHide child attributes
idstringrequirednamestringrequiredstageobjectrequiredShow child attributesHide child attributes
idstringrequirednamestringrequiredtypestringrequiredOPEN, CLOSED_WON, or CLOSED_LOST.
contact_idnullable stringrequiredContact the deal belongs to, if linked.
listing_labelnullable stringrequiredListing linked to the deal, if any (read-only through the API).
expected_close_datenullable timestamprequiredclosed_atnullable timestamprequiredlost_reasonnullable stringrequiredWhy the deal was lost, when it sits in a closed-lost stage.
notesnullable stringrequiredcreated_attimestamprequiredupdated_attimestamprequiredcurl "https://api.uplevelre.com/v1/deals" \
-H "Authorization: Bearer $UPLEVEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "1420 Terry Ave — Whitaker purchase",
"stage_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"value": "725000.00",
"expected_close_date": "2026-09-30"
}'{
"id": "6b9f1a2c-3d4e-5f60-7a8b-9c0d1e2f3a4b",
"name": "1420 Terry Ave — Whitaker purchase",
"value": "725000.00",
"status": "open",
"pipeline": {
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Sales Pipeline"
},
"stage": {
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Negotiation",
"type": "OPEN"
},
"contact_id": null,
"listing_label": null,
"expected_close_date": null,
"closed_at": null,
"lost_reason": null,
"notes": null,
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z"
}Retrieve a deal
GET/v1/deals/{deal_id}
Path parameters
deal_idstringrequiredId of the deal.
Returns
200The deal.401Missing or invalid API key.404No deal with that id.Response attributes
idstringrequirednamestringrequiredvaluenullable stringrequiredDeal value in workspace currency, as a decimal string.
statusstringrequiredopen, won, or lost — derived from the stage's type.
pipelineobjectrequiredShow child attributesHide child attributes
idstringrequirednamestringrequiredstageobjectrequiredShow child attributesHide child attributes
idstringrequirednamestringrequiredtypestringrequiredOPEN, CLOSED_WON, or CLOSED_LOST.
contact_idnullable stringrequiredContact the deal belongs to, if linked.
listing_labelnullable stringrequiredListing linked to the deal, if any (read-only through the API).
expected_close_datenullable timestamprequiredclosed_atnullable timestamprequiredlost_reasonnullable stringrequiredWhy the deal was lost, when it sits in a closed-lost stage.
notesnullable stringrequiredcreated_attimestamprequiredupdated_attimestamprequiredcurl "https://api.uplevelre.com/v1/deals/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"id": "6b9f1a2c-3d4e-5f60-7a8b-9c0d1e2f3a4b",
"name": "1420 Terry Ave — Whitaker purchase",
"value": "725000.00",
"status": "open",
"pipeline": {
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Sales Pipeline"
},
"stage": {
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Negotiation",
"type": "OPEN"
},
"contact_id": null,
"listing_label": null,
"expected_close_date": null,
"closed_at": null,
"lost_reason": null,
"notes": null,
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z"
}Update a deal
PATCH/v1/deals/{deal_id}
Partial update. Passing stage_id moves the deal — deal.stage_changed webhooks fire in addition to deal.updated.
Path parameters
deal_idstringrequiredId of the deal.
Body parameters
namenullable stringvaluenullable stringDecimal string; empty string clears the value.
stage_idnullable stringMove the deal to this stage (must be in the deal's pipeline). The stage's type updates status and closed_at.
contact_idnullable stringContact to link; empty string unlinks.
expected_close_datenullable stringRFC 3339 timestamp or YYYY-MM-DD; empty string clears it.
lost_reasonnullable stringRecorded when moving into a closed-lost stage.
notesnullable stringReturns
200The updated deal.400A field failed validation.401Missing or invalid API key.404No deal with that id.Response attributes
idstringrequirednamestringrequiredvaluenullable stringrequiredDeal value in workspace currency, as a decimal string.
statusstringrequiredopen, won, or lost — derived from the stage's type.
pipelineobjectrequiredShow child attributesHide child attributes
idstringrequirednamestringrequiredstageobjectrequiredShow child attributesHide child attributes
idstringrequirednamestringrequiredtypestringrequiredOPEN, CLOSED_WON, or CLOSED_LOST.
contact_idnullable stringrequiredContact the deal belongs to, if linked.
listing_labelnullable stringrequiredListing linked to the deal, if any (read-only through the API).
expected_close_datenullable timestamprequiredclosed_atnullable timestamprequiredlost_reasonnullable stringrequiredWhy the deal was lost, when it sits in a closed-lost stage.
notesnullable stringrequiredcreated_attimestamprequiredupdated_attimestamprequiredcurl "https://api.uplevelre.com/v1/deals/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
-X PATCH \
-H "Authorization: Bearer $UPLEVEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "…",
"value": "…",
"stage_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21"
}'{
"id": "6b9f1a2c-3d4e-5f60-7a8b-9c0d1e2f3a4b",
"name": "1420 Terry Ave — Whitaker purchase",
"value": "725000.00",
"status": "open",
"pipeline": {
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Sales Pipeline"
},
"stage": {
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Negotiation",
"type": "OPEN"
},
"contact_id": null,
"listing_label": null,
"expected_close_date": null,
"closed_at": null,
"lost_reason": null,
"notes": null,
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z"
}Delete a deal
DELETE/v1/deals/{deal_id}
Path parameters
deal_idstringrequiredId of the deal.
Returns
200Deletion confirmation.401Missing or invalid API key.404No deal with that id.Response attributes
idstringrequiredId of the deleted object.
deletedbooleanrequiredcurl "https://api.uplevelre.com/v1/deals/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
-X DELETE \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"deleted": true
}Tasks
To-dos and reminders, optionally linked to a contact and assigned to a teammate.
List tasks
GET/v1/tasks
Returns the workspace's tasks, newest first.
Query parameters
limitintegerObjects per page, 1–100.
cursorstringOpaque cursor from a previous response's next_cursor; returns results strictly after it.
statusstringOnly tasks with this status: todo, in_progress, waiting, done.
completedbooleanOnly completed (true) or open (false) tasks.
assignee_idstringOnly tasks assigned to this member (see /v1/members).
contact_idstringOnly tasks linked to this contact.
deal_idstringOnly tasks linked to this deal.
due_beforetimestampOnly tasks due at or before this RFC 3339 timestamp.
due_aftertimestampOnly tasks due at or after this RFC 3339 timestamp.
Returns
200One page of tasks.401Missing or invalid API key.403The key lacks the read_tasks scope.Response attributes
dataarray of objectsrequiredShow child attributesHide child attributes
idstringrequiredtitlestringrequireddescriptionnullable stringrequiredtypestringrequiredKind of task, e.g. todo, call, email, showing.
prioritystringrequiredlow, medium, or high.
statusstringrequiredtodo, in_progress, waiting, or done.
completedbooleanrequireddue_datenullable timestamprequiredall_daybooleanrequiredWhether the due date is a date (no time of day).
contact_idnullable stringrequiredContact the task is linked to, if any.
deal_idnullable stringrequiredDeal the task is linked to, if any.
assigneenullable objectrequiredTeam member the task is assigned to.
Show child attributesHide child attributes
idstringrequirednamestringrequiredremind_minutes_beforenullable integerrequiredReminder offset before due_date, in minutes.
completed_atnullable timestamprequiredcreated_attimestamprequiredupdated_attimestamprequiredhas_morebooleanrequiredWhether another page exists after this one.
total_countintegerrequiredTotal objects matching the query across all pages.
next_cursornullable stringPass as ?cursor= to fetch the next page. Left out on the last page.
curl "https://api.uplevelre.com/v1/tasks?limit=25" \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"data": [
{
"id": "a1b2c3d4-e5f6-4708-9a0b-c1d2e3f4a5b6",
"title": "Call Dana about the Terry Ave listing",
"description": null,
"type": "call",
"priority": "medium",
"status": "todo",
"completed": true,
"due_date": null,
"all_day": true,
"contact_id": null,
"deal_id": null,
"assignee": null,
"remind_minutes_before": null,
"completed_at": null,
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z"
}
],
"has_more": true,
"total_count": 42,
"next_cursor": null
}Create a task
POST/v1/tasks
Body parameters
titlestringrequireddescriptionnullable stringtypenullable stringKind of task, e.g. todo, call, email, showing. Defaults to todo.
prioritynullable stringlow, medium, or high. Defaults to medium.
statusnullable stringtodo, in_progress, waiting, or done. Defaults to todo.
due_datenullable timestampRFC 3339 timestamp the task is due.
all_daynullable booleanWhether due_date is a date without a time of day.
contact_idnullable stringContact to link (see /v1/contacts).
deal_idnullable stringDeal to link (see /v1/deals).
assignee_idnullable stringMember to assign (see /v1/members). Omit to leave unassigned.
remind_minutes_beforenullable integerReminder offset before due_date, in minutes.
Returns
201The created task.400A field failed validation.401Missing or invalid API key.403The key lacks the write_tasks scope.Response attributes
idstringrequiredtitlestringrequireddescriptionnullable stringrequiredtypestringrequiredKind of task, e.g. todo, call, email, showing.
prioritystringrequiredlow, medium, or high.
statusstringrequiredtodo, in_progress, waiting, or done.
completedbooleanrequireddue_datenullable timestamprequiredall_daybooleanrequiredWhether the due date is a date (no time of day).
contact_idnullable stringrequiredContact the task is linked to, if any.
deal_idnullable stringrequiredDeal the task is linked to, if any.
assigneenullable objectrequiredTeam member the task is assigned to.
Show child attributesHide child attributes
idstringrequirednamestringrequiredremind_minutes_beforenullable integerrequiredReminder offset before due_date, in minutes.
completed_atnullable timestamprequiredcreated_attimestamprequiredupdated_attimestamprequiredcurl "https://api.uplevelre.com/v1/tasks" \
-H "Authorization: Bearer $UPLEVEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Call Dana about the Terry Ave listing",
"description": "…",
"type": "…"
}'{
"id": "a1b2c3d4-e5f6-4708-9a0b-c1d2e3f4a5b6",
"title": "Call Dana about the Terry Ave listing",
"description": null,
"type": "call",
"priority": "medium",
"status": "todo",
"completed": true,
"due_date": null,
"all_day": true,
"contact_id": null,
"deal_id": null,
"assignee": null,
"remind_minutes_before": null,
"completed_at": null,
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z"
}Retrieve a task
GET/v1/tasks/{task_id}
Path parameters
task_idstringrequiredId of the task.
Returns
200The task.401Missing or invalid API key.404No task with that id.Response attributes
idstringrequiredtitlestringrequireddescriptionnullable stringrequiredtypestringrequiredKind of task, e.g. todo, call, email, showing.
prioritystringrequiredlow, medium, or high.
statusstringrequiredtodo, in_progress, waiting, or done.
completedbooleanrequireddue_datenullable timestamprequiredall_daybooleanrequiredWhether the due date is a date (no time of day).
contact_idnullable stringrequiredContact the task is linked to, if any.
deal_idnullable stringrequiredDeal the task is linked to, if any.
assigneenullable objectrequiredTeam member the task is assigned to.
Show child attributesHide child attributes
idstringrequirednamestringrequiredremind_minutes_beforenullable integerrequiredReminder offset before due_date, in minutes.
completed_atnullable timestamprequiredcreated_attimestamprequiredupdated_attimestamprequiredcurl "https://api.uplevelre.com/v1/tasks/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"id": "a1b2c3d4-e5f6-4708-9a0b-c1d2e3f4a5b6",
"title": "Call Dana about the Terry Ave listing",
"description": null,
"type": "call",
"priority": "medium",
"status": "todo",
"completed": true,
"due_date": null,
"all_day": true,
"contact_id": null,
"deal_id": null,
"assignee": null,
"remind_minutes_before": null,
"completed_at": null,
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z"
}Update a task
PATCH/v1/tasks/{task_id}
Partial update. Completing a task (status done) fires task.completed webhooks in addition to task.updated.
Path parameters
task_idstringrequiredId of the task.
Body parameters
titlenullable stringdescriptionnullable stringEmpty string clears the description.
typenullable stringprioritynullable stringstatusnullable stringSetting done completes the task; any other status reopens it.
due_datenullable timestampRFC 3339 timestamp; null leaves it unchanged. Use clear_due_date to remove one.
clear_due_datenullable booleanSet true to remove the due date (and any reminder).
all_daynullable booleanassignee_idnullable stringMember to assign; empty string unassigns.
remind_minutes_beforenullable integerReminder offset in minutes; -1 is invalid — use null with clear_due_date to drop reminders along with the date.
Returns
200The updated task.400A field failed validation.401Missing or invalid API key.404No task with that id.Response attributes
idstringrequiredtitlestringrequireddescriptionnullable stringrequiredtypestringrequiredKind of task, e.g. todo, call, email, showing.
prioritystringrequiredlow, medium, or high.
statusstringrequiredtodo, in_progress, waiting, or done.
completedbooleanrequireddue_datenullable timestamprequiredall_daybooleanrequiredWhether the due date is a date (no time of day).
contact_idnullable stringrequiredContact the task is linked to, if any.
deal_idnullable stringrequiredDeal the task is linked to, if any.
assigneenullable objectrequiredTeam member the task is assigned to.
Show child attributesHide child attributes
idstringrequirednamestringrequiredremind_minutes_beforenullable integerrequiredReminder offset before due_date, in minutes.
completed_atnullable timestamprequiredcreated_attimestamprequiredupdated_attimestamprequiredcurl "https://api.uplevelre.com/v1/tasks/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
-X PATCH \
-H "Authorization: Bearer $UPLEVEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "…",
"description": "…",
"type": "…"
}'{
"id": "a1b2c3d4-e5f6-4708-9a0b-c1d2e3f4a5b6",
"title": "Call Dana about the Terry Ave listing",
"description": null,
"type": "call",
"priority": "medium",
"status": "todo",
"completed": true,
"due_date": null,
"all_day": true,
"contact_id": null,
"deal_id": null,
"assignee": null,
"remind_minutes_before": null,
"completed_at": null,
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z"
}Delete a task
DELETE/v1/tasks/{task_id}
Path parameters
task_idstringrequiredId of the task.
Returns
200Deletion confirmation.401Missing or invalid API key.404No task with that id.Response attributes
idstringrequiredId of the deleted object.
deletedbooleanrequiredcurl "https://api.uplevelre.com/v1/tasks/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
-X DELETE \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"deleted": true
}Listings
Your workspace's property listings. MLS-imported listings are read-only through the API; manual listings can be created and edited.
List listings
GET/v1/listings
Returns the workspace's listings, newest first.
Query parameters
limitintegerObjects per page, 1–100.
cursorstringOpaque cursor from a previous response's next_cursor; returns results strictly after it.
statusstringOnly listings with this status.
sourcestringOnly listings from this source: manual, mls_import, url_import.
qstringFree-text search over address, description, and property type.
Returns
200One page of listings.401Missing or invalid API key.403The key lacks the read_listings scope.Response attributes
dataarray of objectsrequiredShow child attributesHide child attributes
idstringrequiredsourcestringrequiredHow the listing entered the system: manual, mls_import, or url_import. Only manual listings can be edited through the API.
statusstringrequireddraft, active, pending, sold, or off_market. Draft listings stay off websites and property alerts.
listing_typestringrequiredsale or rental. For rentals, list_price is the asking rent per month and close_price the agreed rent once leased.
street_addressstringrequiredcitystringrequiredstate_or_provincestringrequiredpostal_codestringrequiredcountynullable stringrequiredlatitudenullable numberrequiredlongitudenullable numberrequiredproperty_typenullable stringrequiredproperty_sub_typenullable stringrequiredlist_pricenullable integerrequiredWhole dollars.
close_pricenullable integerrequiredWhole dollars; set when the listing sold.
bedrooms_totalnullable integerrequiredbathrooms_fullnullable integerrequiredbathrooms_halfnullable integerrequiredliving_areanullable integerrequiredInterior square footage.
lot_size_acresnullable numberrequiredyear_builtnullable integerrequireddescriptionnullable stringrequiredfeaturesarray of stringsrequiredFeature bullet points shown on websites.
virtual_tour_urlnullable stringrequiredphotosarray of stringsrequiredPhoto URLs, in display order. Read-only.
created_attimestamprequiredupdated_attimestamprequiredhas_morebooleanrequiredWhether another page exists after this one.
next_cursornullable stringPass as ?cursor= to fetch the next page. Left out on the last page.
total_countintegerrequiredTotal objects matching the query across all pages.
curl "https://api.uplevelre.com/v1/listings?limit=25&status=active" \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"data": [
{
"id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"source": "manual",
"status": "active",
"listing_type": "sale",
"street_address": "1420 Terry Ave #1903",
"city": "Seattle",
"state_or_province": "WA",
"postal_code": "98101",
"county": null,
"latitude": null,
"longitude": null,
"property_type": "Condominium",
"property_sub_type": null,
"list_price": 725000,
"close_price": null,
"bedrooms_total": null,
"bathrooms_full": null,
"bathrooms_half": null,
"living_area": null,
"lot_size_acres": null,
"year_built": null,
"description": null,
"features": [
"Corner unit",
"City views",
"2 parking spaces"
],
"virtual_tour_url": null,
"photos": [
"…"
],
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z"
}
],
"has_more": true,
"next_cursor": null,
"total_count": 42
}Create a listing
POST/v1/listings
Adds a manual listing. Address fields are required; everything else is optional. New listings default to draft status so they stay off websites until you activate them.
Body parameters
street_addressstringrequiredcitynullable stringstate_or_provincenullable stringpostal_codenullable stringcountynullable stringstatusnullable stringdraft, active, pending, sold, or off_market. Defaults to draft.
listing_typenullable stringsale or rental. Defaults to sale. For rentals, list_price is the asking rent per month.
property_typenullable stringproperty_sub_typenullable stringlist_pricenullable integerWhole dollars.
close_pricenullable integerbedrooms_totalnullable integerbathrooms_fullnullable integerbathrooms_halfnullable integerliving_areanullable integerlot_size_acresnullable numberyear_builtnullable integerdescriptionnullable stringfeaturesnullable array of stringsvirtual_tour_urlnullable stringReturns
201The created listing.400A field failed validation.401Missing or invalid API key.403The key lacks the write_listings scope.Response attributes
idstringrequiredsourcestringrequiredHow the listing entered the system: manual, mls_import, or url_import. Only manual listings can be edited through the API.
statusstringrequireddraft, active, pending, sold, or off_market. Draft listings stay off websites and property alerts.
listing_typestringrequiredsale or rental. For rentals, list_price is the asking rent per month and close_price the agreed rent once leased.
street_addressstringrequiredcitystringrequiredstate_or_provincestringrequiredpostal_codestringrequiredcountynullable stringrequiredlatitudenullable numberrequiredlongitudenullable numberrequiredproperty_typenullable stringrequiredproperty_sub_typenullable stringrequiredlist_pricenullable integerrequiredWhole dollars.
close_pricenullable integerrequiredWhole dollars; set when the listing sold.
bedrooms_totalnullable integerrequiredbathrooms_fullnullable integerrequiredbathrooms_halfnullable integerrequiredliving_areanullable integerrequiredInterior square footage.
lot_size_acresnullable numberrequiredyear_builtnullable integerrequireddescriptionnullable stringrequiredfeaturesarray of stringsrequiredFeature bullet points shown on websites.
virtual_tour_urlnullable stringrequiredphotosarray of stringsrequiredPhoto URLs, in display order. Read-only.
created_attimestamprequiredupdated_attimestamprequiredcurl "https://api.uplevelre.com/v1/listings" \
-H "Authorization: Bearer $UPLEVEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"street_address": "1420 Terry Ave #1903",
"city": "Seattle",
"state_or_province": "WA",
"postal_code": "98101",
"property_type": "Condominium",
"list_price": 725000
}'{
"id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"source": "manual",
"status": "active",
"listing_type": "sale",
"street_address": "1420 Terry Ave #1903",
"city": "Seattle",
"state_or_province": "WA",
"postal_code": "98101",
"county": null,
"latitude": null,
"longitude": null,
"property_type": "Condominium",
"property_sub_type": null,
"list_price": 725000,
"close_price": null,
"bedrooms_total": null,
"bathrooms_full": null,
"bathrooms_half": null,
"living_area": null,
"lot_size_acres": null,
"year_built": null,
"description": null,
"features": [
"Corner unit",
"City views",
"2 parking spaces"
],
"virtual_tour_url": null,
"photos": [
"…"
],
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z"
}Retrieve a listing
GET/v1/listings/{listing_id}
Path parameters
listing_idstringrequiredId of the listing.
Returns
200The listing.401Missing or invalid API key.404No listing with that id.Response attributes
idstringrequiredsourcestringrequiredHow the listing entered the system: manual, mls_import, or url_import. Only manual listings can be edited through the API.
statusstringrequireddraft, active, pending, sold, or off_market. Draft listings stay off websites and property alerts.
listing_typestringrequiredsale or rental. For rentals, list_price is the asking rent per month and close_price the agreed rent once leased.
street_addressstringrequiredcitystringrequiredstate_or_provincestringrequiredpostal_codestringrequiredcountynullable stringrequiredlatitudenullable numberrequiredlongitudenullable numberrequiredproperty_typenullable stringrequiredproperty_sub_typenullable stringrequiredlist_pricenullable integerrequiredWhole dollars.
close_pricenullable integerrequiredWhole dollars; set when the listing sold.
bedrooms_totalnullable integerrequiredbathrooms_fullnullable integerrequiredbathrooms_halfnullable integerrequiredliving_areanullable integerrequiredInterior square footage.
lot_size_acresnullable numberrequiredyear_builtnullable integerrequireddescriptionnullable stringrequiredfeaturesarray of stringsrequiredFeature bullet points shown on websites.
virtual_tour_urlnullable stringrequiredphotosarray of stringsrequiredPhoto URLs, in display order. Read-only.
created_attimestamprequiredupdated_attimestamprequiredcurl "https://api.uplevelre.com/v1/listings/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"source": "manual",
"status": "active",
"listing_type": "sale",
"street_address": "1420 Terry Ave #1903",
"city": "Seattle",
"state_or_province": "WA",
"postal_code": "98101",
"county": null,
"latitude": null,
"longitude": null,
"property_type": "Condominium",
"property_sub_type": null,
"list_price": 725000,
"close_price": null,
"bedrooms_total": null,
"bathrooms_full": null,
"bathrooms_half": null,
"living_area": null,
"lot_size_acres": null,
"year_built": null,
"description": null,
"features": [
"Corner unit",
"City views",
"2 parking spaces"
],
"virtual_tour_url": null,
"photos": [
"…"
],
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z"
}Update a listing
PATCH/v1/listings/{listing_id}
Partial update of a manual listing. MLS- and URL-imported listings are read-only through the API.
Path parameters
listing_idstringrequiredId of the listing.
Body parameters
street_addressnullable stringcitynullable stringstate_or_provincenullable stringpostal_codenullable stringcountynullable stringstatusnullable stringlisting_typenullable stringsale or rental.
property_typenullable stringproperty_sub_typenullable stringlist_pricenullable integerclose_pricenullable integerbedrooms_totalnullable integerbathrooms_fullnullable integerbathrooms_halfnullable integerliving_areanullable integerlot_size_acresnullable numberyear_builtnullable integerdescriptionnullable stringfeaturesnullable array of stringsReplaces the feature list wholesale when provided.
virtual_tour_urlnullable stringReturns
200The updated listing.400A field failed validation, or the listing is not manual.401Missing or invalid API key.404No listing with that id.Response attributes
idstringrequiredsourcestringrequiredHow the listing entered the system: manual, mls_import, or url_import. Only manual listings can be edited through the API.
statusstringrequireddraft, active, pending, sold, or off_market. Draft listings stay off websites and property alerts.
listing_typestringrequiredsale or rental. For rentals, list_price is the asking rent per month and close_price the agreed rent once leased.
street_addressstringrequiredcitystringrequiredstate_or_provincestringrequiredpostal_codestringrequiredcountynullable stringrequiredlatitudenullable numberrequiredlongitudenullable numberrequiredproperty_typenullable stringrequiredproperty_sub_typenullable stringrequiredlist_pricenullable integerrequiredWhole dollars.
close_pricenullable integerrequiredWhole dollars; set when the listing sold.
bedrooms_totalnullable integerrequiredbathrooms_fullnullable integerrequiredbathrooms_halfnullable integerrequiredliving_areanullable integerrequiredInterior square footage.
lot_size_acresnullable numberrequiredyear_builtnullable integerrequireddescriptionnullable stringrequiredfeaturesarray of stringsrequiredFeature bullet points shown on websites.
virtual_tour_urlnullable stringrequiredphotosarray of stringsrequiredPhoto URLs, in display order. Read-only.
created_attimestamprequiredupdated_attimestamprequiredcurl "https://api.uplevelre.com/v1/listings/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
-X PATCH \
-H "Authorization: Bearer $UPLEVEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"street_address": "…",
"city": "…",
"state_or_province": "…"
}'{
"id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"source": "manual",
"status": "active",
"listing_type": "sale",
"street_address": "1420 Terry Ave #1903",
"city": "Seattle",
"state_or_province": "WA",
"postal_code": "98101",
"county": null,
"latitude": null,
"longitude": null,
"property_type": "Condominium",
"property_sub_type": null,
"list_price": 725000,
"close_price": null,
"bedrooms_total": null,
"bathrooms_full": null,
"bathrooms_half": null,
"living_area": null,
"lot_size_acres": null,
"year_built": null,
"description": null,
"features": [
"Corner unit",
"City views",
"2 parking spaces"
],
"virtual_tour_url": null,
"photos": [
"…"
],
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z"
}Delete a listing
DELETE/v1/listings/{listing_id}
Permanently removes a manual listing and its photos. MLS- and URL-imported listings are read-only through the API.
Path parameters
listing_idstringrequiredId of the listing.
Returns
200Deletion confirmation.400The listing is not manual.401Missing or invalid API key.404No listing with that id.Response attributes
idstringrequiredId of the deleted object.
deletedbooleanrequiredcurl "https://api.uplevelre.com/v1/listings/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
-X DELETE \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"deleted": true
}Webhooks
Subscriptions that POST signed JSON events to your https:// endpoint as data changes in the workspace, once the endpoint is verified.
List webhooks
GET/v1/webhooks
Query parameters
limitintegerObjects per page, 1–100.
cursorstringOpaque cursor from a previous response's next_cursor; returns results strictly after it.
Returns
200One page of webhook endpoints.401Missing or invalid API key.403The key lacks the webhooks_manage scope.Response attributes
dataarray of objectsrequiredShow child attributesHide child attributes
idstringrequirednamestringrequiredurlstringrequiredeventsarray of stringsrequiredSubscribed event types, or ["*"] for everything.
secret_kindstringrequiredHow the signing secret was established: generated (a whsec_… secret returned once when it is created or rotated) or code_word (an endpoint created in the dashboard before secrets were generated; the signing key is the SHA-256 hex digest of the code word). Rotating the secret in the dashboard makes it generated.
is_activebooleanrequiredWhether the endpoint receives deliveries. Set to false to pause.
disabled_atnullable timestamprequiredSet when Uplevel disabled the endpoint after repeated failures. Re-enable by updating the endpoint with is_active: true.
disabled_reasonnullable stringrequiredfailure_countintegerrequiredConsecutive failed delivery attempts since the last success.
last_success_atnullable timestamprequiredlast_failure_atnullable timestamprequiredcreated_attimestamprequiredverified_atnullable timestamprequiredWhen the endpoint last echoed a verification challenge. Until it is set, the endpoint receives no events: call POST /v1/webhooks/{webhook_id}/verify. Changing the url clears it.
has_morebooleanrequiredWhether another page exists after this one.
next_cursornullable stringPass as ?cursor= to fetch the next page. Left out on the last page.
total_countintegerrequiredTotal objects matching the query across all pages.
curl "https://api.uplevelre.com/v1/webhooks?limit=25" \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"data": [
{
"id": "9c1d1c0a-2f6b-4c8e-9f37-52b6a1e0d9f4",
"name": "Production sync",
"url": "https://example.com/hooks/uplevel",
"events": [
"contact.created",
"deal.stage_changed"
],
"secret_kind": "generated",
"is_active": true,
"disabled_at": null,
"disabled_reason": null,
"failure_count": 0,
"last_success_at": null,
"last_failure_at": null,
"created_at": "2026-07-02T16:20:00Z",
"verified_at": null
}
],
"has_more": true,
"next_cursor": null,
"total_count": 42
}Create a webhook
POST/v1/webhooks
Registers an endpoint and returns it with its signing secret — the only time the secret is shown. The endpoint receives no events until it is verified with POST /v1/webhooks/{webhook_id}/verify. See Verifying deliveries for the signature.
Body parameters
namestringrequiredurlstringrequiredPublicly reachable https:// endpoint to POST events to. Plain http:// is refused.
eventsarray of stringsrequiredEvent types to deliver, or ["*"] for all events.
Returns
201The created endpoint, including its signing secret.400A field failed validation.401Missing or invalid API key.403The key lacks the webhooks_manage scope.Response attributes
idstringnamestringurlstringeventsarray of stringsSubscribed event types, or ["*"] for everything.
secret_kindstringHow the signing secret was established: generated (a whsec_… secret returned once when it is created or rotated) or code_word (an endpoint created in the dashboard before secrets were generated; the signing key is the SHA-256 hex digest of the code word). Rotating the secret in the dashboard makes it generated.
is_activebooleanWhether the endpoint receives deliveries. Set to false to pause.
disabled_atnullable timestampSet when Uplevel disabled the endpoint after repeated failures. Re-enable by updating the endpoint with is_active: true.
disabled_reasonnullable stringfailure_countintegerConsecutive failed delivery attempts since the last success.
last_success_atnullable timestamplast_failure_atnullable timestampcreated_attimestampverified_atnullable timestampWhen the endpoint last echoed a verification challenge. Until it is set, the endpoint receives no events: call POST /v1/webhooks/{webhook_id}/verify. Changing the url clears it.
secretstringrequiredHMAC-SHA256 signing secret for verifying deliveries. Shown once.
curl "https://api.uplevelre.com/v1/webhooks" \
-H "Authorization: Bearer $UPLEVEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Production sync",
"url": "https://example.com/hooks/uplevel",
"events": [
"contact.created",
"contact.updated"
]
}'{
"id": "9c1d1c0a-2f6b-4c8e-9f37-52b6a1e0d9f4",
"name": "Production sync",
"url": "https://example.com/hooks/uplevel",
"events": [
"contact.created",
"deal.stage_changed"
],
"secret_kind": "generated",
"is_active": true,
"disabled_at": null,
"disabled_reason": null,
"failure_count": 0,
"last_success_at": null,
"last_failure_at": null,
"created_at": "2026-07-02T16:20:00Z",
"verified_at": null,
"secret": "whsec_6f0e9d8c7b6a5f4e3d2c1b0a9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e"
}Retrieve a webhook
GET/v1/webhooks/{webhook_id}
Path parameters
webhook_idstringrequiredId of the webhook.
Returns
200The webhook endpoint.401Missing or invalid API key.404No webhook with that id.Response attributes
idstringrequirednamestringrequiredurlstringrequiredeventsarray of stringsrequiredSubscribed event types, or ["*"] for everything.
secret_kindstringrequiredHow the signing secret was established: generated (a whsec_… secret returned once when it is created or rotated) or code_word (an endpoint created in the dashboard before secrets were generated; the signing key is the SHA-256 hex digest of the code word). Rotating the secret in the dashboard makes it generated.
is_activebooleanrequiredWhether the endpoint receives deliveries. Set to false to pause.
disabled_atnullable timestamprequiredSet when Uplevel disabled the endpoint after repeated failures. Re-enable by updating the endpoint with is_active: true.
disabled_reasonnullable stringrequiredfailure_countintegerrequiredConsecutive failed delivery attempts since the last success.
last_success_atnullable timestamprequiredlast_failure_atnullable timestamprequiredcreated_attimestamprequiredverified_atnullable timestamprequiredWhen the endpoint last echoed a verification challenge. Until it is set, the endpoint receives no events: call POST /v1/webhooks/{webhook_id}/verify. Changing the url clears it.
curl "https://api.uplevelre.com/v1/webhooks/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"id": "9c1d1c0a-2f6b-4c8e-9f37-52b6a1e0d9f4",
"name": "Production sync",
"url": "https://example.com/hooks/uplevel",
"events": [
"contact.created",
"deal.stage_changed"
],
"secret_kind": "generated",
"is_active": true,
"disabled_at": null,
"disabled_reason": null,
"failure_count": 0,
"last_success_at": null,
"last_failure_at": null,
"created_at": "2026-07-02T16:20:00Z",
"verified_at": null
}Update a webhook
PATCH/v1/webhooks/{webhook_id}
Path parameters
webhook_idstringrequiredId of the webhook.
Body parameters
namenullable stringurlnullable stringA new https:// address. The endpoint must be verified again before it receives events.
eventsnullable array of stringsis_activenullable booleanSet true to (re-)enable deliveries — this also clears an automatic disable and resets the failure counter. Set false to pause.
Returns
200The updated endpoint.400A field failed validation.401Missing or invalid API key.404No webhook with that id.Response attributes
idstringrequirednamestringrequiredurlstringrequiredeventsarray of stringsrequiredSubscribed event types, or ["*"] for everything.
secret_kindstringrequiredHow the signing secret was established: generated (a whsec_… secret returned once when it is created or rotated) or code_word (an endpoint created in the dashboard before secrets were generated; the signing key is the SHA-256 hex digest of the code word). Rotating the secret in the dashboard makes it generated.
is_activebooleanrequiredWhether the endpoint receives deliveries. Set to false to pause.
disabled_atnullable timestamprequiredSet when Uplevel disabled the endpoint after repeated failures. Re-enable by updating the endpoint with is_active: true.
disabled_reasonnullable stringrequiredfailure_countintegerrequiredConsecutive failed delivery attempts since the last success.
last_success_atnullable timestamprequiredlast_failure_atnullable timestamprequiredcreated_attimestamprequiredverified_atnullable timestamprequiredWhen the endpoint last echoed a verification challenge. Until it is set, the endpoint receives no events: call POST /v1/webhooks/{webhook_id}/verify. Changing the url clears it.
curl "https://api.uplevelre.com/v1/webhooks/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
-X PATCH \
-H "Authorization: Bearer $UPLEVEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "…",
"url": "https://example.com",
"events": [
"…"
]
}'{
"id": "9c1d1c0a-2f6b-4c8e-9f37-52b6a1e0d9f4",
"name": "Production sync",
"url": "https://example.com/hooks/uplevel",
"events": [
"contact.created",
"deal.stage_changed"
],
"secret_kind": "generated",
"is_active": true,
"disabled_at": null,
"disabled_reason": null,
"failure_count": 0,
"last_success_at": null,
"last_failure_at": null,
"created_at": "2026-07-02T16:20:00Z",
"verified_at": null
}Delete a webhook
DELETE/v1/webhooks/{webhook_id}
Removes the endpoint and its delivery history. In-flight deliveries are abandoned.
Path parameters
webhook_idstringrequiredId of the webhook.
Returns
200Deletion confirmation.401Missing or invalid API key.404No webhook with that id.Response attributes
idstringrequiredId of the deleted object.
deletedbooleanrequiredcurl "https://api.uplevelre.com/v1/webhooks/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
-X DELETE \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"deleted": true
}List a webhook's deliveries
GET/v1/webhooks/{webhook_id}/deliveries
Recent delivery attempts for the endpoint, newest first — the place to look when events are not arriving.
Path parameters
webhook_idstringrequiredId of the webhook.
Query parameters
limitintegerObjects per page, 1–100.
cursorstringOpaque cursor from a previous response's next_cursor; returns results strictly after it.
Returns
200One page of deliveries.401Missing or invalid API key.404No webhook with that id.Response attributes
dataarray of objectsrequiredShow child attributesHide child attributes
idstringrequiredevent_typestringrequiredEvent that triggered the delivery, e.g. contact.created.
event_idstringrequiredId of the event across all endpoints it was fanned out to.
statusstringrequiredpending, delivered, or failed.
attemptsintegerrequiredAttempts made so far (retried with backoff up to 5 times).
http_statusnullable integerrequiredHTTP status your endpoint returned, when it responded.
error_messagenullable stringrequireddelivered_atnullable timestamprequiredcreated_attimestamprequiredhas_morebooleanrequiredWhether another page exists after this one.
next_cursornullable stringPass as ?cursor= to fetch the next page. Left out on the last page.
total_countintegerrequiredTotal objects matching the query across all pages.
curl "https://api.uplevelre.com/v1/webhooks/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21/deliveries?limit=25" \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"data": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"event_type": "…",
"event_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"status": "delivered",
"attempts": 0,
"http_status": null,
"error_message": null,
"delivered_at": null,
"created_at": "2026-07-02T16:20:00Z"
}
],
"has_more": true,
"next_cursor": null,
"total_count": 42
}Verify a webhook
POST/v1/webhooks/{webhook_id}/verify
Proves you control the endpoint. Uplevel POSTs a signed webhook.verification event whose data.challenge is a random value. The endpoint is verified, and starts receiving events, when it answers with a 2xx status and the challenge in the response body (for example {"challenge": "whchal_…"}). Verify again after changing the endpoint's url.
Path parameters
webhook_idstringrequiredId of the webhook.
Returns
200The verified endpoint.400The endpoint didn't answer with the challenge. The message says what it answered.401Missing or invalid API key.404No webhook with that id.Response attributes
idstringrequirednamestringrequiredurlstringrequiredeventsarray of stringsrequiredSubscribed event types, or ["*"] for everything.
secret_kindstringrequiredHow the signing secret was established: generated (a whsec_… secret returned once when it is created or rotated) or code_word (an endpoint created in the dashboard before secrets were generated; the signing key is the SHA-256 hex digest of the code word). Rotating the secret in the dashboard makes it generated.
is_activebooleanrequiredWhether the endpoint receives deliveries. Set to false to pause.
disabled_atnullable timestamprequiredSet when Uplevel disabled the endpoint after repeated failures. Re-enable by updating the endpoint with is_active: true.
disabled_reasonnullable stringrequiredfailure_countintegerrequiredConsecutive failed delivery attempts since the last success.
last_success_atnullable timestamprequiredlast_failure_atnullable timestamprequiredcreated_attimestamprequiredverified_atnullable timestamprequiredWhen the endpoint last echoed a verification challenge. Until it is set, the endpoint receives no events: call POST /v1/webhooks/{webhook_id}/verify. Changing the url clears it.
curl "https://api.uplevelre.com/v1/webhooks/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21/verify" \
-X POST \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"id": "9c1d1c0a-2f6b-4c8e-9f37-52b6a1e0d9f4",
"name": "Production sync",
"url": "https://example.com/hooks/uplevel",
"events": [
"contact.created",
"deal.stage_changed"
],
"secret_kind": "generated",
"is_active": true,
"disabled_at": null,
"disabled_reason": null,
"failure_count": 0,
"last_success_at": null,
"last_failure_at": null,
"created_at": "2026-07-02T16:20:00Z",
"verified_at": null
}Webhook events
Every event a webhook endpoint can receive, with the exact payload each one delivers. All events share the envelope described in Webhooks, and every delivery is signed — see Verifying deliveries.
transaction.created
Transactions
A transaction was created.
Payload
idstringrequiredUnique id for this event, shared by every endpoint it fans out to and stable across retries.
typestringrequiredThe event type.
created_attimestamprequiredWhen the event occurred.
dataobjectrequiredThe transaction, as GET /v1/transactions/{id} returns it.
Show child attributesHide child attributes
actual_close_datestringrequiredClosing date, YYYY-MM-DD; set when the transaction closes.
appraisal_datestringrequiredAppraisal deadline, YYYY-MM-DD; empty when not set.
brokerage_split_ratestringrequiredBrokerage split as a percent of GCI after the referral fee.
commission_ratestringrequiredCommission rate as a percent, e.g. 3.00.
contact_emailstringrequiredcontact_first_namestringrequiredcontact_idstringrequiredLinked contact; empty when there is none.
contact_last_namestringrequiredcontract_datestringrequiredContract date, YYYY-MM-DD; empty when not set.
created_attimestamprequireddeal_idstringrequiredLinked deal; empty when there is none.
deal_namestringrequireddeal_statusstringrequiredThe linked deal's open, won, or lost status.
document_countintegerrequiredNumber of documents stored on the transaction.
earnest_money_due_datestringrequiredEarnest money deadline, YYYY-MM-DD; empty when not set.
fell_through_reasonstringrequiredWhy the transaction fell through; empty otherwise.
financing_datestringrequiredFinancing deadline, YYYY-MM-DD; empty when not set.
gci_overridebooleanrequiredWhether gross_commission was entered directly instead of derived.
gross_commissionstringrequiredGross commission income, as a decimal string. Derived from sale_price × commission_rate unless gci_override is set.
idstringrequiredinspection_datestringrequiredInspection deadline, YYYY-MM-DD; empty when not set.
listing_keystringrequiredMLS listing key; empty unless the property is an MLS listing.
listing_labelstringrequiredThe property's address or label.
listing_photo_pathstringrequiredPath to the property's primary photo; empty when there is none.
namestringrequirednet_commissionstringrequiredWhat the agent keeps, as a decimal string: (GCI − referral fee) × (1 − brokerage split − team split) − transaction fees. Always derived.
notesstringrequiredpossession_datestringrequiredPossession date, YYYY-MM-DD; empty when not set.
projected_close_datestringrequiredExpected closing date, YYYY-MM-DD; empty when not set.
referral_feestringrequiredReferral fee taken off the top, as a decimal string.
sale_pricestringrequiredSale price, as a decimal string.
sidestringrequiredbuyer, seller, or both.
stage_idstringrequiredClosing stage the transaction sits in.
stage_namestringrequiredstatusstringrequiredactive, pending, closed, or fell_through, from the closing stage the transaction sits in.
team_split_ratestringrequiredTeam split as a percent of GCI after the referral fee.
transaction_feesstringrequiredFlat transaction fees, as a decimal string.
updated_attimestamprequiredwalkthrough_datestringrequiredFinal walkthrough, YYYY-MM-DD; empty when not set.
{
"id": "evt_1f8b4c9d2e0a4b7f9c3d5e6f7a8b9c0d",
"type": "transaction.created",
"created_at": "2026-07-02T16:20:00Z",
"data": {
"actual_close_date": "2026-09-15",
"appraisal_date": "…",
"brokerage_split_rate": "20.00",
"commission_rate": "3.00",
"contact_email": "dana@example.com",
"contact_first_name": "Dana",
"contact_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"contact_last_name": "Whitaker",
"contract_date": "…",
"created_at": "2026-07-02T16:20:00Z",
"deal_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"deal_name": "…",
"deal_status": "…",
"document_count": 0,
"earnest_money_due_date": "…",
"fell_through_reason": "…",
"financing_date": "…",
"gci_override": true,
"gross_commission": "21750.00",
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"inspection_date": "…",
"listing_key": "…",
"listing_label": "1420 Terry Ave #1903",
"listing_photo_path": "…",
"name": "1420 Terry Ave — Whitaker purchase",
"net_commission": "…",
"notes": "…",
"possession_date": "…",
"projected_close_date": "…",
"referral_fee": "…",
"sale_price": "725000.00",
"side": "buyer",
"stage_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"stage_name": "Under contract",
"status": "pending",
"team_split_rate": "…",
"transaction_fees": "…",
"updated_at": "2026-07-02T16:20:00Z",
"walkthrough_date": "…"
}
}transaction.updated
Transactions
A transaction changed.
Payload
idstringrequiredUnique id for this event, shared by every endpoint it fans out to and stable across retries.
typestringrequiredThe event type.
created_attimestamprequiredWhen the event occurred.
dataobjectrequiredThe transaction, as GET /v1/transactions/{id} returns it.
Show child attributesHide child attributes
actual_close_datestringrequiredClosing date, YYYY-MM-DD; set when the transaction closes.
appraisal_datestringrequiredAppraisal deadline, YYYY-MM-DD; empty when not set.
brokerage_split_ratestringrequiredBrokerage split as a percent of GCI after the referral fee.
commission_ratestringrequiredCommission rate as a percent, e.g. 3.00.
contact_emailstringrequiredcontact_first_namestringrequiredcontact_idstringrequiredLinked contact; empty when there is none.
contact_last_namestringrequiredcontract_datestringrequiredContract date, YYYY-MM-DD; empty when not set.
created_attimestamprequireddeal_idstringrequiredLinked deal; empty when there is none.
deal_namestringrequireddeal_statusstringrequiredThe linked deal's open, won, or lost status.
document_countintegerrequiredNumber of documents stored on the transaction.
earnest_money_due_datestringrequiredEarnest money deadline, YYYY-MM-DD; empty when not set.
fell_through_reasonstringrequiredWhy the transaction fell through; empty otherwise.
financing_datestringrequiredFinancing deadline, YYYY-MM-DD; empty when not set.
gci_overridebooleanrequiredWhether gross_commission was entered directly instead of derived.
gross_commissionstringrequiredGross commission income, as a decimal string. Derived from sale_price × commission_rate unless gci_override is set.
idstringrequiredinspection_datestringrequiredInspection deadline, YYYY-MM-DD; empty when not set.
listing_keystringrequiredMLS listing key; empty unless the property is an MLS listing.
listing_labelstringrequiredThe property's address or label.
listing_photo_pathstringrequiredPath to the property's primary photo; empty when there is none.
namestringrequirednet_commissionstringrequiredWhat the agent keeps, as a decimal string: (GCI − referral fee) × (1 − brokerage split − team split) − transaction fees. Always derived.
notesstringrequiredpossession_datestringrequiredPossession date, YYYY-MM-DD; empty when not set.
projected_close_datestringrequiredExpected closing date, YYYY-MM-DD; empty when not set.
referral_feestringrequiredReferral fee taken off the top, as a decimal string.
sale_pricestringrequiredSale price, as a decimal string.
sidestringrequiredbuyer, seller, or both.
stage_idstringrequiredClosing stage the transaction sits in.
stage_namestringrequiredstatusstringrequiredactive, pending, closed, or fell_through, from the closing stage the transaction sits in.
team_split_ratestringrequiredTeam split as a percent of GCI after the referral fee.
transaction_feesstringrequiredFlat transaction fees, as a decimal string.
updated_attimestamprequiredwalkthrough_datestringrequiredFinal walkthrough, YYYY-MM-DD; empty when not set.
{
"id": "evt_1f8b4c9d2e0a4b7f9c3d5e6f7a8b9c0d",
"type": "transaction.updated",
"created_at": "2026-07-02T16:20:00Z",
"data": {
"actual_close_date": "2026-09-15",
"appraisal_date": "…",
"brokerage_split_rate": "20.00",
"commission_rate": "3.00",
"contact_email": "dana@example.com",
"contact_first_name": "Dana",
"contact_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"contact_last_name": "Whitaker",
"contract_date": "…",
"created_at": "2026-07-02T16:20:00Z",
"deal_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"deal_name": "…",
"deal_status": "…",
"document_count": 0,
"earnest_money_due_date": "…",
"fell_through_reason": "…",
"financing_date": "…",
"gci_override": true,
"gross_commission": "21750.00",
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"inspection_date": "…",
"listing_key": "…",
"listing_label": "1420 Terry Ave #1903",
"listing_photo_path": "…",
"name": "1420 Terry Ave — Whitaker purchase",
"net_commission": "…",
"notes": "…",
"possession_date": "…",
"projected_close_date": "…",
"referral_fee": "…",
"sale_price": "725000.00",
"side": "buyer",
"stage_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"stage_name": "Under contract",
"status": "pending",
"team_split_rate": "…",
"transaction_fees": "…",
"updated_at": "2026-07-02T16:20:00Z",
"walkthrough_date": "…"
}
}transaction.status_changed
Transactions
A transaction changed closing stage.
Payload
idstringrequiredUnique id for this event, shared by every endpoint it fans out to and stable across retries.
typestringrequiredThe event type.
created_attimestamprequiredWhen the event occurred.
dataobjectrequiredThe transaction, as GET /v1/transactions/{id} returns it.
Show child attributesHide child attributes
actual_close_datestringrequiredClosing date, YYYY-MM-DD; set when the transaction closes.
appraisal_datestringrequiredAppraisal deadline, YYYY-MM-DD; empty when not set.
brokerage_split_ratestringrequiredBrokerage split as a percent of GCI after the referral fee.
commission_ratestringrequiredCommission rate as a percent, e.g. 3.00.
contact_emailstringrequiredcontact_first_namestringrequiredcontact_idstringrequiredLinked contact; empty when there is none.
contact_last_namestringrequiredcontract_datestringrequiredContract date, YYYY-MM-DD; empty when not set.
created_attimestamprequireddeal_idstringrequiredLinked deal; empty when there is none.
deal_namestringrequireddeal_statusstringrequiredThe linked deal's open, won, or lost status.
document_countintegerrequiredNumber of documents stored on the transaction.
earnest_money_due_datestringrequiredEarnest money deadline, YYYY-MM-DD; empty when not set.
fell_through_reasonstringrequiredWhy the transaction fell through; empty otherwise.
financing_datestringrequiredFinancing deadline, YYYY-MM-DD; empty when not set.
gci_overridebooleanrequiredWhether gross_commission was entered directly instead of derived.
gross_commissionstringrequiredGross commission income, as a decimal string. Derived from sale_price × commission_rate unless gci_override is set.
idstringrequiredinspection_datestringrequiredInspection deadline, YYYY-MM-DD; empty when not set.
listing_keystringrequiredMLS listing key; empty unless the property is an MLS listing.
listing_labelstringrequiredThe property's address or label.
listing_photo_pathstringrequiredPath to the property's primary photo; empty when there is none.
namestringrequirednet_commissionstringrequiredWhat the agent keeps, as a decimal string: (GCI − referral fee) × (1 − brokerage split − team split) − transaction fees. Always derived.
notesstringrequiredpossession_datestringrequiredPossession date, YYYY-MM-DD; empty when not set.
projected_close_datestringrequiredExpected closing date, YYYY-MM-DD; empty when not set.
referral_feestringrequiredReferral fee taken off the top, as a decimal string.
sale_pricestringrequiredSale price, as a decimal string.
sidestringrequiredbuyer, seller, or both.
stage_idstringrequiredClosing stage the transaction sits in.
stage_namestringrequiredstatusstringrequiredactive, pending, closed, or fell_through, from the closing stage the transaction sits in.
team_split_ratestringrequiredTeam split as a percent of GCI after the referral fee.
transaction_feesstringrequiredFlat transaction fees, as a decimal string.
updated_attimestamprequiredwalkthrough_datestringrequiredFinal walkthrough, YYYY-MM-DD; empty when not set.
{
"id": "evt_1f8b4c9d2e0a4b7f9c3d5e6f7a8b9c0d",
"type": "transaction.status_changed",
"created_at": "2026-07-02T16:20:00Z",
"data": {
"actual_close_date": "2026-09-15",
"appraisal_date": "…",
"brokerage_split_rate": "20.00",
"commission_rate": "3.00",
"contact_email": "dana@example.com",
"contact_first_name": "Dana",
"contact_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"contact_last_name": "Whitaker",
"contract_date": "…",
"created_at": "2026-07-02T16:20:00Z",
"deal_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"deal_name": "…",
"deal_status": "…",
"document_count": 0,
"earnest_money_due_date": "…",
"fell_through_reason": "…",
"financing_date": "…",
"gci_override": true,
"gross_commission": "21750.00",
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"inspection_date": "…",
"listing_key": "…",
"listing_label": "1420 Terry Ave #1903",
"listing_photo_path": "…",
"name": "1420 Terry Ave — Whitaker purchase",
"net_commission": "…",
"notes": "…",
"possession_date": "…",
"projected_close_date": "…",
"referral_fee": "…",
"sale_price": "725000.00",
"side": "buyer",
"stage_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"stage_name": "Under contract",
"status": "pending",
"team_split_rate": "…",
"transaction_fees": "…",
"updated_at": "2026-07-02T16:20:00Z",
"walkthrough_date": "…"
}
}transaction.closed
Transactions
A transaction closed; the sale is actual revenue.
Payload
idstringrequiredUnique id for this event, shared by every endpoint it fans out to and stable across retries.
typestringrequiredThe event type.
created_attimestamprequiredWhen the event occurred.
dataobjectrequiredThe transaction, as GET /v1/transactions/{id} returns it.
Show child attributesHide child attributes
actual_close_datestringrequiredClosing date, YYYY-MM-DD; set when the transaction closes.
appraisal_datestringrequiredAppraisal deadline, YYYY-MM-DD; empty when not set.
brokerage_split_ratestringrequiredBrokerage split as a percent of GCI after the referral fee.
commission_ratestringrequiredCommission rate as a percent, e.g. 3.00.
contact_emailstringrequiredcontact_first_namestringrequiredcontact_idstringrequiredLinked contact; empty when there is none.
contact_last_namestringrequiredcontract_datestringrequiredContract date, YYYY-MM-DD; empty when not set.
created_attimestamprequireddeal_idstringrequiredLinked deal; empty when there is none.
deal_namestringrequireddeal_statusstringrequiredThe linked deal's open, won, or lost status.
document_countintegerrequiredNumber of documents stored on the transaction.
earnest_money_due_datestringrequiredEarnest money deadline, YYYY-MM-DD; empty when not set.
fell_through_reasonstringrequiredWhy the transaction fell through; empty otherwise.
financing_datestringrequiredFinancing deadline, YYYY-MM-DD; empty when not set.
gci_overridebooleanrequiredWhether gross_commission was entered directly instead of derived.
gross_commissionstringrequiredGross commission income, as a decimal string. Derived from sale_price × commission_rate unless gci_override is set.
idstringrequiredinspection_datestringrequiredInspection deadline, YYYY-MM-DD; empty when not set.
listing_keystringrequiredMLS listing key; empty unless the property is an MLS listing.
listing_labelstringrequiredThe property's address or label.
listing_photo_pathstringrequiredPath to the property's primary photo; empty when there is none.
namestringrequirednet_commissionstringrequiredWhat the agent keeps, as a decimal string: (GCI − referral fee) × (1 − brokerage split − team split) − transaction fees. Always derived.
notesstringrequiredpossession_datestringrequiredPossession date, YYYY-MM-DD; empty when not set.
projected_close_datestringrequiredExpected closing date, YYYY-MM-DD; empty when not set.
referral_feestringrequiredReferral fee taken off the top, as a decimal string.
sale_pricestringrequiredSale price, as a decimal string.
sidestringrequiredbuyer, seller, or both.
stage_idstringrequiredClosing stage the transaction sits in.
stage_namestringrequiredstatusstringrequiredactive, pending, closed, or fell_through, from the closing stage the transaction sits in.
team_split_ratestringrequiredTeam split as a percent of GCI after the referral fee.
transaction_feesstringrequiredFlat transaction fees, as a decimal string.
updated_attimestamprequiredwalkthrough_datestringrequiredFinal walkthrough, YYYY-MM-DD; empty when not set.
{
"id": "evt_1f8b4c9d2e0a4b7f9c3d5e6f7a8b9c0d",
"type": "transaction.closed",
"created_at": "2026-07-02T16:20:00Z",
"data": {
"actual_close_date": "2026-09-15",
"appraisal_date": "…",
"brokerage_split_rate": "20.00",
"commission_rate": "3.00",
"contact_email": "dana@example.com",
"contact_first_name": "Dana",
"contact_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"contact_last_name": "Whitaker",
"contract_date": "…",
"created_at": "2026-07-02T16:20:00Z",
"deal_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"deal_name": "…",
"deal_status": "…",
"document_count": 0,
"earnest_money_due_date": "…",
"fell_through_reason": "…",
"financing_date": "…",
"gci_override": true,
"gross_commission": "21750.00",
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"inspection_date": "…",
"listing_key": "…",
"listing_label": "1420 Terry Ave #1903",
"listing_photo_path": "…",
"name": "1420 Terry Ave — Whitaker purchase",
"net_commission": "…",
"notes": "…",
"possession_date": "…",
"projected_close_date": "…",
"referral_fee": "…",
"sale_price": "725000.00",
"side": "buyer",
"stage_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"stage_name": "Under contract",
"status": "pending",
"team_split_rate": "…",
"transaction_fees": "…",
"updated_at": "2026-07-02T16:20:00Z",
"walkthrough_date": "…"
}
}transaction.fell_through
Transactions
A transaction fell through.
Payload
idstringrequiredUnique id for this event, shared by every endpoint it fans out to and stable across retries.
typestringrequiredThe event type.
created_attimestamprequiredWhen the event occurred.
dataobjectrequiredThe transaction, as GET /v1/transactions/{id} returns it.
Show child attributesHide child attributes
actual_close_datestringrequiredClosing date, YYYY-MM-DD; set when the transaction closes.
appraisal_datestringrequiredAppraisal deadline, YYYY-MM-DD; empty when not set.
brokerage_split_ratestringrequiredBrokerage split as a percent of GCI after the referral fee.
commission_ratestringrequiredCommission rate as a percent, e.g. 3.00.
contact_emailstringrequiredcontact_first_namestringrequiredcontact_idstringrequiredLinked contact; empty when there is none.
contact_last_namestringrequiredcontract_datestringrequiredContract date, YYYY-MM-DD; empty when not set.
created_attimestamprequireddeal_idstringrequiredLinked deal; empty when there is none.
deal_namestringrequireddeal_statusstringrequiredThe linked deal's open, won, or lost status.
document_countintegerrequiredNumber of documents stored on the transaction.
earnest_money_due_datestringrequiredEarnest money deadline, YYYY-MM-DD; empty when not set.
fell_through_reasonstringrequiredWhy the transaction fell through; empty otherwise.
financing_datestringrequiredFinancing deadline, YYYY-MM-DD; empty when not set.
gci_overridebooleanrequiredWhether gross_commission was entered directly instead of derived.
gross_commissionstringrequiredGross commission income, as a decimal string. Derived from sale_price × commission_rate unless gci_override is set.
idstringrequiredinspection_datestringrequiredInspection deadline, YYYY-MM-DD; empty when not set.
listing_keystringrequiredMLS listing key; empty unless the property is an MLS listing.
listing_labelstringrequiredThe property's address or label.
listing_photo_pathstringrequiredPath to the property's primary photo; empty when there is none.
namestringrequirednet_commissionstringrequiredWhat the agent keeps, as a decimal string: (GCI − referral fee) × (1 − brokerage split − team split) − transaction fees. Always derived.
notesstringrequiredpossession_datestringrequiredPossession date, YYYY-MM-DD; empty when not set.
projected_close_datestringrequiredExpected closing date, YYYY-MM-DD; empty when not set.
referral_feestringrequiredReferral fee taken off the top, as a decimal string.
sale_pricestringrequiredSale price, as a decimal string.
sidestringrequiredbuyer, seller, or both.
stage_idstringrequiredClosing stage the transaction sits in.
stage_namestringrequiredstatusstringrequiredactive, pending, closed, or fell_through, from the closing stage the transaction sits in.
team_split_ratestringrequiredTeam split as a percent of GCI after the referral fee.
transaction_feesstringrequiredFlat transaction fees, as a decimal string.
updated_attimestamprequiredwalkthrough_datestringrequiredFinal walkthrough, YYYY-MM-DD; empty when not set.
{
"id": "evt_1f8b4c9d2e0a4b7f9c3d5e6f7a8b9c0d",
"type": "transaction.fell_through",
"created_at": "2026-07-02T16:20:00Z",
"data": {
"actual_close_date": "2026-09-15",
"appraisal_date": "…",
"brokerage_split_rate": "20.00",
"commission_rate": "3.00",
"contact_email": "dana@example.com",
"contact_first_name": "Dana",
"contact_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"contact_last_name": "Whitaker",
"contract_date": "…",
"created_at": "2026-07-02T16:20:00Z",
"deal_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"deal_name": "…",
"deal_status": "…",
"document_count": 0,
"earnest_money_due_date": "…",
"fell_through_reason": "…",
"financing_date": "…",
"gci_override": true,
"gross_commission": "21750.00",
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"inspection_date": "…",
"listing_key": "…",
"listing_label": "1420 Terry Ave #1903",
"listing_photo_path": "…",
"name": "1420 Terry Ave — Whitaker purchase",
"net_commission": "…",
"notes": "…",
"possession_date": "…",
"projected_close_date": "…",
"referral_fee": "…",
"sale_price": "725000.00",
"side": "buyer",
"stage_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"stage_name": "Under contract",
"status": "pending",
"team_split_rate": "…",
"transaction_fees": "…",
"updated_at": "2026-07-02T16:20:00Z",
"walkthrough_date": "…"
}
}contact.created
Contacts
A contact was added — from the dashboard, the API, a website form, or another lead-capture source. Bulk imports do not emit events.
Payload
idstringrequiredUnique id for this event, shared by every endpoint it fans out to and stable across retries.
typestringrequiredThe event type.
created_attimestamprequiredWhen the event occurred.
dataobjectrequiredThe contact, as GET /v1/contacts/{contact_id} returns it.
Show child attributesHide child attributes
idstringrequiredfirst_namestringrequiredlast_namestringrequiredemailnullable stringrequiredphonenullable stringrequiredemailsarray of objectsrequiredEvery ordered email address; email above remains the primary shortcut.
Show child attributesHide child attributes
idstringrequiredvaluestringrequiredlabelstringrequiredHome | Work | Other
is_primarybooleanrequiredpositionintegerrequiredphonesarray of objectsrequiredEvery ordered phone number; phone above remains the primary shortcut.
Show child attributesHide child attributes
idstringrequiredvaluestringrequiredlabelstringrequiredMobile | Home | Work | Fax | Other
is_primarybooleanrequiredpositionintegerrequiredaddressnullable stringrequiredcitynullable stringrequiredstatenullable stringrequiredzip_codenullable stringrequiredcompanynullable stringrequiredjob_titlenullable stringrequirednotesnullable stringrequiredFree-form notes shown on the contact record.
stagenullable objectrequiredPipeline stage of the contact, from /v1/contact-stages.
Show child attributesHide child attributes
idstringrequirednamestringrequiredlead_sourcenullable objectrequiredWhere the contact came from, from /v1/lead-sources.
Show child attributesHide child attributes
idstringrequirednamestringrequiredownernullable objectrequiredTeam member the contact is assigned to.
Show child attributesHide child attributes
idstringrequirednamestringrequiredtagsarray of objectsrequiredWorkspace tags on the contact.
Show child attributesHide child attributes
idstringrequirednamestringrequiredcolornullable stringrequiredcustom_fieldsobjectrequiredValues for the workspace's custom fields, keyed by field id.
created_attimestamprequiredupdated_attimestamprequiredlast_activity_atnullable timestamprequiredLast time an activity touched this contact.
{
"id": "evt_1f8b4c9d2e0a4b7f9c3d5e6f7a8b9c0d",
"type": "contact.created",
"created_at": "2026-07-02T16:20:00Z",
"data": {
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"first_name": "Dana",
"last_name": "Whitaker",
"email": "dana@example.com",
"phone": "+12065550123",
"emails": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"value": "…",
"label": "…",
"is_primary": true,
"position": 0
}
],
"phones": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"value": "…",
"label": "…",
"is_primary": true,
"position": 0
}
],
"address": null,
"city": null,
"state": null,
"zip_code": null,
"company": null,
"job_title": null,
"notes": null,
"stage": null,
"lead_source": null,
"owner": null,
"tags": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Buyer",
"color": "#26c2e7"
}
],
"custom_fields": {},
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z",
"last_activity_at": null
}
}contact.updated
Contacts
A contact's details changed: fields, stage, assignment, or tags.
Payload
idstringrequiredUnique id for this event, shared by every endpoint it fans out to and stable across retries.
typestringrequiredThe event type.
created_attimestamprequiredWhen the event occurred.
dataobjectrequiredThe contact, as GET /v1/contacts/{contact_id} returns it.
Show child attributesHide child attributes
idstringrequiredfirst_namestringrequiredlast_namestringrequiredemailnullable stringrequiredphonenullable stringrequiredemailsarray of objectsrequiredEvery ordered email address; email above remains the primary shortcut.
Show child attributesHide child attributes
idstringrequiredvaluestringrequiredlabelstringrequiredHome | Work | Other
is_primarybooleanrequiredpositionintegerrequiredphonesarray of objectsrequiredEvery ordered phone number; phone above remains the primary shortcut.
Show child attributesHide child attributes
idstringrequiredvaluestringrequiredlabelstringrequiredMobile | Home | Work | Fax | Other
is_primarybooleanrequiredpositionintegerrequiredaddressnullable stringrequiredcitynullable stringrequiredstatenullable stringrequiredzip_codenullable stringrequiredcompanynullable stringrequiredjob_titlenullable stringrequirednotesnullable stringrequiredFree-form notes shown on the contact record.
stagenullable objectrequiredPipeline stage of the contact, from /v1/contact-stages.
Show child attributesHide child attributes
idstringrequirednamestringrequiredlead_sourcenullable objectrequiredWhere the contact came from, from /v1/lead-sources.
Show child attributesHide child attributes
idstringrequirednamestringrequiredownernullable objectrequiredTeam member the contact is assigned to.
Show child attributesHide child attributes
idstringrequirednamestringrequiredtagsarray of objectsrequiredWorkspace tags on the contact.
Show child attributesHide child attributes
idstringrequirednamestringrequiredcolornullable stringrequiredcustom_fieldsobjectrequiredValues for the workspace's custom fields, keyed by field id.
created_attimestamprequiredupdated_attimestamprequiredlast_activity_atnullable timestamprequiredLast time an activity touched this contact.
{
"id": "evt_1f8b4c9d2e0a4b7f9c3d5e6f7a8b9c0d",
"type": "contact.updated",
"created_at": "2026-07-02T16:20:00Z",
"data": {
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"first_name": "Dana",
"last_name": "Whitaker",
"email": "dana@example.com",
"phone": "+12065550123",
"emails": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"value": "…",
"label": "…",
"is_primary": true,
"position": 0
}
],
"phones": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"value": "…",
"label": "…",
"is_primary": true,
"position": 0
}
],
"address": null,
"city": null,
"state": null,
"zip_code": null,
"company": null,
"job_title": null,
"notes": null,
"stage": null,
"lead_source": null,
"owner": null,
"tags": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Buyer",
"color": "#26c2e7"
}
],
"custom_fields": {},
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z",
"last_activity_at": null
}
}contact.deleted
Contacts
A contact was deleted.
Payload
idstringrequiredUnique id for this event, shared by every endpoint it fans out to and stable across retries.
typestringrequiredThe event type.
created_attimestamprequiredWhen the event occurred.
dataobjectrequiredThe deleted object is gone; only its id remains.
Show child attributesHide child attributes
idstringrequiredId of the deleted object.
{
"id": "evt_1f8b4c9d2e0a4b7f9c3d5e6f7a8b9c0d",
"type": "contact.deleted",
"created_at": "2026-07-02T16:20:00Z",
"data": {
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21"
}
}deal.created
Deals
A deal was created in a pipeline.
Payload
idstringrequiredUnique id for this event, shared by every endpoint it fans out to and stable across retries.
typestringrequiredThe event type.
created_attimestamprequiredWhen the event occurred.
dataobjectrequiredThe deal, as GET /v1/deals/{deal_id} returns it.
Show child attributesHide child attributes
idstringrequirednamestringrequiredvaluenullable stringrequiredDeal value in workspace currency, as a decimal string.
statusstringrequiredopen, won, or lost — derived from the stage's type.
pipelineobjectrequiredShow child attributesHide child attributes
idstringrequirednamestringrequiredstageobjectrequiredShow child attributesHide child attributes
idstringrequirednamestringrequiredtypestringrequiredOPEN, CLOSED_WON, or CLOSED_LOST.
contact_idnullable stringrequiredContact the deal belongs to, if linked.
listing_labelnullable stringrequiredListing linked to the deal, if any (read-only through the API).
expected_close_datenullable timestamprequiredclosed_atnullable timestamprequiredlost_reasonnullable stringrequiredWhy the deal was lost, when it sits in a closed-lost stage.
notesnullable stringrequiredcreated_attimestamprequiredupdated_attimestamprequired{
"id": "evt_1f8b4c9d2e0a4b7f9c3d5e6f7a8b9c0d",
"type": "deal.created",
"created_at": "2026-07-02T16:20:00Z",
"data": {
"id": "6b9f1a2c-3d4e-5f60-7a8b-9c0d1e2f3a4b",
"name": "1420 Terry Ave — Whitaker purchase",
"value": "725000.00",
"status": "open",
"pipeline": {
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Sales Pipeline"
},
"stage": {
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Negotiation",
"type": "OPEN"
},
"contact_id": null,
"listing_label": null,
"expected_close_date": null,
"closed_at": null,
"lost_reason": null,
"notes": null,
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z"
}
}deal.updated
Deals
A deal's details changed: name, value, status, or links.
Payload
idstringrequiredUnique id for this event, shared by every endpoint it fans out to and stable across retries.
typestringrequiredThe event type.
created_attimestamprequiredWhen the event occurred.
dataobjectrequiredThe deal, as GET /v1/deals/{deal_id} returns it.
Show child attributesHide child attributes
idstringrequirednamestringrequiredvaluenullable stringrequiredDeal value in workspace currency, as a decimal string.
statusstringrequiredopen, won, or lost — derived from the stage's type.
pipelineobjectrequiredShow child attributesHide child attributes
idstringrequirednamestringrequiredstageobjectrequiredShow child attributesHide child attributes
idstringrequirednamestringrequiredtypestringrequiredOPEN, CLOSED_WON, or CLOSED_LOST.
contact_idnullable stringrequiredContact the deal belongs to, if linked.
listing_labelnullable stringrequiredListing linked to the deal, if any (read-only through the API).
expected_close_datenullable timestamprequiredclosed_atnullable timestamprequiredlost_reasonnullable stringrequiredWhy the deal was lost, when it sits in a closed-lost stage.
notesnullable stringrequiredcreated_attimestamprequiredupdated_attimestamprequired{
"id": "evt_1f8b4c9d2e0a4b7f9c3d5e6f7a8b9c0d",
"type": "deal.updated",
"created_at": "2026-07-02T16:20:00Z",
"data": {
"id": "6b9f1a2c-3d4e-5f60-7a8b-9c0d1e2f3a4b",
"name": "1420 Terry Ave — Whitaker purchase",
"value": "725000.00",
"status": "open",
"pipeline": {
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Sales Pipeline"
},
"stage": {
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Negotiation",
"type": "OPEN"
},
"contact_id": null,
"listing_label": null,
"expected_close_date": null,
"closed_at": null,
"lost_reason": null,
"notes": null,
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z"
}
}deal.stage_changed
Deals
A deal moved to a different pipeline stage.
Payload
idstringrequiredUnique id for this event, shared by every endpoint it fans out to and stable across retries.
typestringrequiredThe event type.
created_attimestamprequiredWhen the event occurred.
dataobjectrequiredThe deal, as GET /v1/deals/{deal_id} returns it.
Show child attributesHide child attributes
idstringrequirednamestringrequiredvaluenullable stringrequiredDeal value in workspace currency, as a decimal string.
statusstringrequiredopen, won, or lost — derived from the stage's type.
pipelineobjectrequiredShow child attributesHide child attributes
idstringrequirednamestringrequiredstageobjectrequiredShow child attributesHide child attributes
idstringrequirednamestringrequiredtypestringrequiredOPEN, CLOSED_WON, or CLOSED_LOST.
contact_idnullable stringrequiredContact the deal belongs to, if linked.
listing_labelnullable stringrequiredListing linked to the deal, if any (read-only through the API).
expected_close_datenullable timestamprequiredclosed_atnullable timestamprequiredlost_reasonnullable stringrequiredWhy the deal was lost, when it sits in a closed-lost stage.
notesnullable stringrequiredcreated_attimestamprequiredupdated_attimestamprequired{
"id": "evt_1f8b4c9d2e0a4b7f9c3d5e6f7a8b9c0d",
"type": "deal.stage_changed",
"created_at": "2026-07-02T16:20:00Z",
"data": {
"id": "6b9f1a2c-3d4e-5f60-7a8b-9c0d1e2f3a4b",
"name": "1420 Terry Ave — Whitaker purchase",
"value": "725000.00",
"status": "open",
"pipeline": {
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Sales Pipeline"
},
"stage": {
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Negotiation",
"type": "OPEN"
},
"contact_id": null,
"listing_label": null,
"expected_close_date": null,
"closed_at": null,
"lost_reason": null,
"notes": null,
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z"
}
}deal.deleted
Deals
A deal was deleted.
Payload
idstringrequiredUnique id for this event, shared by every endpoint it fans out to and stable across retries.
typestringrequiredThe event type.
created_attimestamprequiredWhen the event occurred.
dataobjectrequiredThe deleted object is gone; only its id remains.
Show child attributesHide child attributes
idstringrequiredId of the deleted object.
{
"id": "evt_1f8b4c9d2e0a4b7f9c3d5e6f7a8b9c0d",
"type": "deal.deleted",
"created_at": "2026-07-02T16:20:00Z",
"data": {
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21"
}
}task.created
Tasks
A task was created.
Payload
idstringrequiredUnique id for this event, shared by every endpoint it fans out to and stable across retries.
typestringrequiredThe event type.
created_attimestamprequiredWhen the event occurred.
dataobjectrequiredThe task, as GET /v1/tasks/{task_id} returns it.
Show child attributesHide child attributes
idstringrequiredtitlestringrequireddescriptionnullable stringrequiredtypestringrequiredKind of task, e.g. todo, call, email, showing.
prioritystringrequiredlow, medium, or high.
statusstringrequiredtodo, in_progress, waiting, or done.
completedbooleanrequireddue_datenullable timestamprequiredall_daybooleanrequiredWhether the due date is a date (no time of day).
contact_idnullable stringrequiredContact the task is linked to, if any.
deal_idnullable stringrequiredDeal the task is linked to, if any.
assigneenullable objectrequiredTeam member the task is assigned to.
Show child attributesHide child attributes
idstringrequirednamestringrequiredremind_minutes_beforenullable integerrequiredReminder offset before due_date, in minutes.
completed_atnullable timestamprequiredcreated_attimestamprequiredupdated_attimestamprequired{
"id": "evt_1f8b4c9d2e0a4b7f9c3d5e6f7a8b9c0d",
"type": "task.created",
"created_at": "2026-07-02T16:20:00Z",
"data": {
"id": "a1b2c3d4-e5f6-4708-9a0b-c1d2e3f4a5b6",
"title": "Call Dana about the Terry Ave listing",
"description": null,
"type": "call",
"priority": "medium",
"status": "todo",
"completed": true,
"due_date": null,
"all_day": true,
"contact_id": null,
"deal_id": null,
"assignee": null,
"remind_minutes_before": null,
"completed_at": null,
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z"
}
}task.updated
Tasks
A task's details changed: title, due date, assignee, or status.
Payload
idstringrequiredUnique id for this event, shared by every endpoint it fans out to and stable across retries.
typestringrequiredThe event type.
created_attimestamprequiredWhen the event occurred.
dataobjectrequiredThe task, as GET /v1/tasks/{task_id} returns it.
Show child attributesHide child attributes
idstringrequiredtitlestringrequireddescriptionnullable stringrequiredtypestringrequiredKind of task, e.g. todo, call, email, showing.
prioritystringrequiredlow, medium, or high.
statusstringrequiredtodo, in_progress, waiting, or done.
completedbooleanrequireddue_datenullable timestamprequiredall_daybooleanrequiredWhether the due date is a date (no time of day).
contact_idnullable stringrequiredContact the task is linked to, if any.
deal_idnullable stringrequiredDeal the task is linked to, if any.
assigneenullable objectrequiredTeam member the task is assigned to.
Show child attributesHide child attributes
idstringrequirednamestringrequiredremind_minutes_beforenullable integerrequiredReminder offset before due_date, in minutes.
completed_atnullable timestamprequiredcreated_attimestamprequiredupdated_attimestamprequired{
"id": "evt_1f8b4c9d2e0a4b7f9c3d5e6f7a8b9c0d",
"type": "task.updated",
"created_at": "2026-07-02T16:20:00Z",
"data": {
"id": "a1b2c3d4-e5f6-4708-9a0b-c1d2e3f4a5b6",
"title": "Call Dana about the Terry Ave listing",
"description": null,
"type": "call",
"priority": "medium",
"status": "todo",
"completed": true,
"due_date": null,
"all_day": true,
"contact_id": null,
"deal_id": null,
"assignee": null,
"remind_minutes_before": null,
"completed_at": null,
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z"
}
}task.completed
Tasks
A task was marked complete.
Payload
idstringrequiredUnique id for this event, shared by every endpoint it fans out to and stable across retries.
typestringrequiredThe event type.
created_attimestamprequiredWhen the event occurred.
dataobjectrequiredThe task, as GET /v1/tasks/{task_id} returns it.
Show child attributesHide child attributes
idstringrequiredtitlestringrequireddescriptionnullable stringrequiredtypestringrequiredKind of task, e.g. todo, call, email, showing.
prioritystringrequiredlow, medium, or high.
statusstringrequiredtodo, in_progress, waiting, or done.
completedbooleanrequireddue_datenullable timestamprequiredall_daybooleanrequiredWhether the due date is a date (no time of day).
contact_idnullable stringrequiredContact the task is linked to, if any.
deal_idnullable stringrequiredDeal the task is linked to, if any.
assigneenullable objectrequiredTeam member the task is assigned to.
Show child attributesHide child attributes
idstringrequirednamestringrequiredremind_minutes_beforenullable integerrequiredReminder offset before due_date, in minutes.
completed_atnullable timestamprequiredcreated_attimestamprequiredupdated_attimestamprequired{
"id": "evt_1f8b4c9d2e0a4b7f9c3d5e6f7a8b9c0d",
"type": "task.completed",
"created_at": "2026-07-02T16:20:00Z",
"data": {
"id": "a1b2c3d4-e5f6-4708-9a0b-c1d2e3f4a5b6",
"title": "Call Dana about the Terry Ave listing",
"description": null,
"type": "call",
"priority": "medium",
"status": "todo",
"completed": true,
"due_date": null,
"all_day": true,
"contact_id": null,
"deal_id": null,
"assignee": null,
"remind_minutes_before": null,
"completed_at": null,
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z"
}
}task.deleted
Tasks
A task was deleted.
Payload
idstringrequiredUnique id for this event, shared by every endpoint it fans out to and stable across retries.
typestringrequiredThe event type.
created_attimestamprequiredWhen the event occurred.
dataobjectrequiredThe deleted object is gone; only its id remains.
Show child attributesHide child attributes
idstringrequiredId of the deleted object.
{
"id": "evt_1f8b4c9d2e0a4b7f9c3d5e6f7a8b9c0d",
"type": "task.deleted",
"created_at": "2026-07-02T16:20:00Z",
"data": {
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21"
}
}listing.created
Listings
A listing was added to the workspace. MLS feed syncs do not emit events.
Payload
idstringrequiredUnique id for this event, shared by every endpoint it fans out to and stable across retries.
typestringrequiredThe event type.
created_attimestamprequiredWhen the event occurred.
dataobjectrequiredThe listing, as GET /v1/listings/{listing_id} returns it.
Show child attributesHide child attributes
idstringrequiredsourcestringrequiredHow the listing entered the system: manual, mls_import, or url_import. Only manual listings can be edited through the API.
statusstringrequireddraft, active, pending, sold, or off_market. Draft listings stay off websites and property alerts.
listing_typestringrequiredsale or rental. For rentals, list_price is the asking rent per month and close_price the agreed rent once leased.
street_addressstringrequiredcitystringrequiredstate_or_provincestringrequiredpostal_codestringrequiredcountynullable stringrequiredlatitudenullable numberrequiredlongitudenullable numberrequiredproperty_typenullable stringrequiredproperty_sub_typenullable stringrequiredlist_pricenullable integerrequiredWhole dollars.
close_pricenullable integerrequiredWhole dollars; set when the listing sold.
bedrooms_totalnullable integerrequiredbathrooms_fullnullable integerrequiredbathrooms_halfnullable integerrequiredliving_areanullable integerrequiredInterior square footage.
lot_size_acresnullable numberrequiredyear_builtnullable integerrequireddescriptionnullable stringrequiredfeaturesarray of stringsrequiredFeature bullet points shown on websites.
virtual_tour_urlnullable stringrequiredphotosarray of stringsrequiredPhoto URLs, in display order. Read-only.
created_attimestamprequiredupdated_attimestamprequired{
"id": "evt_1f8b4c9d2e0a4b7f9c3d5e6f7a8b9c0d",
"type": "listing.created",
"created_at": "2026-07-02T16:20:00Z",
"data": {
"id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"source": "manual",
"status": "active",
"listing_type": "sale",
"street_address": "1420 Terry Ave #1903",
"city": "Seattle",
"state_or_province": "WA",
"postal_code": "98101",
"county": null,
"latitude": null,
"longitude": null,
"property_type": "Condominium",
"property_sub_type": null,
"list_price": 725000,
"close_price": null,
"bedrooms_total": null,
"bathrooms_full": null,
"bathrooms_half": null,
"living_area": null,
"lot_size_acres": null,
"year_built": null,
"description": null,
"features": [
"Corner unit",
"City views",
"2 parking spaces"
],
"virtual_tour_url": null,
"photos": [
"…"
],
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z"
}
}listing.updated
Listings
A listing's details changed.
Payload
idstringrequiredUnique id for this event, shared by every endpoint it fans out to and stable across retries.
typestringrequiredThe event type.
created_attimestamprequiredWhen the event occurred.
dataobjectrequiredThe listing, as GET /v1/listings/{listing_id} returns it.
Show child attributesHide child attributes
idstringrequiredsourcestringrequiredHow the listing entered the system: manual, mls_import, or url_import. Only manual listings can be edited through the API.
statusstringrequireddraft, active, pending, sold, or off_market. Draft listings stay off websites and property alerts.
listing_typestringrequiredsale or rental. For rentals, list_price is the asking rent per month and close_price the agreed rent once leased.
street_addressstringrequiredcitystringrequiredstate_or_provincestringrequiredpostal_codestringrequiredcountynullable stringrequiredlatitudenullable numberrequiredlongitudenullable numberrequiredproperty_typenullable stringrequiredproperty_sub_typenullable stringrequiredlist_pricenullable integerrequiredWhole dollars.
close_pricenullable integerrequiredWhole dollars; set when the listing sold.
bedrooms_totalnullable integerrequiredbathrooms_fullnullable integerrequiredbathrooms_halfnullable integerrequiredliving_areanullable integerrequiredInterior square footage.
lot_size_acresnullable numberrequiredyear_builtnullable integerrequireddescriptionnullable stringrequiredfeaturesarray of stringsrequiredFeature bullet points shown on websites.
virtual_tour_urlnullable stringrequiredphotosarray of stringsrequiredPhoto URLs, in display order. Read-only.
created_attimestamprequiredupdated_attimestamprequired{
"id": "evt_1f8b4c9d2e0a4b7f9c3d5e6f7a8b9c0d",
"type": "listing.updated",
"created_at": "2026-07-02T16:20:00Z",
"data": {
"id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"source": "manual",
"status": "active",
"listing_type": "sale",
"street_address": "1420 Terry Ave #1903",
"city": "Seattle",
"state_or_province": "WA",
"postal_code": "98101",
"county": null,
"latitude": null,
"longitude": null,
"property_type": "Condominium",
"property_sub_type": null,
"list_price": 725000,
"close_price": null,
"bedrooms_total": null,
"bathrooms_full": null,
"bathrooms_half": null,
"living_area": null,
"lot_size_acres": null,
"year_built": null,
"description": null,
"features": [
"Corner unit",
"City views",
"2 parking spaces"
],
"virtual_tour_url": null,
"photos": [
"…"
],
"created_at": "2026-07-02T16:20:00Z",
"updated_at": "2026-07-02T16:20:00Z"
}
}listing.deleted
Listings
A listing was removed from the workspace.
Payload
idstringrequiredUnique id for this event, shared by every endpoint it fans out to and stable across retries.
typestringrequiredThe event type.
created_attimestamprequiredWhen the event occurred.
dataobjectrequiredThe deleted object is gone; only its id remains.
Show child attributesHide child attributes
idstringrequiredId of the deleted object.
{
"id": "evt_1f8b4c9d2e0a4b7f9c3d5e6f7a8b9c0d",
"type": "listing.deleted",
"created_at": "2026-07-02T16:20:00Z",
"data": {
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21"
}
}ping
Test
An on-demand test delivery, sent from Settings → Webhooks → Send test. Not subscribable — any active endpoint can receive it.
Payload
idstringrequiredUnique id for this event, shared by every endpoint it fans out to and stable across retries.
typestringrequiredThe event type.
created_attimestamprequiredWhen the event occurred.
dataobjectrequiredShow child attributesHide child attributes
messagestringrequiredwebhook_idstringrequiredId of the endpoint the test was sent to.
{
"id": "evt_1f8b4c9d2e0a4b7f9c3d5e6f7a8b9c0d",
"type": "ping",
"created_at": "2026-07-02T16:20:00Z",
"data": {
"message": "Test delivery from Uplevel. Your endpoint is receiving events.",
"webhook_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21"
}
}Reference
Workspace reference data: pipelines, stages, lead sources, tags, and members. Read-only; manage these in the dashboard.
List pipelines
GET/v1/pipelines
The workspace's deal pipelines with their stages — the vocabulary for creating and moving deals.
Returns
200All pipelines with stages.401Missing or invalid API key.403The key lacks the read_deals scope.Response attributes
dataarray of objectsrequiredShow child attributesHide child attributes
idstringrequirednamestringrequiredis_activebooleanrequiredstagesarray of objectsrequiredStages in board order.
Show child attributesHide child attributes
idstringrequirednamestringrequiredtypestringrequiredOPEN, CLOSED_WON, or CLOSED_LOST.
probabilityintegerrequiredWin probability percentage used for weighted forecasts.
positionintegerrequiredcurl "https://api.uplevelre.com/v1/pipelines" \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"data": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Sales Pipeline",
"is_active": true,
"stages": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Negotiation",
"type": "OPEN",
"probability": 80,
"position": 0
}
]
}
]
}List contact stages
GET/v1/contact-stages
The stages contacts move through, in board order.
Returns
200All contact stages.401Missing or invalid API key.403The key lacks the read_contacts scope.Response attributes
dataarray of objectsrequiredShow child attributesHide child attributes
idstringrequirednamestringrequiredcolorstringrequiredis_defaultbooleanrequiredApplied to new contacts when no stage is given.
positionintegerrequiredcurl "https://api.uplevelre.com/v1/contact-stages" \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"data": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Hot Lead",
"color": "#f97316",
"is_default": true,
"position": 0
}
]
}List lead sources
GET/v1/lead-sources
Returns
200All lead sources.401Missing or invalid API key.403The key lacks the read_contacts scope.Response attributes
dataarray of objectsrequiredShow child attributesHide child attributes
idstringrequirednamestringrequiredis_activebooleanrequiredcurl "https://api.uplevelre.com/v1/lead-sources" \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"data": [
{
"id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
"name": "Zillow",
"is_active": true
}
]
}List members
GET/v1/members
Returns
200All workspace members.401Missing or invalid API key.403The key lacks the read_contacts scope.Response attributes
dataarray of objectsrequiredShow child attributesHide child attributes
idstringrequiredUse as owner_id on contacts or assignee_id on tasks.
namestringrequiredemailstringrequiredrolestringrequiredowner, admin, or member.
curl "https://api.uplevelre.com/v1/members" \
-H "Authorization: Bearer $UPLEVEL_API_KEY"{
"data": [
{
"id": "3b241101-e2bb-4255-8caf-4136c566a962",
"name": "Alex Rivera",
"email": "alex@acme-realty.com",
"role": "member"
}
]
}