API Reference

Webhooks

Manage webhook subscriptions for integration events.

REST /api/v1API key authentication9 endpoints
GET/api/v1/webhooks

List webhook subscriptions

Query schema
const listQuerySchema = z.object({
  isActive: z
    .string()
    .transform((val) => val === 'true')
    .optional(),
  limit: z.coerce.number().int().min(1).max(100).default(50),
  offset: z.coerce.number().int().min(0).default(0),
});
Response200JSON response with data and pagination envelopes.
POST/api/v1/webhooks

Create a new webhook subscription

JSON body schema
const webhookEventSchema = z.enum([
  'invoice.created',
  'invoice.sent',
  'invoice.paid',
  'invoice.overdue',
  'quote.created',
  'quote.sent',
  'quote.accepted',
  'quote.rejected',
  'project.created',
  'project.completed',
  'task.created',
  'task.completed',
  'time_entry.created',
  'expense.created',
  'expense.approved',
  'milestone.completed',
]);

const createBodySchema = z.object({
  name: z.string().min(1).max(255),
  url: z.string().url().max(500),
  events: z.array(webhookEventSchema).min(1),
  description: z.string().optional(),
  isActive: z.boolean().default(true),
});
Response201JSON response with a data envelope.
DELETE/api/v1/webhooks/:id

Delete a webhook subscription

Path parametersid: string
Response204No response body.
GET/api/v1/webhooks/:id

Get webhook by ID (includes secret)

Path parametersid: string
Response200JSON response with a data envelope.
PATCH/api/v1/webhooks/:id

Update a webhook subscription

Path parametersid: string
JSON body schema
const webhookEventSchema = z.enum([
  'invoice.created',
  'invoice.sent',
  'invoice.paid',
  'invoice.overdue',
  'quote.created',
  'quote.sent',
  'quote.accepted',
  'quote.rejected',
  'project.created',
  'project.completed',
  'task.created',
  'task.completed',
  'time_entry.created',
  'expense.created',
  'expense.approved',
  'milestone.completed',
]);

const updateBodySchema = z.object({
  name: z.string().min(1).max(255).optional(),
  url: z.string().url().max(500).optional(),
  events: z.array(webhookEventSchema).min(1).optional(),
  description: z.string().nullable().optional(),
  isActive: z.boolean().optional(),
});
Response200JSON response with a data envelope.
GET/api/v1/webhooks/:id/deliveries

List delivery attempts for a webhook

Path parametersid: string
Query schema
const listDeliveriesQuerySchema = z.object({
  status: z.enum(['pending', 'delivered', 'failed', 'retrying']).optional(),
  limit: z.coerce.number().int().min(1).max(100).default(50),
  offset: z.coerce.number().int().min(0).default(0),
});
Response200JSON response with data and pagination envelopes.
POST/api/v1/webhooks/:id/rotate-secret

Rotate the webhook secret

Path parametersid: string
Response200JSON response with a data envelope.
POST/api/v1/webhooks/:id/test

Send a test event to the webhook

Path parametersid: string
Response200JSON response with a data envelope.
GET/api/v1/webhooks/events

List available webhook event types

Response200JSON response with a data envelope.