Skip to content

Recurring Tasks API

All endpoints require a Bearer JWT token. Recurring tasks are scoped to a workspace.

Base URL: https://api.hule-do.com/api


POST /workspaces/:workspaceId/recurring-tasks

Create a new recurring task series.

Request:

json
{
  "title": "Weekly standup notes",
  "description": "What I worked on, what's blocking me, next steps",
  "listId": "667f...",
  "spaceId": "667f...",
  "interval": {
    "frequency": "week",
    "every": 1,
    "daysOfWeek": ["mon", "wed", "fri"],
    "timeOfDay": "09:00",
    "timezone": "Europe/Moscow"
  },
  "endCondition": {
    "type": "after_n",
    "count": 50
  },
  "spawnStatusId": "667f...",
  "priority": "medium",
  "tagIds": ["667f..."]
}

interval fields:

FieldTypeRequiredNotes
frequencystringyesday, week, month, year
everynumberyesStep: every N days/weeks/months/years
daysOfWeekstring[]for weekmon, tue, wed, thu, fri, sat, sun
monthDaynumberfor monthDay of month (1–31)
monthOfYearnumberfor yearMonth (1–12)
timeOfDaystringyesHH:MM in 24h format
timezonestringyesIANA timezone, e.g. America/New_York

endCondition fields:

TypeAdditional fields
never
on_datedate (ISO 8601)
after_ncount (number)

Response: 201

json
{
  "id": "667f...",
  "title": "Weekly standup notes",
  "interval": { /* ... */ },
  "nextRunAt": "2026-06-02T06:00:00.000Z",
  "spawnCount": 0,
  "active": true,
  "createdAt": "2026-05-28T10:00:00.000Z"
}

GET /workspaces/:workspaceId/recurring-tasks

List all recurring task series in the workspace.

Response: 200 — array of recurring job objects.


GET /workspaces/:workspaceId/recurring-tasks/:id

Get a single recurring job.

Response: 200 — recurring job object.


PATCH /workspaces/:workspaceId/recurring-tasks/:id

Update a recurring job. Omitted fields are not changed.

Request:

json
{
  "active": false,
  "title": "Updated meeting title"
}

Response: 200 — updated recurring job.


DELETE /workspaces/:workspaceId/recurring-tasks/:id

Delete the recurring series. Existing spawned task instances are preserved.

Response: 204 No Content


POST /workspaces/:workspaceId/recurring-tasks/:id/skip

Skip the next occurrence. The job's nextRunAt is advanced past the current candidate by adding it to skipDates[].

Request: (no body)

Response: 204 No Content


POST /workspaces/:workspaceId/recurring-tasks/:id/skip-until

Skip all occurrences until a specific date. Pass null to clear.

Request:

json
{
  "skipUntil": "2026-06-15T00:00:00.000Z"
}

Response: 204 No Content


POST /workspaces/:workspaceId/recurring-tasks/:jobId/instances/:taskId/edit-mode

Edit a spawned task instance with control over how the change propagates.

Request:

json
{
  "mode": "this",
  "updates": {
    "title": "Updated standup topic",
    "priority": "high"
  }
}

mode values:

ModeBehaviour
thisUpdate only this instance. The occurrence date is added to the series' skip list.
this_and_followingSplit the series. End the current series before this date and create a new one with the changes.
allUpdate this instance + the template + all past instances (title, description, priority, tags).

Response: 200 — updated TaskDto.


GET /workspaces/:workspaceId/recurring-tasks/:id/instances

List all task instances spawned from this recurring job.

Query parameters: page, limit.

Response: 200

json
{
  "items": [ /* TaskDto[] */ ],
  "total": 12,
  "page": 1,
  "limit": 20
}

Errors

CodeMeaning
400Invalid interval or end condition
404Recurring job not found