API Documentation

Use the Prospects API to send new prospects into CadenHQ from your app, forms, or integrations. Authenticate with an account API key; we upsert by email and start conversion campaigns for new prospects.

Overview

The CadenHQ API lets you submit prospects from outside the app (e.g. signup forms, landing pages, CRMs). Send a POST request with at least the prospect's email. We create or update the prospect by normalized email per account.

  • New prospect – We set status to new, start the conversion campaign, and schedule follow-up actions.
  • Existing prospect – We update any provided fields and return success without re-starting the campaign.

Base URL

All endpoints are relative to the base URL for your environment (e.g. https://api.cadenhq.com). Public API routes are under /api/v1 (e.g. POST /api/v1/prospects).

Authentication

Authenticate by sending your API key in the X-CadenHQ-Key header. Keys belong to your user and can be scoped to an account (e.g. one per environment).

Header

HeaderX-CadenHQ-Key
DescriptionYour API key (raw value). Keys belong to your user and can be scoped to an account; store them securely and never commit them to source control.

If the key is missing or invalid, the API responds with 401 Unauthorized and a JSON body:

{"error":"Missing or invalid X-CadenHQ-Key"}

Rate limits: Requests are limited per account (default 60 requests per minute). When exceeded, the API returns 429 Too Many Requests with a Retry-After header.

Getting an API key: Create keys in your CadenHQ dashboard under Account Settings → API Keys. The raw key is returned only once at creation; store it in your environment or secrets manager.

POST /api/v1/prospects

Create or update a prospect. The request body must include email. All other fields are optional. Prospects are upserted by (account_id, email_normalized); email is normalized (lowercased, trimmed). Metadata is not accepted for prospects created or updated via the API—including it returns 400 Bad Request.

Owner: The prospect owner is always set to the API key user; owner_id cannot be sent in the request.

Field limits: email 254 chars; display_name, first_name, last_name 255; phone 50; address 500; city, state, zip, country, source, external_id, UTM fields 255. campaign_id must be a valid UUID when provided.

POST /api/v1/prospects

Submit a prospect. New prospects are enrolled in the conversion campaign; existing prospects are updated with provided attributes.

Request headers

HeaderRequiredDescription
X-CadenHQ-KeyRequiredAccount API key.
Content-TypeOptionalUse application/json for JSON body.

Request body parameters

ParameterTypeRequiredDescription
emailstringRequiredProspect email (max 254 chars).
campaign_idstring (UUID)OptionalCampaign ID to enroll the prospect in.
display_namestringOptionalDisplay name.
first_namestringOptionalFirst name.
last_namestringOptionalLast name.
phonestringOptionalPhone number (max 50 chars).
addressstringOptionalStreet address (max 500 chars).
citystringOptionalCity (max 255 chars).
statestringOptionalState or region (max 255 chars).
zipstringOptionalPostal code (max 255 chars).
countrystringOptionalCountry (max 255 chars).
sourcestringOptionalProspect source (e.g. landing_page, import).
external_idstringOptionalYour system's ID for this prospect.
utm_source, utm_medium, etc.stringOptionalUTM parameters (max 255 chars each).

Responses

201 Created 200 OK 400 Bad Request 401 Unauthorized 404 Not Found 422 Unprocessable Entity 429 Too Many Requests

201 Created – New prospect created. Body includes accepted: true, created: true, and prospect_id (CadenHQ UUID—use this for PATCH to update the prospect's status).

200 OK – Existing prospect updated. Body includes accepted: true, created: false, and prospect_id.

404 Not Foundcampaign_id was provided but the campaign does not exist in the account.

PATCH /api/v1/prospects/:id

Update a prospect's status. The :id is the CadenHQ prospect UUID returned when you create the prospect (e.g. in prospect_id from POST /api/v1/prospects). Only prospects owned by the API key user can be updated; otherwise the API returns 404 Not Found. Setting status to converted, unsubscribed, or bounced removes the prospect from all campaigns.

PATCH /api/v1/prospects/:id

:id — CadenHQ prospect UUID (returned as prospect_id in the create response).

Request headers

HeaderRequiredDescription
X-CadenHQ-KeyRequiredAccount API key (prospect must be owned by this user).
Content-TypeOptionalUse application/json for JSON body.

Request body parameters

ParameterTypeRequiredDescription
statusstringRequiredOne of new, converted, unsubscribed, bounced.

Responses

200 OK 400 Bad Request 401 Unauthorized 404 Not Found

200 OK — Status updated. Body includes accepted: true, prospect_id, status.

404 Not Found — No prospect found for the given UUID or the prospect is not owned by the API key user.

Errors

Error responses are JSON objects with error or errors fields.

  • 400 – Missing/invalid params, metadata not accepted
  • 401 – Missing or invalid X-CadenHQ-Key
  • 404 – Prospect not found (PATCH) or campaign not found (POST when campaign_id is provided)
  • 422 – Validation failed
  • 429 – Rate limit exceeded (see Retry-After header)

Code examples

cURL

curl -X POST https://api.cadenhq.com/api/v1/prospects \
  -H "Content-Type: application/json" \
  -H "X-CadenHQ-Key: YOUR_API_KEY" \
  -d '{
    "email": "prospect@example.com",
    "display_name": "Jane Doe",
    "source": "landing_page"
  }'

JavaScript (fetch)

const response = await fetch("https://api.cadenhq.com/api/v1/prospects", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-CadenHQ-Key": process.env.CADENHQ_API_KEY,
  },
  body: JSON.stringify({
    email: "prospect@example.com",
    display_name: "Jane Doe",
    source: "landing_page",
  }),
});