# API Changelog

> Notable changes to the Seedly CRM REST API.

All notable changes to the Seedly CRM REST API.

---

## Replay-protected webhook signature, and two response fixes

### Added

- **`X-Webhook-Signature-V2`** on every outbound webhook delivery. It signs `<timestamp>.<body>` with your existing per-subscription secret, so a receiver can trust `X-Webhook-Timestamp` and reject a replayed delivery outside a freshness window. This is additive: `X-Webhook-Signature` is still sent, unchanged, and integrations that verify it keep working. See [Webhook Payloads](/docs/help/webhooks#delivery-headers-and-verification) for the verification snippet.

### Fixed

- **By-id and sub-resource routes resolve.** Routes addressing a single record or a nested resource under it were not being matched and returned a not-found response. They now behave as documented. If you worked around this by listing and filtering client-side, you can go back to addressing the record directly.
- **`meta.total` is the size of the full result set**, not the number of records in the current page. If you were treating `total` as a page count, or computing a total by summing it across pages, correct that when you upgrade.

---

## Expanded Webhook Events

### Added

The outbound webhook catalog has grown from the original 15 events to **26**. The following events are now available to subscribe to, in addition to the launch set:

- `opportunity.updated`, `opportunity.deleted`
- `appointment.cancelled`, `appointment.rescheduled`, `appointment.confirmed`, `appointment.completed`, `appointment.no_show`
- `task.created`, `task.updated`, `task.completed`, `task.deleted`

Existing subscriptions are unaffected. See the [REST API](/docs/help/api#7-webhooks-real-time-events) and [Webhook Payloads](/docs/help/webhooks) pages for the full list and payload shapes.

---

## 2026-03-27 - Agency-Scoped API Keys

### Added

- **Agency-scoped API keys** - Create a single API key that operates across all sub-accounts under an agency. Prefix: `sk_agency_live_` (production) and `sk_agency_test_` (sandbox). Requires `X-Sub-Account-Id` header on every request.
- **`GET /api/v1/sub-accounts`** - Discovery endpoint to list available sub-accounts. Only accessible with agency-scoped keys.
- New error codes: `MISSING_SUB_ACCOUNT` (400), `INVALID_SUB_ACCOUNT` (403)

---

## 2026-03-27 - v1 Launch

Initial release of the public REST API.

### Added

**Authentication:**

- API key authentication with `sk_live_` (production) and `sk_test_` (sandbox) prefixes
- Scoped permissions: `contacts:read`, `contacts:write`, `conversations:read`, `conversations:write`, `calendars:read`, `calendars:write`, `webhooks:manage`
- Test mode keys - messages recorded but not sent to providers

**Contacts:**

- `GET /api/v1/contacts` - list/search contacts, exact email lookup via `email` param
- `GET /api/v1/contacts/{id}` - get contact
- `POST /api/v1/contacts` - create contact
- `PATCH /api/v1/contacts/{id}` - update contact
- `DELETE /api/v1/contacts/{id}` - soft-delete contact
- `GET /api/v1/contacts/fields` - list custom field definitions

**Conversations:**

- `GET /api/v1/conversations` - list conversations, filter by `contactId`
- `GET /api/v1/conversations/{id}` - get conversation
- `POST /api/v1/conversations` - create or find existing conversation
- `GET /api/v1/conversations/{id}/messages` - list messages (cursor-based pagination)
- `POST /api/v1/conversations/{id}/messages` - send message (all channels)
- `PATCH /api/v1/conversations/{id}` - update status/assignment

**Calendars:**

- `GET /api/v1/calendars` - list active calendars
- `GET /api/v1/calendars/types` - list appointment types
- `GET /api/v1/calendars/availability` - check available slots
- `GET /api/v1/calendars/appointments` - list appointments
- `POST /api/v1/calendars/appointments` - book appointment
- `DELETE /api/v1/calendars/appointments/{id}` - cancel appointment

**Webhooks:**

- `GET /api/v1/webhooks` - list subscriptions
- `POST /api/v1/webhooks` - create subscription
- `PATCH /api/v1/webhooks/{id}` - update subscription
- `DELETE /api/v1/webhooks/{id}` - delete subscription
- `POST /api/v1/webhooks/{id}/regenerate-secret` - regenerate signing secret
- 15 webhook events: `contact.created`, `contact.updated`, `contact.lifecycle_changed`, `contact.tag_added`, `opportunity.created`, `opportunity.stage_changed`, `opportunity.won`, `opportunity.lost`, `message.received`, `message.sent`, `message.delivered`, `message.failed`, `appointment.booked`, `form.submitted`, `invoice.paid`

**General:**

- Per-key rate limiting with separate limits for read and write operations
- ISO 8601 timestamps in all responses
- Usage logging per API key
- Automated cleanup of expired keys and old usage logs

---
Source: https://seedlycrm.com/docs/help/api-changelog
