Uplevel

API Reference

v1https://api.uplevelre.com

Introduction

The Uplevel API gives you programmatic access to your workspace: contacts, deals, tasks, activities, listings, and webhooks.

Base URL
https://api.uplevelre.com

Authentication

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.

Authentication
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:

Statuserror.typeMeaning
400invalid_request_errorMalformed request or invalid field.
401authentication_errorMissing, revoked, or expired API key.
403permission_errorThe key lacks a scope, or the plan excludes the feature.
404invalid_request_errorThe requested object does not exist.
415invalid_request_errorThe request has a body but no Content-Type: application/json header.
429rate_limit_errorRate limit exceeded — see Retry-After.
5xxapi_errorSomething failed on our side. Safe to retry with backoff.
Example
{
  "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.

Example
{ "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:

HeaderValue
X-Uplevel-EventThe event type, e.g. contact.created.
X-Uplevel-Event-IdThe event id, shared by every endpoint the event fanned out to.
X-Uplevel-Delivery-IdUnique per endpoint and event; constant across retries — deduplicate on it.
X-Uplevel-Signaturet=<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.

Verifying an endpoint
if (event.type === "webhook.verification") {
  return res.json({ challenge: event.data.challenge });
}
Example
{
  "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.

Verifying deliveries
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"));
}

API

Introspection endpoints for the key you are calling with.

Endpoints

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

workspaceobjectrequired

Workspace the key belongs to.

Show child attributes
idstringrequired
namestringrequired
slugstringrequired
api_keyobjectrequired

The key itself (never the secret).

Show child attributes
idstringrequired
key_prefixstringrequired

Identifying fragment of the secret, as shown in Settings.

scopesarray of stringsrequired

Scopes granted to this key.

rate_limit_per_minuteintegerrequired

Requests per minute this workspace may make, across all keys.

GET /v1/me
curl "https://api.uplevelre.com/v1/me" \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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

limitinteger

Objects per page, 1–100.

cursorstring

Opaque cursor from a previous response's next_cursor; returns results strictly after it.

qstring

Free-text search over name, email, phone, and company.

stage_idstring

Only contacts in this stage (see /v1/contact-stages).

lead_source_idstring

Only contacts from this lead source (see /v1/lead-sources).

owner_idstring

Only contacts assigned to this member (see /v1/members).

tag_idstring

Only contacts carrying this tag (see /v1/tags).

emailstring

Only contacts with this exact email.

created_aftertimestamp

Only contacts created at or after this RFC 3339 timestamp.

created_beforetimestamp

Only contacts created at or before this RFC 3339 timestamp.

updated_aftertimestamp

Only 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 objectsrequired
Show child attributes
idstringrequired
first_namestringrequired
last_namestringrequired
emailnullable stringrequired
phonenullable stringrequired
emailsarray of objectsrequired

Every ordered email address; email above remains the primary shortcut.

Show child attributes
idstringrequired
valuestringrequired
labelstringrequired

Home | Work | Other

is_primarybooleanrequired
positionintegerrequired
phonesarray of objectsrequired

Every ordered phone number; phone above remains the primary shortcut.

Show child attributes
idstringrequired
valuestringrequired
labelstringrequired

Mobile | Home | Work | Fax | Other

is_primarybooleanrequired
positionintegerrequired
addressnullable stringrequired
citynullable stringrequired
statenullable stringrequired
zip_codenullable stringrequired
companynullable stringrequired
job_titlenullable stringrequired
notesnullable stringrequired

Free-form notes shown on the contact record.

stagenullable objectrequired

Pipeline stage of the contact, from /v1/contact-stages.

Show child attributes
idstringrequired
namestringrequired
lead_sourcenullable objectrequired

Where the contact came from, from /v1/lead-sources.

Show child attributes
idstringrequired
namestringrequired
ownernullable objectrequired

Team member the contact is assigned to.

Show child attributes
idstringrequired
namestringrequired
tagsarray of objectsrequired

Workspace tags on the contact.

Show child attributes
idstringrequired
namestringrequired
colornullable stringrequired
custom_fieldsobjectrequired

Values for the workspace's custom fields, keyed by field id.

created_attimestamprequired
updated_attimestamprequired
last_activity_atnullable timestamprequired

Last time an activity touched this contact.

has_morebooleanrequired

Whether another page exists after this one.

next_cursornullable string

Pass as ?cursor= to fetch the next page. Left out on the last page.

total_countintegerrequired

Total objects matching the query across all pages.

GET /v1/contacts
curl "https://api.uplevelre.com/v1/contacts?limit=25&q=dana" \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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_namestringrequired
last_namestringrequired
emailnullable string
phonenullable string
emailsnullable array of objects

Full email list. When omitted, email becomes the sole primary row.

Show child attributes
valuestringrequired
labelstringrequired

Home | Work | Other

idnullable string

Id of an existing row to keep; leave it out for a new one.

is_primarynullable boolean
positionnullable integer
phonesnullable array of objects

Full phone list. When omitted, phone becomes the sole primary row.

Show child attributes
valuestringrequired
labelstringrequired

Mobile | Home | Work | Fax | Other

idnullable string

Id of an existing row to keep; leave it out for a new one.

is_primarynullable boolean
positionnullable integer
addressnullable string
citynullable string
statenullable string
zip_codenullable string
companynullable string
job_titlenullable string
notesnullable string
stage_idnullable string

Stage id from /v1/contact-stages.

lead_source_idnullable string

Lead source id from /v1/lead-sources.

owner_idnullable string

Member id from /v1/members to assign the contact to. Omit to leave the contact unassigned.

custom_fieldsnullable object

Values 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

idstringrequired
first_namestringrequired
last_namestringrequired
emailnullable stringrequired
phonenullable stringrequired
emailsarray of objectsrequired

Every ordered email address; email above remains the primary shortcut.

Show child attributes
idstringrequired
valuestringrequired
labelstringrequired

Home | Work | Other

is_primarybooleanrequired
positionintegerrequired
phonesarray of objectsrequired

Every ordered phone number; phone above remains the primary shortcut.

Show child attributes
idstringrequired
valuestringrequired
labelstringrequired

Mobile | Home | Work | Fax | Other

is_primarybooleanrequired
positionintegerrequired
addressnullable stringrequired
citynullable stringrequired
statenullable stringrequired
zip_codenullable stringrequired
companynullable stringrequired
job_titlenullable stringrequired
notesnullable stringrequired

Free-form notes shown on the contact record.

stagenullable objectrequired

Pipeline stage of the contact, from /v1/contact-stages.

Show child attributes
idstringrequired
namestringrequired
lead_sourcenullable objectrequired

Where the contact came from, from /v1/lead-sources.

Show child attributes
idstringrequired
namestringrequired
ownernullable objectrequired

Team member the contact is assigned to.

Show child attributes
idstringrequired
namestringrequired
tagsarray of objectsrequired

Workspace tags on the contact.

Show child attributes
idstringrequired
namestringrequired
colornullable stringrequired
custom_fieldsobjectrequired

Values for the workspace's custom fields, keyed by field id.

created_attimestamprequired
updated_attimestamprequired
last_activity_atnullable timestamprequired

Last time an activity touched this contact.

POST /v1/contacts
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"
  }'
Response201
{
  "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_idstringrequired

Id of the contact.

Returns

200The contact.
401Missing or invalid API key.
404No contact with that id.

Response attributes

idstringrequired
first_namestringrequired
last_namestringrequired
emailnullable stringrequired
phonenullable stringrequired
emailsarray of objectsrequired

Every ordered email address; email above remains the primary shortcut.

Show child attributes
idstringrequired
valuestringrequired
labelstringrequired

Home | Work | Other

is_primarybooleanrequired
positionintegerrequired
phonesarray of objectsrequired

Every ordered phone number; phone above remains the primary shortcut.

Show child attributes
idstringrequired
valuestringrequired
labelstringrequired

Mobile | Home | Work | Fax | Other

is_primarybooleanrequired
positionintegerrequired
addressnullable stringrequired
citynullable stringrequired
statenullable stringrequired
zip_codenullable stringrequired
companynullable stringrequired
job_titlenullable stringrequired
notesnullable stringrequired

Free-form notes shown on the contact record.

stagenullable objectrequired

Pipeline stage of the contact, from /v1/contact-stages.

Show child attributes
idstringrequired
namestringrequired
lead_sourcenullable objectrequired

Where the contact came from, from /v1/lead-sources.

Show child attributes
idstringrequired
namestringrequired
ownernullable objectrequired

Team member the contact is assigned to.

Show child attributes
idstringrequired
namestringrequired
tagsarray of objectsrequired

Workspace tags on the contact.

Show child attributes
idstringrequired
namestringrequired
colornullable stringrequired
custom_fieldsobjectrequired

Values for the workspace's custom fields, keyed by field id.

created_attimestamprequired
updated_attimestamprequired
last_activity_atnullable timestamprequired

Last time an activity touched this contact.

GET /v1/contacts/{contact_id}
curl "https://api.uplevelre.com/v1/contacts/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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_idstringrequired

Id of the contact.

Body parameters

first_namenullable string
last_namenullable string
emailnullable string
phonenullable string
emailsnullable array of objects

Replaces the full email list when present.

Show child attributes
valuestringrequired
labelstringrequired

Home | Work | Other

idnullable string

Id of an existing row to keep; leave it out for a new one.

is_primarynullable boolean
positionnullable integer
phonesnullable array of objects

Replaces the full phone list when present.

Show child attributes
valuestringrequired
labelstringrequired

Mobile | Home | Work | Fax | Other

idnullable string

Id of an existing row to keep; leave it out for a new one.

is_primarynullable boolean
positionnullable integer
addressnullable string
citynullable string
statenullable string
zip_codenullable string
companynullable string
job_titlenullable string
notesnullable string
stage_idnullable string

Stage id from /v1/contact-stages; empty string clears the stage.

lead_source_idnullable string

Lead source id from /v1/lead-sources; empty string clears it.

owner_idnullable string

Member id from /v1/members; empty string unassigns the contact.

custom_fieldsnullable object

Replaces 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

idstringrequired
first_namestringrequired
last_namestringrequired
emailnullable stringrequired
phonenullable stringrequired
emailsarray of objectsrequired

Every ordered email address; email above remains the primary shortcut.

Show child attributes
idstringrequired
valuestringrequired
labelstringrequired

Home | Work | Other

is_primarybooleanrequired
positionintegerrequired
phonesarray of objectsrequired

Every ordered phone number; phone above remains the primary shortcut.

Show child attributes
idstringrequired
valuestringrequired
labelstringrequired

Mobile | Home | Work | Fax | Other

is_primarybooleanrequired
positionintegerrequired
addressnullable stringrequired
citynullable stringrequired
statenullable stringrequired
zip_codenullable stringrequired
companynullable stringrequired
job_titlenullable stringrequired
notesnullable stringrequired

Free-form notes shown on the contact record.

stagenullable objectrequired

Pipeline stage of the contact, from /v1/contact-stages.

Show child attributes
idstringrequired
namestringrequired
lead_sourcenullable objectrequired

Where the contact came from, from /v1/lead-sources.

Show child attributes
idstringrequired
namestringrequired
ownernullable objectrequired

Team member the contact is assigned to.

Show child attributes
idstringrequired
namestringrequired
tagsarray of objectsrequired

Workspace tags on the contact.

Show child attributes
idstringrequired
namestringrequired
colornullable stringrequired
custom_fieldsobjectrequired

Values for the workspace's custom fields, keyed by field id.

created_attimestamprequired
updated_attimestamprequired
last_activity_atnullable timestamprequired

Last time an activity touched this contact.

PATCH /v1/contacts/{contact_id}
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"
  }'
Response200
{
  "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_idstringrequired

Id of the contact.

Returns

200Deletion confirmation.
401Missing or invalid API key.
404No contact with that id.

Response attributes

idstringrequired

Id of the deleted object.

deletedbooleanrequired
DELETE /v1/contacts/{contact_id}
curl "https://api.uplevelre.com/v1/contacts/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
  -X DELETE \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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_idstringrequired

Id of the contact.

tag_idstringrequired

Id of the workspace tag.

Returns

200The contact with the tag applied.
401Missing or invalid API key.
404No such contact or tag.

Response attributes

idstringrequired
first_namestringrequired
last_namestringrequired
emailnullable stringrequired
phonenullable stringrequired
emailsarray of objectsrequired

Every ordered email address; email above remains the primary shortcut.

Show child attributes
idstringrequired
valuestringrequired
labelstringrequired

Home | Work | Other

is_primarybooleanrequired
positionintegerrequired
phonesarray of objectsrequired

Every ordered phone number; phone above remains the primary shortcut.

Show child attributes
idstringrequired
valuestringrequired
labelstringrequired

Mobile | Home | Work | Fax | Other

is_primarybooleanrequired
positionintegerrequired
addressnullable stringrequired
citynullable stringrequired
statenullable stringrequired
zip_codenullable stringrequired
companynullable stringrequired
job_titlenullable stringrequired
notesnullable stringrequired

Free-form notes shown on the contact record.

stagenullable objectrequired

Pipeline stage of the contact, from /v1/contact-stages.

Show child attributes
idstringrequired
namestringrequired
lead_sourcenullable objectrequired

Where the contact came from, from /v1/lead-sources.

Show child attributes
idstringrequired
namestringrequired
ownernullable objectrequired

Team member the contact is assigned to.

Show child attributes
idstringrequired
namestringrequired
tagsarray of objectsrequired

Workspace tags on the contact.

Show child attributes
idstringrequired
namestringrequired
colornullable stringrequired
custom_fieldsobjectrequired

Values for the workspace's custom fields, keyed by field id.

created_attimestamprequired
updated_attimestamprequired
last_activity_atnullable timestamprequired

Last time an activity touched this contact.

PUT /v1/contacts/{contact_id}/tags/{tag_id}
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"
Response200
{
  "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_idstringrequired

Id of the contact.

tag_idstringrequired

Id of the workspace tag.

Returns

200The contact with the tag removed.
401Missing or invalid API key.
404No such contact.

Response attributes

idstringrequired
first_namestringrequired
last_namestringrequired
emailnullable stringrequired
phonenullable stringrequired
emailsarray of objectsrequired

Every ordered email address; email above remains the primary shortcut.

Show child attributes
idstringrequired
valuestringrequired
labelstringrequired

Home | Work | Other

is_primarybooleanrequired
positionintegerrequired
phonesarray of objectsrequired

Every ordered phone number; phone above remains the primary shortcut.

Show child attributes
idstringrequired
valuestringrequired
labelstringrequired

Mobile | Home | Work | Fax | Other

is_primarybooleanrequired
positionintegerrequired
addressnullable stringrequired
citynullable stringrequired
statenullable stringrequired
zip_codenullable stringrequired
companynullable stringrequired
job_titlenullable stringrequired
notesnullable stringrequired

Free-form notes shown on the contact record.

stagenullable objectrequired

Pipeline stage of the contact, from /v1/contact-stages.

Show child attributes
idstringrequired
namestringrequired
lead_sourcenullable objectrequired

Where the contact came from, from /v1/lead-sources.

Show child attributes
idstringrequired
namestringrequired
ownernullable objectrequired

Team member the contact is assigned to.

Show child attributes
idstringrequired
namestringrequired
tagsarray of objectsrequired

Workspace tags on the contact.

Show child attributes
idstringrequired
namestringrequired
colornullable stringrequired
custom_fieldsobjectrequired

Values for the workspace's custom fields, keyed by field id.

created_attimestamprequired
updated_attimestamprequired
last_activity_atnullable timestamprequired

Last time an activity touched this contact.

DELETE /v1/contacts/{contact_id}/tags/{tag_id}
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"
Response200
{
  "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_idstringrequired

Id of the contact.

Query parameters

limitinteger

Objects per page, 1–100.

cursorstring

Opaque 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 objectsrequired
Show child attributes
idstringrequired
typestringrequired

Kind of entry: note, call, email, contact_created, contact_updated, stage_changed, owner_changed, and similar system types.

titlestringrequired
descriptionnullable stringrequired
metadatanullable objectrequired

Entry-specific details (for example the fields an update changed).

actor_namenullable stringrequired

Team member who performed the action; null for automated entries and API writes.

created_attimestamprequired
has_morebooleanrequired

Whether another page exists after this one.

next_cursornullable string

Pass as ?cursor= to fetch the next page. Left out on the last page.

total_countintegerrequired

Total objects matching the query across all pages.

GET /v1/contacts/{contact_id}/activities
curl "https://api.uplevelre.com/v1/contacts/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21/activities?limit=25" \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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_idstringrequired

Id of the contact.

Body parameters

bodystringrequired

The 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

idstringrequired
typestringrequired

Kind of entry: note, call, email, contact_created, contact_updated, stage_changed, owner_changed, and similar system types.

titlestringrequired
descriptionnullable stringrequired
metadatanullable objectrequired

Entry-specific details (for example the fields an update changed).

actor_namenullable stringrequired

Team member who performed the action; null for automated entries and API writes.

created_attimestamprequired
POST /v1/contacts/{contact_id}/notes
curl "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."
  }'
Response201
{
  "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

statusstring

Only transactions with this status: active, pending, closed, or fell_through.

sidestring

Only transactions on this side: buyer, seller, or both.

searchstring

Case-insensitive match against the name, listing label, or contact name.

contact_idstring

Only transactions linked to this contact.

deal_idstring

Only transactions linked to this deal.

stage_idstring

Only transactions in this closing stage.

closing_fromstring

Only transactions projected or actually closing on or after this YYYY-MM-DD date.

closing_tostring

Only transactions projected or actually closing on or before this YYYY-MM-DD date.

limitinteger

Transactions per page, up to 200. Leave it out for the default.

offsetinteger

Matching 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

countsobjectrequired

Transactions per semantic status across every match, ignoring paging. Counts are 64-bit integers encoded as strings.

Show child attributes
activestringrequired
closedstringrequired
fell_throughstringrequired
pendingstringrequired
dataarray of objectsrequired
Show child attributes
actual_close_datestringrequired

Closing date, YYYY-MM-DD; set when the transaction closes.

appraisal_datestringrequired

Appraisal deadline, YYYY-MM-DD; empty when not set.

brokerage_split_ratestringrequired

Brokerage split as a percent of GCI after the referral fee.

commission_ratestringrequired

Commission rate as a percent, e.g. 3.00.

contact_emailstringrequired
contact_first_namestringrequired
contact_idstringrequired

Linked contact; empty when there is none.

contact_last_namestringrequired
contract_datestringrequired

Contract date, YYYY-MM-DD; empty when not set.

created_attimestamprequired
deal_idstringrequired

Linked deal; empty when there is none.

deal_namestringrequired
deal_statusstringrequired

The linked deal's open, won, or lost status.

document_countintegerrequired

Number of documents stored on the transaction.

earnest_money_due_datestringrequired

Earnest money deadline, YYYY-MM-DD; empty when not set.

fell_through_reasonstringrequired

Why the transaction fell through; empty otherwise.

financing_datestringrequired

Financing deadline, YYYY-MM-DD; empty when not set.

gci_overridebooleanrequired

Whether gross_commission was entered directly instead of derived.

gross_commissionstringrequired

Gross commission income, as a decimal string. Derived from sale_price × commission_rate unless gci_override is set.

idstringrequired
inspection_datestringrequired

Inspection deadline, YYYY-MM-DD; empty when not set.

listing_keystringrequired

MLS listing key; empty unless the property is an MLS listing.

listing_labelstringrequired

The property's address or label.

listing_photo_pathstringrequired

Path to the property's primary photo; empty when there is none.

namestringrequired
net_commissionstringrequired

What the agent keeps, as a decimal string: (GCI − referral fee) × (1 − brokerage split − team split) − transaction fees. Always derived.

notesstringrequired
possession_datestringrequired

Possession date, YYYY-MM-DD; empty when not set.

projected_close_datestringrequired

Expected closing date, YYYY-MM-DD; empty when not set.

referral_feestringrequired

Referral fee taken off the top, as a decimal string.

sale_pricestringrequired

Sale price, as a decimal string.

sidestringrequired

buyer, seller, or both.

stage_idstringrequired

Closing stage the transaction sits in.

stage_namestringrequired
statusstringrequired

active, pending, closed, or fell_through, from the closing stage the transaction sits in.

team_split_ratestringrequired

Team split as a percent of GCI after the referral fee.

transaction_feesstringrequired

Flat transaction fees, as a decimal string.

updated_attimestamprequired
walkthrough_datestringrequired

Final walkthrough, YYYY-MM-DD; empty when not set.

GET /v1/transactions
curl "https://api.uplevelre.com/v1/transactions" \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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 string

Leave empty to name it after the listing, the deal, or the contact.

sidenullable string

buyer, seller, or both. Defaults to buyer.

statusnullable string

active, pending, closed, or fell_through. Defaults to active.

deal_idnullable string

Deal to link (see /v1/deals).

contact_idnullable string

Contact to link (see /v1/contacts).

listing_keynullable string

MLS listing key of the property.

sale_pricenullable string
commission_ratenullable string

Percent, e.g. 3.00.

projected_close_datenullable string
notesnullable string
stage_idnullable string

Closing stage to start in (see /v1/transaction-settings).

checklist_template_idnullable string

Checklist template to apply (see /v1/transaction-settings).

idempotency_keynullable string

Reuse 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_datestringrequired

Closing date, YYYY-MM-DD; set when the transaction closes.

appraisal_datestringrequired

Appraisal deadline, YYYY-MM-DD; empty when not set.

brokerage_split_ratestringrequired

Brokerage split as a percent of GCI after the referral fee.

commission_ratestringrequired

Commission rate as a percent, e.g. 3.00.

contact_emailstringrequired
contact_first_namestringrequired
contact_idstringrequired

Linked contact; empty when there is none.

contact_last_namestringrequired
contract_datestringrequired

Contract date, YYYY-MM-DD; empty when not set.

created_attimestamprequired
deal_idstringrequired

Linked deal; empty when there is none.

deal_namestringrequired
deal_statusstringrequired

The linked deal's open, won, or lost status.

document_countintegerrequired

Number of documents stored on the transaction.

earnest_money_due_datestringrequired

Earnest money deadline, YYYY-MM-DD; empty when not set.

fell_through_reasonstringrequired

Why the transaction fell through; empty otherwise.

financing_datestringrequired

Financing deadline, YYYY-MM-DD; empty when not set.

gci_overridebooleanrequired

Whether gross_commission was entered directly instead of derived.

gross_commissionstringrequired

Gross commission income, as a decimal string. Derived from sale_price × commission_rate unless gci_override is set.

idstringrequired
inspection_datestringrequired

Inspection deadline, YYYY-MM-DD; empty when not set.

listing_keystringrequired

MLS listing key; empty unless the property is an MLS listing.

listing_labelstringrequired

The property's address or label.

listing_photo_pathstringrequired

Path to the property's primary photo; empty when there is none.

namestringrequired
net_commissionstringrequired

What the agent keeps, as a decimal string: (GCI − referral fee) × (1 − brokerage split − team split) − transaction fees. Always derived.

notesstringrequired
possession_datestringrequired

Possession date, YYYY-MM-DD; empty when not set.

projected_close_datestringrequired

Expected closing date, YYYY-MM-DD; empty when not set.

referral_feestringrequired

Referral fee taken off the top, as a decimal string.

sale_pricestringrequired

Sale price, as a decimal string.

sidestringrequired

buyer, seller, or both.

stage_idstringrequired

Closing stage the transaction sits in.

stage_namestringrequired
statusstringrequired

active, pending, closed, or fell_through, from the closing stage the transaction sits in.

team_split_ratestringrequired

Team split as a percent of GCI after the referral fee.

transaction_feesstringrequired

Flat transaction fees, as a decimal string.

updated_attimestamprequired
walkthrough_datestringrequired

Final walkthrough, YYYY-MM-DD; empty when not set.

POST /v1/transactions
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"
  }'
Response200
{
  "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

idstringrequired

Transaction 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_datestringrequired

Closing date, YYYY-MM-DD; set when the transaction closes.

appraisal_datestringrequired

Appraisal deadline, YYYY-MM-DD; empty when not set.

brokerage_split_ratestringrequired

Brokerage split as a percent of GCI after the referral fee.

commission_ratestringrequired

Commission rate as a percent, e.g. 3.00.

contact_emailstringrequired
contact_first_namestringrequired
contact_idstringrequired

Linked contact; empty when there is none.

contact_last_namestringrequired
contract_datestringrequired

Contract date, YYYY-MM-DD; empty when not set.

created_attimestamprequired
deal_idstringrequired

Linked deal; empty when there is none.

deal_namestringrequired
deal_statusstringrequired

The linked deal's open, won, or lost status.

document_countintegerrequired

Number of documents stored on the transaction.

earnest_money_due_datestringrequired

Earnest money deadline, YYYY-MM-DD; empty when not set.

fell_through_reasonstringrequired

Why the transaction fell through; empty otherwise.

financing_datestringrequired

Financing deadline, YYYY-MM-DD; empty when not set.

gci_overridebooleanrequired

Whether gross_commission was entered directly instead of derived.

gross_commissionstringrequired

Gross commission income, as a decimal string. Derived from sale_price × commission_rate unless gci_override is set.

idstringrequired
inspection_datestringrequired

Inspection deadline, YYYY-MM-DD; empty when not set.

listing_keystringrequired

MLS listing key; empty unless the property is an MLS listing.

listing_labelstringrequired

The property's address or label.

listing_photo_pathstringrequired

Path to the property's primary photo; empty when there is none.

namestringrequired
net_commissionstringrequired

What the agent keeps, as a decimal string: (GCI − referral fee) × (1 − brokerage split − team split) − transaction fees. Always derived.

notesstringrequired
possession_datestringrequired

Possession date, YYYY-MM-DD; empty when not set.

projected_close_datestringrequired

Expected closing date, YYYY-MM-DD; empty when not set.

referral_feestringrequired

Referral fee taken off the top, as a decimal string.

sale_pricestringrequired

Sale price, as a decimal string.

sidestringrequired

buyer, seller, or both.

stage_idstringrequired

Closing stage the transaction sits in.

stage_namestringrequired
statusstringrequired

active, pending, closed, or fell_through, from the closing stage the transaction sits in.

team_split_ratestringrequired

Team split as a percent of GCI after the referral fee.

transaction_feesstringrequired

Flat transaction fees, as a decimal string.

updated_attimestamprequired
walkthrough_datestringrequired

Final walkthrough, YYYY-MM-DD; empty when not set.

GET /v1/transactions/{id}
curl "https://api.uplevelre.com/v1/transactions/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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

idstringrequired

Transaction ID

Body parameters

namenullable string
sidenullable string
statusnullable string
fell_through_reasonnullable string
deal_idnullable string

Deal to link; empty string unlinks.

contact_idnullable string

Contact to link; empty string unlinks.

listing_keynullable string

MLS listing key; empty string unlinks the property.

sale_pricenullable string
commission_ratenullable string
gross_commissionnullable string

A value pins the gross commission (gci_override); an empty string derives it from sale_price × commission_rate again.

referral_feenullable string
brokerage_split_ratenullable string
team_split_ratenullable string
transaction_feesnullable string
contract_datenullable string
earnest_money_due_datenullable string
inspection_datenullable string
appraisal_datenullable string
financing_datenullable string
walkthrough_datenullable string
projected_close_datenullable string
actual_close_datenullable string
possession_datenullable string
notesnullable string
stage_idnullable string

Closing stage to move to (see /v1/transaction-settings).

deal_dispositionnullable string

Required when a linked won deal's transaction falls through: reopen, lost, or leave_won. No deal changes without it.

reopen_stage_idnullable string

The open deal stage to reopen the deal into, with reopen.

deal_lost_reasonnullable string

Why 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_datestringrequired

Closing date, YYYY-MM-DD; set when the transaction closes.

appraisal_datestringrequired

Appraisal deadline, YYYY-MM-DD; empty when not set.

brokerage_split_ratestringrequired

Brokerage split as a percent of GCI after the referral fee.

commission_ratestringrequired

Commission rate as a percent, e.g. 3.00.

contact_emailstringrequired
contact_first_namestringrequired
contact_idstringrequired

Linked contact; empty when there is none.

contact_last_namestringrequired
contract_datestringrequired

Contract date, YYYY-MM-DD; empty when not set.

created_attimestamprequired
deal_idstringrequired

Linked deal; empty when there is none.

deal_namestringrequired
deal_statusstringrequired

The linked deal's open, won, or lost status.

document_countintegerrequired

Number of documents stored on the transaction.

earnest_money_due_datestringrequired

Earnest money deadline, YYYY-MM-DD; empty when not set.

fell_through_reasonstringrequired

Why the transaction fell through; empty otherwise.

financing_datestringrequired

Financing deadline, YYYY-MM-DD; empty when not set.

gci_overridebooleanrequired

Whether gross_commission was entered directly instead of derived.

gross_commissionstringrequired

Gross commission income, as a decimal string. Derived from sale_price × commission_rate unless gci_override is set.

idstringrequired
inspection_datestringrequired

Inspection deadline, YYYY-MM-DD; empty when not set.

listing_keystringrequired

MLS listing key; empty unless the property is an MLS listing.

listing_labelstringrequired

The property's address or label.

listing_photo_pathstringrequired

Path to the property's primary photo; empty when there is none.

namestringrequired
net_commissionstringrequired

What the agent keeps, as a decimal string: (GCI − referral fee) × (1 − brokerage split − team split) − transaction fees. Always derived.

notesstringrequired
possession_datestringrequired

Possession date, YYYY-MM-DD; empty when not set.

projected_close_datestringrequired

Expected closing date, YYYY-MM-DD; empty when not set.

referral_feestringrequired

Referral fee taken off the top, as a decimal string.

sale_pricestringrequired

Sale price, as a decimal string.

sidestringrequired

buyer, seller, or both.

stage_idstringrequired

Closing stage the transaction sits in.

stage_namestringrequired
statusstringrequired

active, pending, closed, or fell_through, from the closing stage the transaction sits in.

team_split_ratestringrequired

Team split as a percent of GCI after the referral fee.

transaction_feesstringrequired

Flat transaction fees, as a decimal string.

updated_attimestamprequired
walkthrough_datestringrequired

Final walkthrough, YYYY-MM-DD; empty when not set.

PATCH /v1/transactions/{id}
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": "…"
  }'
Response200
{
  "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

idstringrequired

Transaction ID

Returns

200Deletion confirmation.
401Missing or invalid API key.
404No transaction with that id.

Response attributes

deleted_idstringrequired

Id of the deleted transaction.

successbooleanrequired
DELETE /v1/transactions/{id}
curl "https://api.uplevelre.com/v1/transactions/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
  -X DELETE \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "deleted_id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
  "success": true
}

Retrieve a transaction's closing workflow

GET/v1/transactions/{id}/workflow

Path parameters

idstringrequired

Transaction 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 objectsrequired

The transaction's timeline.

Show child attributes
created_attimestamprequired
descriptionstringrequired
idstringrequired
titlestringrequired
default_reopen_stage_idstringrequired

The deal stage a reopened deal moves to by default; empty when there is none.

partiesarray of objectsrequired

People on the transaction.

Show child attributes
contact_idstringrequired
idstringrequired
namestringrequired
relationship_label_idstringrequired

The typed relationship the party was added with; empty for another client.

rolestringrequired
reopen_stagesarray of objectsrequired

Open deal stages the linked deal can reopen into.

Show child attributes
idstringrequired
namestringrequired
tasksarray of objectsrequired

The closing checklist.

Show child attributes
completedbooleanrequired
due_datestringrequired

YYYY-MM-DD; empty when the task has no deadline.

idstringrequired
milestonestringrequired

The transaction date the task is due relative to; empty when it has none.

offset_daysintegerrequired

Days from the milestone to the due date.

titlestringrequired
GET /v1/transactions/{id}/workflow
curl "https://api.uplevelre.com/v1/transactions/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21/workflow" \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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 objectsrequired
Show child attributes
idstringrequired
itemsarray of objectsrequired
Show child attributes
idstringrequired
milestonestringrequired

Transaction date field the item is due relative to; empty means no deadline.

offset_daysintegerrequired
titlestringrequired
namestringrequired
sidestringrequired

buyer, seller, or both.

stagesarray of objectsrequired

Closing stages, in board order.

Show child attributes
archivedbooleanrequired
idstringrequired
namestringrequired
semantic_statusstringrequired

active, pending, closed, or fell_through.

sort_orderintegerrequired
GET /v1/transaction-settings
curl "https://api.uplevelre.com/v1/transaction-settings" \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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

limitinteger

Objects per page, 1–100.

cursorstring

Opaque cursor from a previous response's next_cursor; returns results strictly after it.

pipeline_idstring

Only deals in this pipeline (see /v1/pipelines).

stage_idstring

Only deals in this stage.

contact_idstring

Only deals linked to this contact.

statusstring

Only 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 objectsrequired
Show child attributes
idstringrequired
namestringrequired
valuenullable stringrequired

Deal value in workspace currency, as a decimal string.

statusstringrequired

open, won, or lost — derived from the stage's type.

pipelineobjectrequired
Show child attributes
idstringrequired
namestringrequired
stageobjectrequired
Show child attributes
idstringrequired
namestringrequired
typestringrequired

OPEN, CLOSED_WON, or CLOSED_LOST.

contact_idnullable stringrequired

Contact the deal belongs to, if linked.

listing_labelnullable stringrequired

Listing linked to the deal, if any (read-only through the API).

expected_close_datenullable timestamprequired
closed_atnullable timestamprequired
lost_reasonnullable stringrequired

Why the deal was lost, when it sits in a closed-lost stage.

notesnullable stringrequired
created_attimestamprequired
updated_attimestamprequired
has_morebooleanrequired

Whether another page exists after this one.

next_cursornullable string

Pass as ?cursor= to fetch the next page. Left out on the last page.

total_countintegerrequired

Total objects matching the query across all pages.

GET /v1/deals
curl "https://api.uplevelre.com/v1/deals?limit=25&status=open" \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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

namestringrequired
stage_idstringrequired

Stage to create the deal in (see /v1/pipelines); determines the pipeline and initial status.

valuenullable string

Deal value as a decimal string, up to 2 decimal places.

contact_idnullable string

Contact to link (see /v1/contacts).

expected_close_datenullable string

RFC 3339 timestamp or YYYY-MM-DD date.

notesnullable string

Returns

201The created deal.
400A field failed validation.
401Missing or invalid API key.
403The key lacks the write_deals scope.

Response attributes

idstringrequired
namestringrequired
valuenullable stringrequired

Deal value in workspace currency, as a decimal string.

statusstringrequired

open, won, or lost — derived from the stage's type.

pipelineobjectrequired
Show child attributes
idstringrequired
namestringrequired
stageobjectrequired
Show child attributes
idstringrequired
namestringrequired
typestringrequired

OPEN, CLOSED_WON, or CLOSED_LOST.

contact_idnullable stringrequired

Contact the deal belongs to, if linked.

listing_labelnullable stringrequired

Listing linked to the deal, if any (read-only through the API).

expected_close_datenullable timestamprequired
closed_atnullable timestamprequired
lost_reasonnullable stringrequired

Why the deal was lost, when it sits in a closed-lost stage.

notesnullable stringrequired
created_attimestamprequired
updated_attimestamprequired
POST /v1/deals
curl "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"
  }'
Response201
{
  "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_idstringrequired

Id of the deal.

Returns

200The deal.
401Missing or invalid API key.
404No deal with that id.

Response attributes

idstringrequired
namestringrequired
valuenullable stringrequired

Deal value in workspace currency, as a decimal string.

statusstringrequired

open, won, or lost — derived from the stage's type.

pipelineobjectrequired
Show child attributes
idstringrequired
namestringrequired
stageobjectrequired
Show child attributes
idstringrequired
namestringrequired
typestringrequired

OPEN, CLOSED_WON, or CLOSED_LOST.

contact_idnullable stringrequired

Contact the deal belongs to, if linked.

listing_labelnullable stringrequired

Listing linked to the deal, if any (read-only through the API).

expected_close_datenullable timestamprequired
closed_atnullable timestamprequired
lost_reasonnullable stringrequired

Why the deal was lost, when it sits in a closed-lost stage.

notesnullable stringrequired
created_attimestamprequired
updated_attimestamprequired
GET /v1/deals/{deal_id}
curl "https://api.uplevelre.com/v1/deals/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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_idstringrequired

Id of the deal.

Body parameters

namenullable string
valuenullable string

Decimal string; empty string clears the value.

stage_idnullable string

Move the deal to this stage (must be in the deal's pipeline). The stage's type updates status and closed_at.

contact_idnullable string

Contact to link; empty string unlinks.

expected_close_datenullable string

RFC 3339 timestamp or YYYY-MM-DD; empty string clears it.

lost_reasonnullable string

Recorded when moving into a closed-lost stage.

notesnullable string

Returns

200The updated deal.
400A field failed validation.
401Missing or invalid API key.
404No deal with that id.

Response attributes

idstringrequired
namestringrequired
valuenullable stringrequired

Deal value in workspace currency, as a decimal string.

statusstringrequired

open, won, or lost — derived from the stage's type.

pipelineobjectrequired
Show child attributes
idstringrequired
namestringrequired
stageobjectrequired
Show child attributes
idstringrequired
namestringrequired
typestringrequired

OPEN, CLOSED_WON, or CLOSED_LOST.

contact_idnullable stringrequired

Contact the deal belongs to, if linked.

listing_labelnullable stringrequired

Listing linked to the deal, if any (read-only through the API).

expected_close_datenullable timestamprequired
closed_atnullable timestamprequired
lost_reasonnullable stringrequired

Why the deal was lost, when it sits in a closed-lost stage.

notesnullable stringrequired
created_attimestamprequired
updated_attimestamprequired
PATCH /v1/deals/{deal_id}
curl "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"
  }'
Response200
{
  "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_idstringrequired

Id of the deal.

Returns

200Deletion confirmation.
401Missing or invalid API key.
404No deal with that id.

Response attributes

idstringrequired

Id of the deleted object.

deletedbooleanrequired
DELETE /v1/deals/{deal_id}
curl "https://api.uplevelre.com/v1/deals/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
  -X DELETE \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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

limitinteger

Objects per page, 1–100.

cursorstring

Opaque cursor from a previous response's next_cursor; returns results strictly after it.

statusstring

Only tasks with this status: todo, in_progress, waiting, done.

completedboolean

Only completed (true) or open (false) tasks.

assignee_idstring

Only tasks assigned to this member (see /v1/members).

contact_idstring

Only tasks linked to this contact.

deal_idstring

Only tasks linked to this deal.

due_beforetimestamp

Only tasks due at or before this RFC 3339 timestamp.

due_aftertimestamp

Only 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 objectsrequired
Show child attributes
idstringrequired
titlestringrequired
descriptionnullable stringrequired
typestringrequired

Kind of task, e.g. todo, call, email, showing.

prioritystringrequired

low, medium, or high.

statusstringrequired

todo, in_progress, waiting, or done.

completedbooleanrequired
due_datenullable timestamprequired
all_daybooleanrequired

Whether the due date is a date (no time of day).

contact_idnullable stringrequired

Contact the task is linked to, if any.

deal_idnullable stringrequired

Deal the task is linked to, if any.

assigneenullable objectrequired

Team member the task is assigned to.

Show child attributes
idstringrequired
namestringrequired
remind_minutes_beforenullable integerrequired

Reminder offset before due_date, in minutes.

completed_atnullable timestamprequired
created_attimestamprequired
updated_attimestamprequired
has_morebooleanrequired

Whether another page exists after this one.

total_countintegerrequired

Total objects matching the query across all pages.

next_cursornullable string

Pass as ?cursor= to fetch the next page. Left out on the last page.

GET /v1/tasks
curl "https://api.uplevelre.com/v1/tasks?limit=25" \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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

titlestringrequired
descriptionnullable string
typenullable string

Kind of task, e.g. todo, call, email, showing. Defaults to todo.

prioritynullable string

low, medium, or high. Defaults to medium.

statusnullable string

todo, in_progress, waiting, or done. Defaults to todo.

due_datenullable timestamp

RFC 3339 timestamp the task is due.

all_daynullable boolean

Whether due_date is a date without a time of day.

contact_idnullable string

Contact to link (see /v1/contacts).

deal_idnullable string

Deal to link (see /v1/deals).

assignee_idnullable string

Member to assign (see /v1/members). Omit to leave unassigned.

remind_minutes_beforenullable integer

Reminder 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

idstringrequired
titlestringrequired
descriptionnullable stringrequired
typestringrequired

Kind of task, e.g. todo, call, email, showing.

prioritystringrequired

low, medium, or high.

statusstringrequired

todo, in_progress, waiting, or done.

completedbooleanrequired
due_datenullable timestamprequired
all_daybooleanrequired

Whether the due date is a date (no time of day).

contact_idnullable stringrequired

Contact the task is linked to, if any.

deal_idnullable stringrequired

Deal the task is linked to, if any.

assigneenullable objectrequired

Team member the task is assigned to.

Show child attributes
idstringrequired
namestringrequired
remind_minutes_beforenullable integerrequired

Reminder offset before due_date, in minutes.

completed_atnullable timestamprequired
created_attimestamprequired
updated_attimestamprequired
POST /v1/tasks
curl "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": "…"
  }'
Response201
{
  "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_idstringrequired

Id of the task.

Returns

200The task.
401Missing or invalid API key.
404No task with that id.

Response attributes

idstringrequired
titlestringrequired
descriptionnullable stringrequired
typestringrequired

Kind of task, e.g. todo, call, email, showing.

prioritystringrequired

low, medium, or high.

statusstringrequired

todo, in_progress, waiting, or done.

completedbooleanrequired
due_datenullable timestamprequired
all_daybooleanrequired

Whether the due date is a date (no time of day).

contact_idnullable stringrequired

Contact the task is linked to, if any.

deal_idnullable stringrequired

Deal the task is linked to, if any.

assigneenullable objectrequired

Team member the task is assigned to.

Show child attributes
idstringrequired
namestringrequired
remind_minutes_beforenullable integerrequired

Reminder offset before due_date, in minutes.

completed_atnullable timestamprequired
created_attimestamprequired
updated_attimestamprequired
GET /v1/tasks/{task_id}
curl "https://api.uplevelre.com/v1/tasks/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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_idstringrequired

Id of the task.

Body parameters

titlenullable string
descriptionnullable string

Empty string clears the description.

typenullable string
prioritynullable string
statusnullable string

Setting done completes the task; any other status reopens it.

due_datenullable timestamp

RFC 3339 timestamp; null leaves it unchanged. Use clear_due_date to remove one.

clear_due_datenullable boolean

Set true to remove the due date (and any reminder).

all_daynullable boolean
assignee_idnullable string

Member to assign; empty string unassigns.

remind_minutes_beforenullable integer

Reminder 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

idstringrequired
titlestringrequired
descriptionnullable stringrequired
typestringrequired

Kind of task, e.g. todo, call, email, showing.

prioritystringrequired

low, medium, or high.

statusstringrequired

todo, in_progress, waiting, or done.

completedbooleanrequired
due_datenullable timestamprequired
all_daybooleanrequired

Whether the due date is a date (no time of day).

contact_idnullable stringrequired

Contact the task is linked to, if any.

deal_idnullable stringrequired

Deal the task is linked to, if any.

assigneenullable objectrequired

Team member the task is assigned to.

Show child attributes
idstringrequired
namestringrequired
remind_minutes_beforenullable integerrequired

Reminder offset before due_date, in minutes.

completed_atnullable timestamprequired
created_attimestamprequired
updated_attimestamprequired
PATCH /v1/tasks/{task_id}
curl "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": "…"
  }'
Response200
{
  "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_idstringrequired

Id of the task.

Returns

200Deletion confirmation.
401Missing or invalid API key.
404No task with that id.

Response attributes

idstringrequired

Id of the deleted object.

deletedbooleanrequired
DELETE /v1/tasks/{task_id}
curl "https://api.uplevelre.com/v1/tasks/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
  -X DELETE \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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

limitinteger

Objects per page, 1–100.

cursorstring

Opaque cursor from a previous response's next_cursor; returns results strictly after it.

statusstring

Only listings with this status.

sourcestring

Only listings from this source: manual, mls_import, url_import.

qstring

Free-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 objectsrequired
Show child attributes
idstringrequired
sourcestringrequired

How the listing entered the system: manual, mls_import, or url_import. Only manual listings can be edited through the API.

statusstringrequired

draft, active, pending, sold, or off_market. Draft listings stay off websites and property alerts.

listing_typestringrequired

sale or rental. For rentals, list_price is the asking rent per month and close_price the agreed rent once leased.

street_addressstringrequired
citystringrequired
state_or_provincestringrequired
postal_codestringrequired
countynullable stringrequired
latitudenullable numberrequired
longitudenullable numberrequired
property_typenullable stringrequired
property_sub_typenullable stringrequired
list_pricenullable integerrequired

Whole dollars.

close_pricenullable integerrequired

Whole dollars; set when the listing sold.

bedrooms_totalnullable integerrequired
bathrooms_fullnullable integerrequired
bathrooms_halfnullable integerrequired
living_areanullable integerrequired

Interior square footage.

lot_size_acresnullable numberrequired
year_builtnullable integerrequired
descriptionnullable stringrequired
featuresarray of stringsrequired

Feature bullet points shown on websites.

virtual_tour_urlnullable stringrequired
photosarray of stringsrequired

Photo URLs, in display order. Read-only.

created_attimestamprequired
updated_attimestamprequired
has_morebooleanrequired

Whether another page exists after this one.

next_cursornullable string

Pass as ?cursor= to fetch the next page. Left out on the last page.

total_countintegerrequired

Total objects matching the query across all pages.

GET /v1/listings
curl "https://api.uplevelre.com/v1/listings?limit=25&status=active" \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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_addressstringrequired
citynullable string
state_or_provincenullable string
postal_codenullable string
countynullable string
statusnullable string

draft, active, pending, sold, or off_market. Defaults to draft.

listing_typenullable string

sale or rental. Defaults to sale. For rentals, list_price is the asking rent per month.

property_typenullable string
property_sub_typenullable string
list_pricenullable integer

Whole dollars.

close_pricenullable integer
bedrooms_totalnullable integer
bathrooms_fullnullable integer
bathrooms_halfnullable integer
living_areanullable integer
lot_size_acresnullable number
year_builtnullable integer
descriptionnullable string
featuresnullable array of strings
virtual_tour_urlnullable string

Returns

201The created listing.
400A field failed validation.
401Missing or invalid API key.
403The key lacks the write_listings scope.

Response attributes

idstringrequired
sourcestringrequired

How the listing entered the system: manual, mls_import, or url_import. Only manual listings can be edited through the API.

statusstringrequired

draft, active, pending, sold, or off_market. Draft listings stay off websites and property alerts.

listing_typestringrequired

sale or rental. For rentals, list_price is the asking rent per month and close_price the agreed rent once leased.

street_addressstringrequired
citystringrequired
state_or_provincestringrequired
postal_codestringrequired
countynullable stringrequired
latitudenullable numberrequired
longitudenullable numberrequired
property_typenullable stringrequired
property_sub_typenullable stringrequired
list_pricenullable integerrequired

Whole dollars.

close_pricenullable integerrequired

Whole dollars; set when the listing sold.

bedrooms_totalnullable integerrequired
bathrooms_fullnullable integerrequired
bathrooms_halfnullable integerrequired
living_areanullable integerrequired

Interior square footage.

lot_size_acresnullable numberrequired
year_builtnullable integerrequired
descriptionnullable stringrequired
featuresarray of stringsrequired

Feature bullet points shown on websites.

virtual_tour_urlnullable stringrequired
photosarray of stringsrequired

Photo URLs, in display order. Read-only.

created_attimestamprequired
updated_attimestamprequired
POST /v1/listings
curl "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
  }'
Response201
{
  "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_idstringrequired

Id of the listing.

Returns

200The listing.
401Missing or invalid API key.
404No listing with that id.

Response attributes

idstringrequired
sourcestringrequired

How the listing entered the system: manual, mls_import, or url_import. Only manual listings can be edited through the API.

statusstringrequired

draft, active, pending, sold, or off_market. Draft listings stay off websites and property alerts.

listing_typestringrequired

sale or rental. For rentals, list_price is the asking rent per month and close_price the agreed rent once leased.

street_addressstringrequired
citystringrequired
state_or_provincestringrequired
postal_codestringrequired
countynullable stringrequired
latitudenullable numberrequired
longitudenullable numberrequired
property_typenullable stringrequired
property_sub_typenullable stringrequired
list_pricenullable integerrequired

Whole dollars.

close_pricenullable integerrequired

Whole dollars; set when the listing sold.

bedrooms_totalnullable integerrequired
bathrooms_fullnullable integerrequired
bathrooms_halfnullable integerrequired
living_areanullable integerrequired

Interior square footage.

lot_size_acresnullable numberrequired
year_builtnullable integerrequired
descriptionnullable stringrequired
featuresarray of stringsrequired

Feature bullet points shown on websites.

virtual_tour_urlnullable stringrequired
photosarray of stringsrequired

Photo URLs, in display order. Read-only.

created_attimestamprequired
updated_attimestamprequired
GET /v1/listings/{listing_id}
curl "https://api.uplevelre.com/v1/listings/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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_idstringrequired

Id of the listing.

Body parameters

street_addressnullable string
citynullable string
state_or_provincenullable string
postal_codenullable string
countynullable string
statusnullable string
listing_typenullable string

sale or rental.

property_typenullable string
property_sub_typenullable string
list_pricenullable integer
close_pricenullable integer
bedrooms_totalnullable integer
bathrooms_fullnullable integer
bathrooms_halfnullable integer
living_areanullable integer
lot_size_acresnullable number
year_builtnullable integer
descriptionnullable string
featuresnullable array of strings

Replaces the feature list wholesale when provided.

virtual_tour_urlnullable string

Returns

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

idstringrequired
sourcestringrequired

How the listing entered the system: manual, mls_import, or url_import. Only manual listings can be edited through the API.

statusstringrequired

draft, active, pending, sold, or off_market. Draft listings stay off websites and property alerts.

listing_typestringrequired

sale or rental. For rentals, list_price is the asking rent per month and close_price the agreed rent once leased.

street_addressstringrequired
citystringrequired
state_or_provincestringrequired
postal_codestringrequired
countynullable stringrequired
latitudenullable numberrequired
longitudenullable numberrequired
property_typenullable stringrequired
property_sub_typenullable stringrequired
list_pricenullable integerrequired

Whole dollars.

close_pricenullable integerrequired

Whole dollars; set when the listing sold.

bedrooms_totalnullable integerrequired
bathrooms_fullnullable integerrequired
bathrooms_halfnullable integerrequired
living_areanullable integerrequired

Interior square footage.

lot_size_acresnullable numberrequired
year_builtnullable integerrequired
descriptionnullable stringrequired
featuresarray of stringsrequired

Feature bullet points shown on websites.

virtual_tour_urlnullable stringrequired
photosarray of stringsrequired

Photo URLs, in display order. Read-only.

created_attimestamprequired
updated_attimestamprequired
PATCH /v1/listings/{listing_id}
curl "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": "…"
  }'
Response200
{
  "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_idstringrequired

Id of the listing.

Returns

200Deletion confirmation.
400The listing is not manual.
401Missing or invalid API key.
404No listing with that id.

Response attributes

idstringrequired

Id of the deleted object.

deletedbooleanrequired
DELETE /v1/listings/{listing_id}
curl "https://api.uplevelre.com/v1/listings/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
  -X DELETE \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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

limitinteger

Objects per page, 1–100.

cursorstring

Opaque 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 objectsrequired
Show child attributes
idstringrequired
namestringrequired
urlstringrequired
eventsarray of stringsrequired

Subscribed event types, or ["*"] for everything.

secret_kindstringrequired

How 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_activebooleanrequired

Whether the endpoint receives deliveries. Set to false to pause.

disabled_atnullable timestamprequired

Set when Uplevel disabled the endpoint after repeated failures. Re-enable by updating the endpoint with is_active: true.

disabled_reasonnullable stringrequired
failure_countintegerrequired

Consecutive failed delivery attempts since the last success.

last_success_atnullable timestamprequired
last_failure_atnullable timestamprequired
created_attimestamprequired
verified_atnullable timestamprequired

When 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_morebooleanrequired

Whether another page exists after this one.

next_cursornullable string

Pass as ?cursor= to fetch the next page. Left out on the last page.

total_countintegerrequired

Total objects matching the query across all pages.

GET /v1/webhooks
curl "https://api.uplevelre.com/v1/webhooks?limit=25" \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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

namestringrequired
urlstringrequired

Publicly reachable https:// endpoint to POST events to. Plain http:// is refused.

eventsarray of stringsrequired

Event 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

idstring
namestring
urlstring
eventsarray of strings

Subscribed event types, or ["*"] for everything.

secret_kindstring

How 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_activeboolean

Whether the endpoint receives deliveries. Set to false to pause.

disabled_atnullable timestamp

Set when Uplevel disabled the endpoint after repeated failures. Re-enable by updating the endpoint with is_active: true.

disabled_reasonnullable string
failure_countinteger

Consecutive failed delivery attempts since the last success.

last_success_atnullable timestamp
last_failure_atnullable timestamp
created_attimestamp
verified_atnullable timestamp

When 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.

secretstringrequired

HMAC-SHA256 signing secret for verifying deliveries. Shown once.

POST /v1/webhooks
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"
    ]
  }'
Response201
{
  "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_idstringrequired

Id of the webhook.

Returns

200The webhook endpoint.
401Missing or invalid API key.
404No webhook with that id.

Response attributes

idstringrequired
namestringrequired
urlstringrequired
eventsarray of stringsrequired

Subscribed event types, or ["*"] for everything.

secret_kindstringrequired

How 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_activebooleanrequired

Whether the endpoint receives deliveries. Set to false to pause.

disabled_atnullable timestamprequired

Set when Uplevel disabled the endpoint after repeated failures. Re-enable by updating the endpoint with is_active: true.

disabled_reasonnullable stringrequired
failure_countintegerrequired

Consecutive failed delivery attempts since the last success.

last_success_atnullable timestamprequired
last_failure_atnullable timestamprequired
created_attimestamprequired
verified_atnullable timestamprequired

When 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.

GET /v1/webhooks/{webhook_id}
curl "https://api.uplevelre.com/v1/webhooks/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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_idstringrequired

Id of the webhook.

Body parameters

namenullable string
urlnullable string

A new https:// address. The endpoint must be verified again before it receives events.

eventsnullable array of strings
is_activenullable boolean

Set 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

idstringrequired
namestringrequired
urlstringrequired
eventsarray of stringsrequired

Subscribed event types, or ["*"] for everything.

secret_kindstringrequired

How 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_activebooleanrequired

Whether the endpoint receives deliveries. Set to false to pause.

disabled_atnullable timestamprequired

Set when Uplevel disabled the endpoint after repeated failures. Re-enable by updating the endpoint with is_active: true.

disabled_reasonnullable stringrequired
failure_countintegerrequired

Consecutive failed delivery attempts since the last success.

last_success_atnullable timestamprequired
last_failure_atnullable timestamprequired
created_attimestamprequired
verified_atnullable timestamprequired

When 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.

PATCH /v1/webhooks/{webhook_id}
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": [
      "…"
    ]
  }'
Response200
{
  "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_idstringrequired

Id of the webhook.

Returns

200Deletion confirmation.
401Missing or invalid API key.
404No webhook with that id.

Response attributes

idstringrequired

Id of the deleted object.

deletedbooleanrequired
DELETE /v1/webhooks/{webhook_id}
curl "https://api.uplevelre.com/v1/webhooks/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21" \
  -X DELETE \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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_idstringrequired

Id of the webhook.

Query parameters

limitinteger

Objects per page, 1–100.

cursorstring

Opaque 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 objectsrequired
Show child attributes
idstringrequired
event_typestringrequired

Event that triggered the delivery, e.g. contact.created.

event_idstringrequired

Id of the event across all endpoints it was fanned out to.

statusstringrequired

pending, delivered, or failed.

attemptsintegerrequired

Attempts made so far (retried with backoff up to 5 times).

http_statusnullable integerrequired

HTTP status your endpoint returned, when it responded.

error_messagenullable stringrequired
delivered_atnullable timestamprequired
created_attimestamprequired
has_morebooleanrequired

Whether another page exists after this one.

next_cursornullable string

Pass as ?cursor= to fetch the next page. Left out on the last page.

total_countintegerrequired

Total objects matching the query across all pages.

GET /v1/webhooks/{webhook_id}/deliveries
curl "https://api.uplevelre.com/v1/webhooks/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21/deliveries?limit=25" \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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_idstringrequired

Id 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

idstringrequired
namestringrequired
urlstringrequired
eventsarray of stringsrequired

Subscribed event types, or ["*"] for everything.

secret_kindstringrequired

How 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_activebooleanrequired

Whether the endpoint receives deliveries. Set to false to pause.

disabled_atnullable timestamprequired

Set when Uplevel disabled the endpoint after repeated failures. Re-enable by updating the endpoint with is_active: true.

disabled_reasonnullable stringrequired
failure_countintegerrequired

Consecutive failed delivery attempts since the last success.

last_success_atnullable timestamprequired
last_failure_atnullable timestamprequired
created_attimestamprequired
verified_atnullable timestamprequired

When 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.

POST /v1/webhooks/{webhook_id}/verify
curl "https://api.uplevelre.com/v1/webhooks/8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21/verify" \
  -X POST \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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
}

transaction.created

Transactions

A transaction was created.

Payload

idstringrequired

Unique id for this event, shared by every endpoint it fans out to and stable across retries.

typestringrequired

The event type.

created_attimestamprequired

When the event occurred.

dataobjectrequired

The transaction, as GET /v1/transactions/{id} returns it.

Show child attributes
actual_close_datestringrequired

Closing date, YYYY-MM-DD; set when the transaction closes.

appraisal_datestringrequired

Appraisal deadline, YYYY-MM-DD; empty when not set.

brokerage_split_ratestringrequired

Brokerage split as a percent of GCI after the referral fee.

commission_ratestringrequired

Commission rate as a percent, e.g. 3.00.

contact_emailstringrequired
contact_first_namestringrequired
contact_idstringrequired

Linked contact; empty when there is none.

contact_last_namestringrequired
contract_datestringrequired

Contract date, YYYY-MM-DD; empty when not set.

created_attimestamprequired
deal_idstringrequired

Linked deal; empty when there is none.

deal_namestringrequired
deal_statusstringrequired

The linked deal's open, won, or lost status.

document_countintegerrequired

Number of documents stored on the transaction.

earnest_money_due_datestringrequired

Earnest money deadline, YYYY-MM-DD; empty when not set.

fell_through_reasonstringrequired

Why the transaction fell through; empty otherwise.

financing_datestringrequired

Financing deadline, YYYY-MM-DD; empty when not set.

gci_overridebooleanrequired

Whether gross_commission was entered directly instead of derived.

gross_commissionstringrequired

Gross commission income, as a decimal string. Derived from sale_price × commission_rate unless gci_override is set.

idstringrequired
inspection_datestringrequired

Inspection deadline, YYYY-MM-DD; empty when not set.

listing_keystringrequired

MLS listing key; empty unless the property is an MLS listing.

listing_labelstringrequired

The property's address or label.

listing_photo_pathstringrequired

Path to the property's primary photo; empty when there is none.

namestringrequired
net_commissionstringrequired

What the agent keeps, as a decimal string: (GCI − referral fee) × (1 − brokerage split − team split) − transaction fees. Always derived.

notesstringrequired
possession_datestringrequired

Possession date, YYYY-MM-DD; empty when not set.

projected_close_datestringrequired

Expected closing date, YYYY-MM-DD; empty when not set.

referral_feestringrequired

Referral fee taken off the top, as a decimal string.

sale_pricestringrequired

Sale price, as a decimal string.

sidestringrequired

buyer, seller, or both.

stage_idstringrequired

Closing stage the transaction sits in.

stage_namestringrequired
statusstringrequired

active, pending, closed, or fell_through, from the closing stage the transaction sits in.

team_split_ratestringrequired

Team split as a percent of GCI after the referral fee.

transaction_feesstringrequired

Flat transaction fees, as a decimal string.

updated_attimestamprequired
walkthrough_datestringrequired

Final walkthrough, YYYY-MM-DD; empty when not set.

POST — transaction.created
{
  "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

idstringrequired

Unique id for this event, shared by every endpoint it fans out to and stable across retries.

typestringrequired

The event type.

created_attimestamprequired

When the event occurred.

dataobjectrequired

The transaction, as GET /v1/transactions/{id} returns it.

Show child attributes
actual_close_datestringrequired

Closing date, YYYY-MM-DD; set when the transaction closes.

appraisal_datestringrequired

Appraisal deadline, YYYY-MM-DD; empty when not set.

brokerage_split_ratestringrequired

Brokerage split as a percent of GCI after the referral fee.

commission_ratestringrequired

Commission rate as a percent, e.g. 3.00.

contact_emailstringrequired
contact_first_namestringrequired
contact_idstringrequired

Linked contact; empty when there is none.

contact_last_namestringrequired
contract_datestringrequired

Contract date, YYYY-MM-DD; empty when not set.

created_attimestamprequired
deal_idstringrequired

Linked deal; empty when there is none.

deal_namestringrequired
deal_statusstringrequired

The linked deal's open, won, or lost status.

document_countintegerrequired

Number of documents stored on the transaction.

earnest_money_due_datestringrequired

Earnest money deadline, YYYY-MM-DD; empty when not set.

fell_through_reasonstringrequired

Why the transaction fell through; empty otherwise.

financing_datestringrequired

Financing deadline, YYYY-MM-DD; empty when not set.

gci_overridebooleanrequired

Whether gross_commission was entered directly instead of derived.

gross_commissionstringrequired

Gross commission income, as a decimal string. Derived from sale_price × commission_rate unless gci_override is set.

idstringrequired
inspection_datestringrequired

Inspection deadline, YYYY-MM-DD; empty when not set.

listing_keystringrequired

MLS listing key; empty unless the property is an MLS listing.

listing_labelstringrequired

The property's address or label.

listing_photo_pathstringrequired

Path to the property's primary photo; empty when there is none.

namestringrequired
net_commissionstringrequired

What the agent keeps, as a decimal string: (GCI − referral fee) × (1 − brokerage split − team split) − transaction fees. Always derived.

notesstringrequired
possession_datestringrequired

Possession date, YYYY-MM-DD; empty when not set.

projected_close_datestringrequired

Expected closing date, YYYY-MM-DD; empty when not set.

referral_feestringrequired

Referral fee taken off the top, as a decimal string.

sale_pricestringrequired

Sale price, as a decimal string.

sidestringrequired

buyer, seller, or both.

stage_idstringrequired

Closing stage the transaction sits in.

stage_namestringrequired
statusstringrequired

active, pending, closed, or fell_through, from the closing stage the transaction sits in.

team_split_ratestringrequired

Team split as a percent of GCI after the referral fee.

transaction_feesstringrequired

Flat transaction fees, as a decimal string.

updated_attimestamprequired
walkthrough_datestringrequired

Final walkthrough, YYYY-MM-DD; empty when not set.

POST — transaction.updated
{
  "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

idstringrequired

Unique id for this event, shared by every endpoint it fans out to and stable across retries.

typestringrequired

The event type.

created_attimestamprequired

When the event occurred.

dataobjectrequired

The transaction, as GET /v1/transactions/{id} returns it.

Show child attributes
actual_close_datestringrequired

Closing date, YYYY-MM-DD; set when the transaction closes.

appraisal_datestringrequired

Appraisal deadline, YYYY-MM-DD; empty when not set.

brokerage_split_ratestringrequired

Brokerage split as a percent of GCI after the referral fee.

commission_ratestringrequired

Commission rate as a percent, e.g. 3.00.

contact_emailstringrequired
contact_first_namestringrequired
contact_idstringrequired

Linked contact; empty when there is none.

contact_last_namestringrequired
contract_datestringrequired

Contract date, YYYY-MM-DD; empty when not set.

created_attimestamprequired
deal_idstringrequired

Linked deal; empty when there is none.

deal_namestringrequired
deal_statusstringrequired

The linked deal's open, won, or lost status.

document_countintegerrequired

Number of documents stored on the transaction.

earnest_money_due_datestringrequired

Earnest money deadline, YYYY-MM-DD; empty when not set.

fell_through_reasonstringrequired

Why the transaction fell through; empty otherwise.

financing_datestringrequired

Financing deadline, YYYY-MM-DD; empty when not set.

gci_overridebooleanrequired

Whether gross_commission was entered directly instead of derived.

gross_commissionstringrequired

Gross commission income, as a decimal string. Derived from sale_price × commission_rate unless gci_override is set.

idstringrequired
inspection_datestringrequired

Inspection deadline, YYYY-MM-DD; empty when not set.

listing_keystringrequired

MLS listing key; empty unless the property is an MLS listing.

listing_labelstringrequired

The property's address or label.

listing_photo_pathstringrequired

Path to the property's primary photo; empty when there is none.

namestringrequired
net_commissionstringrequired

What the agent keeps, as a decimal string: (GCI − referral fee) × (1 − brokerage split − team split) − transaction fees. Always derived.

notesstringrequired
possession_datestringrequired

Possession date, YYYY-MM-DD; empty when not set.

projected_close_datestringrequired

Expected closing date, YYYY-MM-DD; empty when not set.

referral_feestringrequired

Referral fee taken off the top, as a decimal string.

sale_pricestringrequired

Sale price, as a decimal string.

sidestringrequired

buyer, seller, or both.

stage_idstringrequired

Closing stage the transaction sits in.

stage_namestringrequired
statusstringrequired

active, pending, closed, or fell_through, from the closing stage the transaction sits in.

team_split_ratestringrequired

Team split as a percent of GCI after the referral fee.

transaction_feesstringrequired

Flat transaction fees, as a decimal string.

updated_attimestamprequired
walkthrough_datestringrequired

Final walkthrough, YYYY-MM-DD; empty when not set.

POST — transaction.status_changed
{
  "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

idstringrequired

Unique id for this event, shared by every endpoint it fans out to and stable across retries.

typestringrequired

The event type.

created_attimestamprequired

When the event occurred.

dataobjectrequired

The transaction, as GET /v1/transactions/{id} returns it.

Show child attributes
actual_close_datestringrequired

Closing date, YYYY-MM-DD; set when the transaction closes.

appraisal_datestringrequired

Appraisal deadline, YYYY-MM-DD; empty when not set.

brokerage_split_ratestringrequired

Brokerage split as a percent of GCI after the referral fee.

commission_ratestringrequired

Commission rate as a percent, e.g. 3.00.

contact_emailstringrequired
contact_first_namestringrequired
contact_idstringrequired

Linked contact; empty when there is none.

contact_last_namestringrequired
contract_datestringrequired

Contract date, YYYY-MM-DD; empty when not set.

created_attimestamprequired
deal_idstringrequired

Linked deal; empty when there is none.

deal_namestringrequired
deal_statusstringrequired

The linked deal's open, won, or lost status.

document_countintegerrequired

Number of documents stored on the transaction.

earnest_money_due_datestringrequired

Earnest money deadline, YYYY-MM-DD; empty when not set.

fell_through_reasonstringrequired

Why the transaction fell through; empty otherwise.

financing_datestringrequired

Financing deadline, YYYY-MM-DD; empty when not set.

gci_overridebooleanrequired

Whether gross_commission was entered directly instead of derived.

gross_commissionstringrequired

Gross commission income, as a decimal string. Derived from sale_price × commission_rate unless gci_override is set.

idstringrequired
inspection_datestringrequired

Inspection deadline, YYYY-MM-DD; empty when not set.

listing_keystringrequired

MLS listing key; empty unless the property is an MLS listing.

listing_labelstringrequired

The property's address or label.

listing_photo_pathstringrequired

Path to the property's primary photo; empty when there is none.

namestringrequired
net_commissionstringrequired

What the agent keeps, as a decimal string: (GCI − referral fee) × (1 − brokerage split − team split) − transaction fees. Always derived.

notesstringrequired
possession_datestringrequired

Possession date, YYYY-MM-DD; empty when not set.

projected_close_datestringrequired

Expected closing date, YYYY-MM-DD; empty when not set.

referral_feestringrequired

Referral fee taken off the top, as a decimal string.

sale_pricestringrequired

Sale price, as a decimal string.

sidestringrequired

buyer, seller, or both.

stage_idstringrequired

Closing stage the transaction sits in.

stage_namestringrequired
statusstringrequired

active, pending, closed, or fell_through, from the closing stage the transaction sits in.

team_split_ratestringrequired

Team split as a percent of GCI after the referral fee.

transaction_feesstringrequired

Flat transaction fees, as a decimal string.

updated_attimestamprequired
walkthrough_datestringrequired

Final walkthrough, YYYY-MM-DD; empty when not set.

POST — transaction.closed
{
  "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

idstringrequired

Unique id for this event, shared by every endpoint it fans out to and stable across retries.

typestringrequired

The event type.

created_attimestamprequired

When the event occurred.

dataobjectrequired

The transaction, as GET /v1/transactions/{id} returns it.

Show child attributes
actual_close_datestringrequired

Closing date, YYYY-MM-DD; set when the transaction closes.

appraisal_datestringrequired

Appraisal deadline, YYYY-MM-DD; empty when not set.

brokerage_split_ratestringrequired

Brokerage split as a percent of GCI after the referral fee.

commission_ratestringrequired

Commission rate as a percent, e.g. 3.00.

contact_emailstringrequired
contact_first_namestringrequired
contact_idstringrequired

Linked contact; empty when there is none.

contact_last_namestringrequired
contract_datestringrequired

Contract date, YYYY-MM-DD; empty when not set.

created_attimestamprequired
deal_idstringrequired

Linked deal; empty when there is none.

deal_namestringrequired
deal_statusstringrequired

The linked deal's open, won, or lost status.

document_countintegerrequired

Number of documents stored on the transaction.

earnest_money_due_datestringrequired

Earnest money deadline, YYYY-MM-DD; empty when not set.

fell_through_reasonstringrequired

Why the transaction fell through; empty otherwise.

financing_datestringrequired

Financing deadline, YYYY-MM-DD; empty when not set.

gci_overridebooleanrequired

Whether gross_commission was entered directly instead of derived.

gross_commissionstringrequired

Gross commission income, as a decimal string. Derived from sale_price × commission_rate unless gci_override is set.

idstringrequired
inspection_datestringrequired

Inspection deadline, YYYY-MM-DD; empty when not set.

listing_keystringrequired

MLS listing key; empty unless the property is an MLS listing.

listing_labelstringrequired

The property's address or label.

listing_photo_pathstringrequired

Path to the property's primary photo; empty when there is none.

namestringrequired
net_commissionstringrequired

What the agent keeps, as a decimal string: (GCI − referral fee) × (1 − brokerage split − team split) − transaction fees. Always derived.

notesstringrequired
possession_datestringrequired

Possession date, YYYY-MM-DD; empty when not set.

projected_close_datestringrequired

Expected closing date, YYYY-MM-DD; empty when not set.

referral_feestringrequired

Referral fee taken off the top, as a decimal string.

sale_pricestringrequired

Sale price, as a decimal string.

sidestringrequired

buyer, seller, or both.

stage_idstringrequired

Closing stage the transaction sits in.

stage_namestringrequired
statusstringrequired

active, pending, closed, or fell_through, from the closing stage the transaction sits in.

team_split_ratestringrequired

Team split as a percent of GCI after the referral fee.

transaction_feesstringrequired

Flat transaction fees, as a decimal string.

updated_attimestamprequired
walkthrough_datestringrequired

Final walkthrough, YYYY-MM-DD; empty when not set.

POST — transaction.fell_through
{
  "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

idstringrequired

Unique id for this event, shared by every endpoint it fans out to and stable across retries.

typestringrequired

The event type.

created_attimestamprequired

When the event occurred.

dataobjectrequired

The contact, as GET /v1/contacts/{contact_id} returns it.

Show child attributes
idstringrequired
first_namestringrequired
last_namestringrequired
emailnullable stringrequired
phonenullable stringrequired
emailsarray of objectsrequired

Every ordered email address; email above remains the primary shortcut.

Show child attributes
idstringrequired
valuestringrequired
labelstringrequired

Home | Work | Other

is_primarybooleanrequired
positionintegerrequired
phonesarray of objectsrequired

Every ordered phone number; phone above remains the primary shortcut.

Show child attributes
idstringrequired
valuestringrequired
labelstringrequired

Mobile | Home | Work | Fax | Other

is_primarybooleanrequired
positionintegerrequired
addressnullable stringrequired
citynullable stringrequired
statenullable stringrequired
zip_codenullable stringrequired
companynullable stringrequired
job_titlenullable stringrequired
notesnullable stringrequired

Free-form notes shown on the contact record.

stagenullable objectrequired

Pipeline stage of the contact, from /v1/contact-stages.

Show child attributes
idstringrequired
namestringrequired
lead_sourcenullable objectrequired

Where the contact came from, from /v1/lead-sources.

Show child attributes
idstringrequired
namestringrequired
ownernullable objectrequired

Team member the contact is assigned to.

Show child attributes
idstringrequired
namestringrequired
tagsarray of objectsrequired

Workspace tags on the contact.

Show child attributes
idstringrequired
namestringrequired
colornullable stringrequired
custom_fieldsobjectrequired

Values for the workspace's custom fields, keyed by field id.

created_attimestamprequired
updated_attimestamprequired
last_activity_atnullable timestamprequired

Last time an activity touched this contact.

POST — contact.created
{
  "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

idstringrequired

Unique id for this event, shared by every endpoint it fans out to and stable across retries.

typestringrequired

The event type.

created_attimestamprequired

When the event occurred.

dataobjectrequired

The contact, as GET /v1/contacts/{contact_id} returns it.

Show child attributes
idstringrequired
first_namestringrequired
last_namestringrequired
emailnullable stringrequired
phonenullable stringrequired
emailsarray of objectsrequired

Every ordered email address; email above remains the primary shortcut.

Show child attributes
idstringrequired
valuestringrequired
labelstringrequired

Home | Work | Other

is_primarybooleanrequired
positionintegerrequired
phonesarray of objectsrequired

Every ordered phone number; phone above remains the primary shortcut.

Show child attributes
idstringrequired
valuestringrequired
labelstringrequired

Mobile | Home | Work | Fax | Other

is_primarybooleanrequired
positionintegerrequired
addressnullable stringrequired
citynullable stringrequired
statenullable stringrequired
zip_codenullable stringrequired
companynullable stringrequired
job_titlenullable stringrequired
notesnullable stringrequired

Free-form notes shown on the contact record.

stagenullable objectrequired

Pipeline stage of the contact, from /v1/contact-stages.

Show child attributes
idstringrequired
namestringrequired
lead_sourcenullable objectrequired

Where the contact came from, from /v1/lead-sources.

Show child attributes
idstringrequired
namestringrequired
ownernullable objectrequired

Team member the contact is assigned to.

Show child attributes
idstringrequired
namestringrequired
tagsarray of objectsrequired

Workspace tags on the contact.

Show child attributes
idstringrequired
namestringrequired
colornullable stringrequired
custom_fieldsobjectrequired

Values for the workspace's custom fields, keyed by field id.

created_attimestamprequired
updated_attimestamprequired
last_activity_atnullable timestamprequired

Last time an activity touched this contact.

POST — contact.updated
{
  "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

idstringrequired

Unique id for this event, shared by every endpoint it fans out to and stable across retries.

typestringrequired

The event type.

created_attimestamprequired

When the event occurred.

dataobjectrequired

The deleted object is gone; only its id remains.

Show child attributes
idstringrequired

Id of the deleted object.

POST — contact.deleted
{
  "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

idstringrequired

Unique id for this event, shared by every endpoint it fans out to and stable across retries.

typestringrequired

The event type.

created_attimestamprequired

When the event occurred.

dataobjectrequired

The deal, as GET /v1/deals/{deal_id} returns it.

Show child attributes
idstringrequired
namestringrequired
valuenullable stringrequired

Deal value in workspace currency, as a decimal string.

statusstringrequired

open, won, or lost — derived from the stage's type.

pipelineobjectrequired
Show child attributes
idstringrequired
namestringrequired
stageobjectrequired
Show child attributes
idstringrequired
namestringrequired
typestringrequired

OPEN, CLOSED_WON, or CLOSED_LOST.

contact_idnullable stringrequired

Contact the deal belongs to, if linked.

listing_labelnullable stringrequired

Listing linked to the deal, if any (read-only through the API).

expected_close_datenullable timestamprequired
closed_atnullable timestamprequired
lost_reasonnullable stringrequired

Why the deal was lost, when it sits in a closed-lost stage.

notesnullable stringrequired
created_attimestamprequired
updated_attimestamprequired
POST — deal.created
{
  "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

idstringrequired

Unique id for this event, shared by every endpoint it fans out to and stable across retries.

typestringrequired

The event type.

created_attimestamprequired

When the event occurred.

dataobjectrequired

The deal, as GET /v1/deals/{deal_id} returns it.

Show child attributes
idstringrequired
namestringrequired
valuenullable stringrequired

Deal value in workspace currency, as a decimal string.

statusstringrequired

open, won, or lost — derived from the stage's type.

pipelineobjectrequired
Show child attributes
idstringrequired
namestringrequired
stageobjectrequired
Show child attributes
idstringrequired
namestringrequired
typestringrequired

OPEN, CLOSED_WON, or CLOSED_LOST.

contact_idnullable stringrequired

Contact the deal belongs to, if linked.

listing_labelnullable stringrequired

Listing linked to the deal, if any (read-only through the API).

expected_close_datenullable timestamprequired
closed_atnullable timestamprequired
lost_reasonnullable stringrequired

Why the deal was lost, when it sits in a closed-lost stage.

notesnullable stringrequired
created_attimestamprequired
updated_attimestamprequired
POST — deal.updated
{
  "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

idstringrequired

Unique id for this event, shared by every endpoint it fans out to and stable across retries.

typestringrequired

The event type.

created_attimestamprequired

When the event occurred.

dataobjectrequired

The deal, as GET /v1/deals/{deal_id} returns it.

Show child attributes
idstringrequired
namestringrequired
valuenullable stringrequired

Deal value in workspace currency, as a decimal string.

statusstringrequired

open, won, or lost — derived from the stage's type.

pipelineobjectrequired
Show child attributes
idstringrequired
namestringrequired
stageobjectrequired
Show child attributes
idstringrequired
namestringrequired
typestringrequired

OPEN, CLOSED_WON, or CLOSED_LOST.

contact_idnullable stringrequired

Contact the deal belongs to, if linked.

listing_labelnullable stringrequired

Listing linked to the deal, if any (read-only through the API).

expected_close_datenullable timestamprequired
closed_atnullable timestamprequired
lost_reasonnullable stringrequired

Why the deal was lost, when it sits in a closed-lost stage.

notesnullable stringrequired
created_attimestamprequired
updated_attimestamprequired
POST — deal.stage_changed
{
  "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

idstringrequired

Unique id for this event, shared by every endpoint it fans out to and stable across retries.

typestringrequired

The event type.

created_attimestamprequired

When the event occurred.

dataobjectrequired

The deleted object is gone; only its id remains.

Show child attributes
idstringrequired

Id of the deleted object.

POST — deal.deleted
{
  "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

idstringrequired

Unique id for this event, shared by every endpoint it fans out to and stable across retries.

typestringrequired

The event type.

created_attimestamprequired

When the event occurred.

dataobjectrequired

The task, as GET /v1/tasks/{task_id} returns it.

Show child attributes
idstringrequired
titlestringrequired
descriptionnullable stringrequired
typestringrequired

Kind of task, e.g. todo, call, email, showing.

prioritystringrequired

low, medium, or high.

statusstringrequired

todo, in_progress, waiting, or done.

completedbooleanrequired
due_datenullable timestamprequired
all_daybooleanrequired

Whether the due date is a date (no time of day).

contact_idnullable stringrequired

Contact the task is linked to, if any.

deal_idnullable stringrequired

Deal the task is linked to, if any.

assigneenullable objectrequired

Team member the task is assigned to.

Show child attributes
idstringrequired
namestringrequired
remind_minutes_beforenullable integerrequired

Reminder offset before due_date, in minutes.

completed_atnullable timestamprequired
created_attimestamprequired
updated_attimestamprequired
POST — task.created
{
  "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

idstringrequired

Unique id for this event, shared by every endpoint it fans out to and stable across retries.

typestringrequired

The event type.

created_attimestamprequired

When the event occurred.

dataobjectrequired

The task, as GET /v1/tasks/{task_id} returns it.

Show child attributes
idstringrequired
titlestringrequired
descriptionnullable stringrequired
typestringrequired

Kind of task, e.g. todo, call, email, showing.

prioritystringrequired

low, medium, or high.

statusstringrequired

todo, in_progress, waiting, or done.

completedbooleanrequired
due_datenullable timestamprequired
all_daybooleanrequired

Whether the due date is a date (no time of day).

contact_idnullable stringrequired

Contact the task is linked to, if any.

deal_idnullable stringrequired

Deal the task is linked to, if any.

assigneenullable objectrequired

Team member the task is assigned to.

Show child attributes
idstringrequired
namestringrequired
remind_minutes_beforenullable integerrequired

Reminder offset before due_date, in minutes.

completed_atnullable timestamprequired
created_attimestamprequired
updated_attimestamprequired
POST — task.updated
{
  "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

idstringrequired

Unique id for this event, shared by every endpoint it fans out to and stable across retries.

typestringrequired

The event type.

created_attimestamprequired

When the event occurred.

dataobjectrequired

The task, as GET /v1/tasks/{task_id} returns it.

Show child attributes
idstringrequired
titlestringrequired
descriptionnullable stringrequired
typestringrequired

Kind of task, e.g. todo, call, email, showing.

prioritystringrequired

low, medium, or high.

statusstringrequired

todo, in_progress, waiting, or done.

completedbooleanrequired
due_datenullable timestamprequired
all_daybooleanrequired

Whether the due date is a date (no time of day).

contact_idnullable stringrequired

Contact the task is linked to, if any.

deal_idnullable stringrequired

Deal the task is linked to, if any.

assigneenullable objectrequired

Team member the task is assigned to.

Show child attributes
idstringrequired
namestringrequired
remind_minutes_beforenullable integerrequired

Reminder offset before due_date, in minutes.

completed_atnullable timestamprequired
created_attimestamprequired
updated_attimestamprequired
POST — task.completed
{
  "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

idstringrequired

Unique id for this event, shared by every endpoint it fans out to and stable across retries.

typestringrequired

The event type.

created_attimestamprequired

When the event occurred.

dataobjectrequired

The deleted object is gone; only its id remains.

Show child attributes
idstringrequired

Id of the deleted object.

POST — task.deleted
{
  "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

idstringrequired

Unique id for this event, shared by every endpoint it fans out to and stable across retries.

typestringrequired

The event type.

created_attimestamprequired

When the event occurred.

dataobjectrequired

The listing, as GET /v1/listings/{listing_id} returns it.

Show child attributes
idstringrequired
sourcestringrequired

How the listing entered the system: manual, mls_import, or url_import. Only manual listings can be edited through the API.

statusstringrequired

draft, active, pending, sold, or off_market. Draft listings stay off websites and property alerts.

listing_typestringrequired

sale or rental. For rentals, list_price is the asking rent per month and close_price the agreed rent once leased.

street_addressstringrequired
citystringrequired
state_or_provincestringrequired
postal_codestringrequired
countynullable stringrequired
latitudenullable numberrequired
longitudenullable numberrequired
property_typenullable stringrequired
property_sub_typenullable stringrequired
list_pricenullable integerrequired

Whole dollars.

close_pricenullable integerrequired

Whole dollars; set when the listing sold.

bedrooms_totalnullable integerrequired
bathrooms_fullnullable integerrequired
bathrooms_halfnullable integerrequired
living_areanullable integerrequired

Interior square footage.

lot_size_acresnullable numberrequired
year_builtnullable integerrequired
descriptionnullable stringrequired
featuresarray of stringsrequired

Feature bullet points shown on websites.

virtual_tour_urlnullable stringrequired
photosarray of stringsrequired

Photo URLs, in display order. Read-only.

created_attimestamprequired
updated_attimestamprequired
POST — listing.created
{
  "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

idstringrequired

Unique id for this event, shared by every endpoint it fans out to and stable across retries.

typestringrequired

The event type.

created_attimestamprequired

When the event occurred.

dataobjectrequired

The listing, as GET /v1/listings/{listing_id} returns it.

Show child attributes
idstringrequired
sourcestringrequired

How the listing entered the system: manual, mls_import, or url_import. Only manual listings can be edited through the API.

statusstringrequired

draft, active, pending, sold, or off_market. Draft listings stay off websites and property alerts.

listing_typestringrequired

sale or rental. For rentals, list_price is the asking rent per month and close_price the agreed rent once leased.

street_addressstringrequired
citystringrequired
state_or_provincestringrequired
postal_codestringrequired
countynullable stringrequired
latitudenullable numberrequired
longitudenullable numberrequired
property_typenullable stringrequired
property_sub_typenullable stringrequired
list_pricenullable integerrequired

Whole dollars.

close_pricenullable integerrequired

Whole dollars; set when the listing sold.

bedrooms_totalnullable integerrequired
bathrooms_fullnullable integerrequired
bathrooms_halfnullable integerrequired
living_areanullable integerrequired

Interior square footage.

lot_size_acresnullable numberrequired
year_builtnullable integerrequired
descriptionnullable stringrequired
featuresarray of stringsrequired

Feature bullet points shown on websites.

virtual_tour_urlnullable stringrequired
photosarray of stringsrequired

Photo URLs, in display order. Read-only.

created_attimestamprequired
updated_attimestamprequired
POST — listing.updated
{
  "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

idstringrequired

Unique id for this event, shared by every endpoint it fans out to and stable across retries.

typestringrequired

The event type.

created_attimestamprequired

When the event occurred.

dataobjectrequired

The deleted object is gone; only its id remains.

Show child attributes
idstringrequired

Id of the deleted object.

POST — listing.deleted
{
  "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

idstringrequired

Unique id for this event, shared by every endpoint it fans out to and stable across retries.

typestringrequired

The event type.

created_attimestamprequired

When the event occurred.

dataobjectrequired
Show child attributes
messagestringrequired
webhook_idstringrequired

Id of the endpoint the test was sent to.

POST — ping
{
  "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 objectsrequired
Show child attributes
idstringrequired
namestringrequired
is_activebooleanrequired
stagesarray of objectsrequired

Stages in board order.

Show child attributes
idstringrequired
namestringrequired
typestringrequired

OPEN, CLOSED_WON, or CLOSED_LOST.

probabilityintegerrequired

Win probability percentage used for weighted forecasts.

positionintegerrequired
GET /v1/pipelines
curl "https://api.uplevelre.com/v1/pipelines" \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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 objectsrequired
Show child attributes
idstringrequired
namestringrequired
colorstringrequired
is_defaultbooleanrequired

Applied to new contacts when no stage is given.

positionintegerrequired
GET /v1/contact-stages
curl "https://api.uplevelre.com/v1/contact-stages" \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "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 objectsrequired
Show child attributes
idstringrequired
namestringrequired
is_activebooleanrequired
GET /v1/lead-sources
curl "https://api.uplevelre.com/v1/lead-sources" \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "data": [
    {
      "id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
      "name": "Zillow",
      "is_active": true
    }
  ]
}

List tags

GET/v1/tags

The workspace's shared tags (personal tags are not exposed through the API).

Returns

200All workspace tags.
401Missing or invalid API key.
403The key lacks the read_contacts scope.

Response attributes

dataarray of objectsrequired
Show child attributes
idstringrequired
namestringrequired
colornullable stringrequired
GET /v1/tags
curl "https://api.uplevelre.com/v1/tags" \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "data": [
    {
      "id": "8f14e45f-ceea-4f3a-9a5a-d3bc0e8a6b21",
      "name": "Buyer",
      "color": "#26c2e7"
    }
  ]
}

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 objectsrequired
Show child attributes
idstringrequired

Use as owner_id on contacts or assignee_id on tasks.

namestringrequired
emailstringrequired
rolestringrequired

owner, admin, or member.

GET /v1/members
curl "https://api.uplevelre.com/v1/members" \
  -H "Authorization: Bearer $UPLEVEL_API_KEY"
Response200
{
  "data": [
    {
      "id": "3b241101-e2bb-4255-8caf-4136c566a962",
      "name": "Alex Rivera",
      "email": "alex@acme-realty.com",
      "role": "member"
    }
  ]
}