API Reference

Milestones

Manage project milestones and milestone status.

REST /api/v1API key authentication6 endpoints
GET/api/v1/milestones

List milestones with filters

Query schema
const listQuerySchema = z.object({
  projectId: z.string().uuid().optional(),
  status: z.enum(['upcoming', 'at_risk', 'completed', 'overdue']).optional(),
  dateFrom: z
    .string()
    .regex(/^\d{4}-\d{2}-\d{2}$/)
    .optional(),
  dateTo: z
    .string()
    .regex(/^\d{4}-\d{2}-\d{2}$/)
    .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/milestones

Create a new milestone

JSON body schema
const createBodySchema = z.object({
  projectId: z.string().uuid(),
  name: z.string().min(1),
  targetDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
  description: z.string().optional(),
  triggersInvoice: z.boolean().optional(),
  completionCriteria: z.array(completionCriterionSchema).optional(),
});
Response201JSON response.
DELETE/api/v1/milestones/:id

Delete a milestone

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

Get milestone by ID

Path parametersid: string
Response200JSON response.
PATCH/api/v1/milestones/:id

Update a milestone

Path parametersid: string
JSON body schema
const updateBodySchema = z.object({
  name: z.string().min(1).optional(),
  targetDate: z
    .string()
    .regex(/^\d{4}-\d{2}-\d{2}$/)
    .optional(),
  description: z.string().nullable().optional(),
  triggersInvoice: z.boolean().optional(),
  completionCriteria: z.array(completionCriterionSchema).optional(),
});
Response200JSON response.
POST/api/v1/milestones/:id/complete

Mark a milestone as complete

Path parametersid: string
JSON body schema
const completeBodySchema = z.object({
  completedDate: z
    .string()
    .regex(/^\d{4}-\d{2}-\d{2}$/)
    .optional(),
});
Response200JSON response.