Skip to content

Developers

Build on Clientwright

A versioned REST API, signed webhooks and polling triggers for automation platforms.

Start here

Quick start

Create a key in Settings, Integrations, then call the API. The full machine-readable spec is in the OpenAPI file.

curl https://clientwright.com/api/v1/contacts?limit=10 \
  -H "Authorization: Bearer cw_live_..."

Download the OpenAPI file

Authentication

Send your key as Authorization: Bearer <key> (or the X-API-Key header). Keys belong to one workspace and only see its data. Each key has a scope per object: none, read, or read and write. Keys are shown once, stored hashed, and can be rotated or revoked at any time.

curl https://clientwright.com/api/v1/me -H "Authorization: Bearer cw_live_..."

Resources

Every resource supports list, get, create, update (PATCH) and delete.

  • /contacts
  • /companies
  • /deals
  • /activities
  • /notes
  • /lists
  • /products
  • /quotes
  • /tickets
  • /objects/{object_id}
curl -X POST https://clientwright.com/api/v1/contacts \
  -H "Authorization: Bearer cw_live_..." \
  -H "Content-Type: application/json" \
  -d '{"name":"Ada Lovelace","email":"ada@example.com"}'

Filters, sorting and pages

Use limit (up to 100) and offset for pages, sort=-created_at for order, filter[field]=value for exact matches, and updated_since or created_since with an ISO date.

GET https://clientwright.com/api/v1/deals?filter[owner_id]=...&sort=-amount&limit=50&offset=50

Errors and limits

Errors always return {"error":{"code":"...","message":"..."}} with a matching status: 400, 401, 403, 404, 405, 409, 422 or 429. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. Over the limit, requests get 429 until the minute resets; nothing is ever billed.

Webhooks

Admins subscribe HTTPS addresses to events. Each delivery is a JSON POST with header X-Clientwright-Signature: t=<unix>,v1=<hex>, where v1 is HMAC-SHA256 of `${t}.${body}` with your endpoint secret. Reject signatures older than five minutes.

const [t, v1] = header.split(",").map((p) => p.split("=")[1]);
const expected = hmacSha256Hex(secret, t + "." + rawBody);
if (!timingSafeEqual(expected, v1) || Date.now() / 1000 - t > 300) reject();

Failed deliveries retry after 1 minute, 5 minutes, 30 minutes, 2 hours and 12 hours. After repeated failures the endpoint is turned off and admins are notified. The delivery log supports replay.

party.created
party.updated
party.deleted
deal.created
deal.updated
deal.deleted
deal.stage_changed
activity.created
activity.updated
activity.deleted
quote.created
quote.updated
quote.accepted
invoice.created
invoice.updated
product.created
product.updated
record.created
record.updated
record.deleted
ticket.created
ticket.updated
ticket.deleted
ticket.status_changed
ticket.sla_breached
lead.converted
form.submitted
chat.started
campaign.open
campaign.click
campaign.unsubscribe
campaign.bounce

Automation platforms

Polling triggers return new or updated records, newest first. Use them from any automation platform that supports polling with an API key.

GET https://clientwright.com/api/v1/triggers/contacts?event=created&since=2026-10-01T00:00:00Z
GET https://clientwright.com/api/v1/triggers/deals?event=updated

Actions use the normal create (POST) and update (PATCH) endpoints.

Plans

  • Starter: read-only keys, 60 requests per minute.
  • Growth: read and write keys, webhooks (up to 10), triggers, 120 per minute.
  • Business: up to 50 webhooks, delivery log export, 600 per minute.

See pricing for all plan details.