API Reference
Webhooks
Manage webhook subscriptions for integration events.
REST /api/v1API key authentication9 endpoints
GET
/api/v1/webhooksList 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/webhooksCreate 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/:idDelete a webhook subscription
Path parametersid: string
Response204No response body.
GET
/api/v1/webhooks/:idGet webhook by ID (includes secret)
Path parametersid: string
Response200JSON response with a data envelope.
PATCH
/api/v1/webhooks/:idUpdate 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/deliveriesList 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-secretRotate the webhook secret
Path parametersid: string
Response200JSON response with a data envelope.
POST
/api/v1/webhooks/:id/testSend a test event to the webhook
Path parametersid: string
Response200JSON response with a data envelope.
GET
/api/v1/webhooks/eventsList available webhook event types
Response200JSON response with a data envelope.