DealDNA API Reference

RESTful API for programmatic access to your DealDNA data

Base URL: https://dealdna.ai/api/v1

Authentication

All API requests require an API key sent via the X-API-Key header. Generate keys in Settings → API.

Example (curl)

curl -H "X-API-Key: dna_your_key_here" \
  https://dealdna.ai/api/v1/properties

Example (JavaScript)

const response = await fetch("https://dealdna.ai/api/v1/properties", {
  headers: { "X-API-Key": "dna_your_key_here" },
});
const { data, meta } = await response.json();

Example (Python)

import requests

resp = requests.get(
    "https://dealdna.ai/api/v1/properties",
    headers={"X-API-Key": "dna_your_key_here"},
)
data = resp.json()["data"]

Rate Limiting

API requests are limited to 100 requests per minute per API key. Exceeding this limit returns 429 Too Many Requests with a Retry-After header.

Response Format

All responses use a consistent JSON envelope:

{
  "data": [...],           // The response payload (array or object)
  "meta": {                // Pagination metadata (list endpoints only)
    "count": 25,
    "limit": 25,
    "next_cursor": "2024-01-15T10:30:00Z",
    "has_more": true
  },
  "error": null            // Error message string (null on success)
}

Pagination

List endpoints use cursor-based pagination. Pass the next_cursor value from the response as the cursor query parameter to fetch the next page.

# First page
GET /api/v1/properties?limit=25

# Next page
GET /api/v1/properties?limit=25&cursor=2024-01-15T10:30:00Z

Permissions

readView all resources (GET endpoints)
writeCreate and update resources (POST, PATCH endpoints)
adminFull access including webhook and API key management

Webhook Events

Configure webhooks to receive POST requests when events occur. Each delivery includes an X-Webhook-Signature header with an HMAC-SHA256 signature for verification.

deal.created
deal.updated
deal.stage_changed
lead.created
lead.status_changed
lead.converted
campaign.completed
property.imported

Webhook Payload

{
  "event": "deal.created",
  "data": { "id": "uuid", "stage": "offer", ... },
  "timestamp": "2024-01-15T10:30:00.000Z"
}

Verifying Signatures (Node.js)

const crypto = require("crypto");

function verifySignature(body, signature, secret) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(body)
    .digest("hex");
  return signature === `sha256=${expected}`;
}

// In your webhook handler:
const sig = req.headers["x-webhook-signature"];
const isValid = verifySignature(rawBody, sig, YOUR_SECRET);

Endpoints

Properties

GET/api/v1/properties

List properties with pagination and filters

Query Parameters

?cursor=X&limit=25&status=active&city=Tampa&state=FL
GET/api/v1/properties/:id

Get a single property by ID

Leads

GET/api/v1/leads

List leads with pagination

Query Parameters

?cursor=X&limit=25&status=new
GET/api/v1/leads/:id

Get a single lead by ID

POST/api/v1/leads

Create a new lead

Request Body

{ "first_name": "John", "last_name": "Doe", "phone": "555-0100", "status": "new" }
PATCH/api/v1/leads/:id

Update a lead

Request Body

{ "status": "contacted" }

Deals

GET/api/v1/deals

List deals with pagination

Query Parameters

?cursor=X&limit=25&stage=under_contract
GET/api/v1/deals/:id

Get a single deal by ID

POST/api/v1/deals

Create a new deal

Request Body

{ "property_id": "uuid", "stage": "offer", "offer_amount": 250000 }
PATCH/api/v1/deals/:id

Update a deal

Request Body

{ "stage": "under_contract" }

Contacts

GET/api/v1/contacts

List contacts with pagination

Query Parameters

?cursor=X&limit=25
GET/api/v1/contacts/:id

Get a single contact by ID

POST/api/v1/contacts

Create a new contact

Request Body

{ "first_name": "Jane", "last_name": "Smith", "email": "jane@example.com" }
PATCH/api/v1/contacts/:id

Update a contact

Request Body

{ "email": "new@example.com" }

Campaigns

GET/api/v1/campaigns

List campaigns with pagination

Query Parameters

?cursor=X&limit=25&status=active
GET/api/v1/campaigns/:id

Get a single campaign by ID

Webhooks

GET/api/v1/webhooks

List webhook endpoints (admin only)

POST/api/v1/webhooks

Create a webhook endpoint (admin only)

Request Body

{ "url": "https://example.com/hook", "events": ["deal.created", "lead.created"] }
PATCH/api/v1/webhooks/:id

Update a webhook endpoint (admin only)

Request Body

{ "active": false }
DELETE/api/v1/webhooks/:id

Delete a webhook endpoint (admin only)