API Reference

Batch Operations

Create, update, or remove multiple records in one request.

REST /api/v1API key authentication3 endpoints
DELETE/api/v1/batch/time-entries

Delete multiple time entries in a single request

JSON body schema
const MAX_BATCH_SIZE = 100;

const deleteBatchSchema = z.object({
  ids: z.array(z.string().uuid()).min(1).max(MAX_BATCH_SIZE),
});
Response200JSON response with a data envelope.
PATCH/api/v1/batch/time-entries

Update multiple time entries in a single request

JSON body schema
const updateItemSchema = z.object({
  id: z.string().uuid(),
  taskId: z.string().uuid().optional(),
  resourceId: z.string().uuid().optional(),
  date: z
    .string()
    .regex(/^\d{4}-\d{2}-\d{2}$/)
    .optional(),
  hours: z.number().min(0).max(24).optional(),
  startTime: z
    .string()
    .regex(/^\d{2}:\d{2}(:\d{2})?$/)
    .nullable()
    .optional(),
  description: z.string().nullable().optional(),
  isBillable: z.boolean().optional(),
  billableRate: z.number().min(0).nullable().optional(),
  tags: z.array(z.string()).optional(),
});

const MAX_BATCH_SIZE = 100;

const updateBatchSchema = z.object({
  updates: z.array(updateItemSchema).min(1).max(MAX_BATCH_SIZE),
});
Response200JSON response with a data envelope.
POST/api/v1/batch/time-entries

Create multiple time entries in a single request

JSON body schema
const timeEntryInputSchema = z.object({
  taskId: z.string().uuid(),
  resourceId: z.string().uuid(),
  date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
  hours: z.number().min(0).max(24),
  startTime: z
    .string()
    .regex(/^\d{2}:\d{2}(:\d{2})?$/)
    .optional(),
  description: z.string().nullable().optional(),
  isBillable: z.boolean().optional(),
  billableRate: z.number().min(0).optional(),
  tags: z.array(z.string()).optional(),
});

const MAX_BATCH_SIZE = 100;

const createBatchSchema = z.object({
  entries: z.array(timeEntryInputSchema).min(1).max(MAX_BATCH_SIZE),
});
Response200JSON response with a data envelope.