RESTful API for programmatic access to your DealDNA data
Base URL: https://dealdna.ai/api/v1
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"]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.
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)
}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
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.createddeal.updateddeal.stage_changedlead.createdlead.status_changedlead.convertedcampaign.completedproperty.importedWebhook 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);/api/v1/propertiesList properties with pagination and filters
Query Parameters
?cursor=X&limit=25&status=active&city=Tampa&state=FL/api/v1/properties/:idGet a single property by ID
/api/v1/leadsList leads with pagination
Query Parameters
?cursor=X&limit=25&status=new/api/v1/leads/:idGet a single lead by ID
/api/v1/leadsCreate a new lead
Request Body
{ "first_name": "John", "last_name": "Doe", "phone": "555-0100", "status": "new" }/api/v1/leads/:idUpdate a lead
Request Body
{ "status": "contacted" }/api/v1/dealsList deals with pagination
Query Parameters
?cursor=X&limit=25&stage=under_contract/api/v1/deals/:idGet a single deal by ID
/api/v1/dealsCreate a new deal
Request Body
{ "property_id": "uuid", "stage": "offer", "offer_amount": 250000 }/api/v1/deals/:idUpdate a deal
Request Body
{ "stage": "under_contract" }/api/v1/contactsList contacts with pagination
Query Parameters
?cursor=X&limit=25/api/v1/contacts/:idGet a single contact by ID
/api/v1/contactsCreate a new contact
Request Body
{ "first_name": "Jane", "last_name": "Smith", "email": "jane@example.com" }/api/v1/contacts/:idUpdate a contact
Request Body
{ "email": "new@example.com" }/api/v1/campaignsList campaigns with pagination
Query Parameters
?cursor=X&limit=25&status=active/api/v1/campaigns/:idGet a single campaign by ID
/api/v1/webhooksList webhook endpoints (admin only)
/api/v1/webhooksCreate a webhook endpoint (admin only)
Request Body
{ "url": "https://example.com/hook", "events": ["deal.created", "lead.created"] }/api/v1/webhooks/:idUpdate a webhook endpoint (admin only)
Request Body
{ "active": false }/api/v1/webhooks/:idDelete a webhook endpoint (admin only)