API authentication

How to call the Harmonia public REST API.

Harmonia exposes a REST API at /api/public/v1. Every request needs an API key on the Authorization: Bearer <key> header.

Get an API key

In Harmonia, open Settings → API → Keys. Click Create key. Give it a name and scopes. You'll get a one-shot key shaped like hk_live_…. Copy it — we hash it on the server and cannot show it again.

Make a request

curl https://app.harmoniacrm.com/api/public/v1/contacts \
  -H "Authorization: Bearer hk_live_…" \
  -H "Accept: application/json"

Response shape

Every endpoint returns the same envelope:

{
  "data": [...],
  "meta": {
    "page": 1,
    "limit": 50,
    "total": 1247
  }
}

Errors come back as:

{
  "error": "validation_failed",
  "message": "email must be a valid address",
  "issues": [...]
}

with the relevant HTTP status (400, 401, 403, 404, 422, 429).

Idempotency

Mutation endpoints accept Idempotency-Key: <uuid>. Same key + same payload within 24h returns the cached result. Different payload with the same key returns 409 conflict.

Webhooks

Subscribe to events at Settings → API → Webhooks. Webhook bodies are signed with HMAC-SHA256 in the X-Harmonia-Signature header. The signing key is shown once at creation.

import crypto from "crypto";

function verify(body: string, sig: string, secret: string): boolean {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(body, "utf8")
    .digest("hex");
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig));
}

Next