Api

API keys and signed webhooks

Connect your own tools without sharing credentials or losing retry safety.

Applies to V1.2+ · Checked July 2026

Before you start

  • Workspace owner or administrator access
  • A public HTTPS receiver for outbound webhooks

Choose the integration boundary

Use a tenant API key for deliberate resource access. Use an inbound webhook when another system needs to trigger a Cygnetree automation. Use an outbound webhook when Cygnetree must notify a tenant-controlled system.

Keys, endpoints, secrets, mappings, checkpoints, and retry state belong to one workspace. They are not Cygnetree platform credentials and never authorize another tenant.

Create and protect an API key

Create the narrowest key that supports the integration. Copy the secret when it is shown, store it in the receiving system's secret manager, and record its owner and rotation date.

A key carries workspace permissions, not workspace ownership. No key can manage your team, your integrations, or your workspace settings, whoever creates it. A key can never do more than the person who created it can do, and that limit is re-checked on every request — if their access is reduced, suspended, or removed, every key they created narrows or stops with them.

Before a key exists, Cygnetree states plainly what an outside system will be able to see and asks you to confirm it. Client contact details, money records, documents, messages, calendar bookings, reporting, and bulk export are all called out by name, because those are the things that leave your workspace and cannot be pulled back.

Each of those lines is a tick box, and you untick anything the integration does not need. A calendar sync has no business reading your contracts. The narrowed set is stored on the key and checked on every request alongside your own access, so a key cannot be widened later by editing the receiving system's configuration — you create a new, narrower key instead.

Settings shows each key's reach, when it was last used, and who created it. A key whose creator has lost access is marked as no longer working rather than left looking healthy. Revoking is immediate and cannot be undone.

Send a key only over HTTPS in the documented authorization header. Never put a key in browser code, query strings, logs, screenshots, support tickets, or webhook bodies. Revoke it immediately if it may have been exposed.

Use the tenant REST API

The V1 API currently supports:

| Method | Path | Result | | --- | --- | --- | | GET | /api/v1/contacts?q= | Up to 100 active people | | POST | /api/v1/contacts | Create or match a person | | GET | /api/v1/projects | Up to 100 active projects | | GET | /api/v1/bookings | Up to 100 bookings | | GET | /api/v1/invoices | Up to 100 invoices; amounts use integer cents |

Send the workspace key as Authorization: Bearer cyg_…. Never put it in a URL. The machine-readable OpenAPI 3.1 contract is available from /api/v1/openapi.json on the application origin and is generated from the same versioned operation registry validated in CI.

bash
curl --fail-with-body \
  --header "Authorization: Bearer $CYGNETREE_API_KEY" \
  "https://app.cygnetree.com/api/v1/projects"
bash
curl --fail-with-body \
  --request POST \
  --header "Authorization: Bearer $CYGNETREE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{"name":"Example client","email":"client@example.com"}' \
  "https://app.cygnetree.com/api/v1/contacts"

Treat 401, 403, and 429 differently: rotate or correct the key after 401, honor the request budget after 429, and read the message on a 403 — it names either the permission the key is missing or the fact that the key's creator no longer has access. Every 403 of that kind is also recorded in your workspace history, so a request that used to succeed can be traced to the change that stopped it. A create response includes a correlation reference for support without exposing credentials.

Connect an MCP client

The streamable HTTP endpoint is /api/mcp on the application origin. Use the same workspace API key as a bearer token. The server is stateless and scopes every discovery and tool call to the workspace that owns that key.

json
{
  "url": "https://app.cygnetree.com/api/mcp",
  "headers": {
    "Authorization": "Bearer cyg_replace_with_the_one_time_value"
  }
}

Tool discovery is capability- and permission-aware. A client sees only the tools this workspace has enabled and this key is allowed to call, and every invocation checks both again so a stale client cannot bypass a later policy change. get_project_status answers with the sections the key may read and names the ones it withheld, rather than reporting an empty result it was never allowed to look at.

| Tool | Mutation | Purpose | | --- | --- | --- | | list_projects | No | List active projects with client, stage, and event date | | search_people | No | Find people by a name or email fragment | | get_project_status | No | Read a project's tasks, bookings, and invoice summary | | create_contact | Yes | Create a person, deduplicating a supplied email | | create_task | Yes | Create a task, optionally attached to a project |

The source-owned tool registry publishes descriptions, JSON input shapes, capability ownership, and read-only/idempotency/destructive/open-world annotations. Treat mutation tools as deliberate actions even when the connected MCP client offers its own confirmation interface. Revoke the workspace key to stop the client; there is no separate platform-wide MCP credential.

Receive an inbound event

Create an inbound webhook under Settings → Integrations. Each request includes:

  • x-cygnetree-event-id: a unique delivery identifier;
  • x-cygnetree-event-type: a stable lowercase event name;
  • x-cygnetree-timestamp: current Unix seconds; and
  • x-cygnetree-signature: sha256= plus the HMAC-SHA256 of timestamp.raw_request_body.

Cygnetree rejects an invalid signature, stale timestamp, oversized body, unsafe replay, or reused event ID with different content. It retains a safe processing record, not arbitrary body content.

Verify an outbound event

Register one public HTTPS destination. Cygnetree validates DNS and rejects embedded credentials, unusual ports, local/private/link-local/metadata addresses, and insecure HTTP.

Verify the signature over the exact raw body before parsing JSON. Compare signatures in constant time, reject stale timestamps, and record the event ID before starting a side effect.

Handle retries and idempotency

Return a successful response only after the event is durably accepted. A receiver may see the same event more than once. Use the event ID as the idempotency key and return success for an exact duplicate.

Do not infer identity or money state from delivery order. Fetch or reconcile the current resource when correctness depends on more than the event itself. Inspect Cygnetree retry/dead-letter state before replaying a failed automation step.

Rotate or disconnect

Test the endpoint, then rotate one side at a time during a controlled window. Rotation immediately invalidates the old secret. Disconnect removes the encrypted destination/secret and causes dependent recipes to fail visibly until another registered destination is selected.

Export the configuration metadata and remove obsolete keys during tenant offboarding. Secret material is never included in a project or workspace export.

Keep going

Did this guide get you unstuck?

If not, tell us — this opens a support conversation with the guide already attached, and a real person reads it. If the guide is wrong or missing something, we fix the guide.

Tell us what's missing