Developer Docs

ShortStack API

v1 · REST · JSON

The ShortStack API gives you programmatic access to your leads. Use it to sync leads with your CRM, trigger automations, or build custom integrations. API access is available on the Professional plan and above.

API Key Auth Outbound Webhooks OpenAPI 3.0

Authentication

All API requests require an API key sent via the Authorization header. Generate keys from Dashboard → Settings → API.

Header format
Authorization: Bearer sk_live_YourApiKeyHere
Keep your key secret. It grants full read/write access to your leads. If compromised, revoke it immediately from your dashboard.

Rate Limits

The API allows 1,000 requests per hour per API key. Rate limit headers are included on every response:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 998
X-RateLimit-Reset: 1719849600000

Endpoints

GET/api/v1/leads

List leads with optional filters. Returns a paginated response.

Query parameters

  • status — Filter by status (new, contacted, proposal, won, lost)
  • from — ISO date, leads created on or after
  • to — ISO date, leads created on or before
  • limit — Results per page (1–100, default 50)
  • offset — Skip N results (default 0)
Example request
const res = await fetch("https://www.shortstack.co.nz/api/v1/leads?status=new&limit=10", {
  headers: {
    "Authorization": "Bearer sk_live_YourApiKeyHere",
    // Try it now with the live demo key:
    // "Authorization": "Bearer sk_demo_roofing001",
  },
});

const { data, total, limit, offset } = await res.json();
console.log(`Found ${total} leads`);
Example response
{
  "data": [
    {
      "id": "abc-123",
      "firstName": "James",
      "lastName": "Wilson",
      "email": "james@example.com",
      "phone": "021 123 4567",
      "status": "new",
      "categoryName": "Solar Installation",
      "estimatedValue": 15000,
      "createdAt": "2026-03-28T09:15:00.000Z"
    }
  ],
  "total": 1,
  "limit": 10,
  "offset": 0
}
GET/api/v1/leads/:id

Retrieve a single lead by its ID.

Example request
const res = await fetch("https://www.shortstack.co.nz/api/v1/leads/abc-123", {
  headers: {
    "Authorization": "Bearer sk_live_YourApiKeyHere",
  },
});

const { data } = await res.json();
PATCH/api/v1/leads/:id

Update a lead’s status. Only the status field can be changed via the API.

Example request
const res = await fetch("https://www.shortstack.co.nz/api/v1/leads/abc-123", {
  method: "PATCH",
  headers: {
    "Authorization": "Bearer sk_live_YourApiKeyHere",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ status: "contacted" }),
});

const { data } = await res.json();

Webhooks

Register webhook endpoints from Dashboard → Settings → API to receive real-time notifications when leads are created or their status changes.

Available events

  • lead.created — A new lead has been submitted
  • lead.status_changed — A lead’s status was updated

Each webhook delivery includes an X-ShortStack-Signature header containing an HMAC-SHA256 signature of the request body, signed with your endpoint’s signing secret.

Verifying webhook signatures (Node.js)
import crypto from "crypto";

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

// In your handler:
const rawBody = await request.text();
const sig = request.headers.get("X-ShortStack-Signature");
if (!verifyWebhook(rawBody, sig, YOUR_SIGNING_SECRET)) {
  return new Response("Invalid signature", { status: 401 });
}

const event = JSON.parse(rawBody);
console.log(event.event);     // "lead.created"
console.log(event.data);      // { leadId: "...", ... }
console.log(event.timestamp); // "2026-03-28T09:15:00.000Z"

OpenAPI Spec

The full OpenAPI 3.0 specification is available at /api/v1/openapi.json. Import it into Postman, Insomnia, or any OpenAPI-compatible tool.

Need help with the API?