API Reference¶
HoneyDew exposes a REST API for managing boards, columns, cards, and labels. Resource endpoints are prefixed with /api; health and schema endpoints are not.
Overview¶
| Property | Value |
|---|---|
| Base URL | http://localhost:8000 |
| Auth | None (designed for local / trusted-network use) |
| Content type | application/json |
| Interactive docs | http://localhost:8000/docs (Swagger UI, auto-generated by FastAPI) |
| Live OpenAPI schema | openapi.json — authoritative request/response fields for your running version |
These are default local addresses. For a remote runtime, use its reachable private API base URL. Start with GET /api/config and GET /api/boards to discover profile and board IDs, then GET /api/boards/{id} for columns. IDs in examples are illustrative. Send the configured agent profile explicitly on agent-created cards and comments. File uploads use multipart form data, not JSON.
Health Check¶
Returns {"status": "healthy"} when the backend is running. Use this to verify connectivity before making API calls.
Configuration¶
Returns the application configuration (user and agent profile names, board definitions). Useful for agents that need to discover profile IDs at runtime.
Boards¶
List all boards¶
Returns an array of boards (id, name, created_at). Does not include nested columns/cards.
Create a board¶
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Board name (1–255 chars). |
columns |
string[] | No | Column names in order. Defaults to ["To Do", "In Progress", "Done"]. |
Get a board¶
Returns the board with all columns and cards. Supports an optional query parameter:
| Param | Type | Description |
|---|---|---|
profile |
string | Filter cards to only those owned by this profile ID. |
Update a board¶
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | No | New board name. |
Delete a board¶
Deletes the board and all its columns and cards. Returns 204 No Content.
Columns¶
Create a column¶
| Field | Type | Required | Description |
|---|---|---|---|
board_id |
int | Yes | The board to add the column to. |
name |
string | Yes | Column name (1–255 chars). |
position |
int | No | Position index (0-based). Appends to end if omitted. |
Update a column¶
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | No | New column name. |
position |
int | No | New position index. |
Delete a column¶
Deletes the column and all its cards. Returns 204 No Content.
Cards¶
List cards¶
| Param | Type | Description |
|---|---|---|
board_id |
int | Filter by board. |
column_id |
int | Filter by column (takes precedence over board_id). |
profile |
string | Filter by profile ID. |
priority |
int | Filter by priority (1–4). |
has_due_date |
bool | true = only cards with a due date; false = only cards without. |
include_archived |
bool | Include soft-archived cards. Defaults to false. |
Create a card¶
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
column_id |
int | Yes | — | Column to place the card in. |
title |
string | Yes | — | Card title (1–255 chars). |
description |
string | No | null |
Card description (max 5000 chars). |
priority |
int | No | 2 |
Priority: 1 = Low, 2 = Medium, 3 = High, 4 = Urgent. |
due_date |
string | No | null |
ISO 8601 date (YYYY-MM-DD). |
profile |
string | No | User profile | Profile ID of the card owner. Must be a valid profile from config. |
is_epic |
bool | No | false |
Make the card an Epic whose description stores the plan. |
epic_id |
int | No | null |
Link a task to an Epic on the same board. |
label_ids |
int[] | No | [] |
Existing project tags assigned directly to this issue. Unknown IDs reject the entire creation. |
Get a card¶
Returns the card with all fields and project tags. labels is the deduplicated union of direct_labels (assigned to this issue) and inherited_labels (its Parent Epic’s current tags). Inheritance applies to existing and new issues, including profile-filtered board/API responses; editing, replacing, or unlinking the Epic updates inherited tags without changing direct tags. Epics also include a shallow subtasks list with each child's current column_name for status display.
Update a card¶
label_ids replaces the issue’s direct tags atomically; omit it to preserve them, or send [] to clear them. Inherited tags remain while the issue belongs to the Epic. Create a shared tag through POST /api/labels first, then include its ID. The issue creation/editing form provides both selection and inline tag creation.
All fields are optional. Only provided fields are updated.
| Field | Type | Description |
|---|---|---|
title |
string | New title. |
description |
string | New description. |
priority |
int | New priority (1–4). |
due_date |
string | New due date (ISO 8601). |
profile |
string | New profile ID. |
is_epic |
bool | Convert an unlinked card to or from an Epic. |
epic_id |
int or null | Link or unlink the task from an Epic on the same board. |
completed_at |
string or null | Completion datetime. Set automatically on entry to Done and may be edited manually. |
archived_at |
string or null | Soft-archive datetime. Set to null to restore a card. |
agent_tokens_used |
int | Optional measured cumulative task total so far (0–9,007,199,254,740,991, integers only); replacement, not increment. Report during progress as well as completion. |
agent_model |
string | Model name used by the agent (optional, max 120 chars). |
agent_execution_time_seconds |
float | Agent execution time in seconds (optional). |
agent_started_at |
string | ISO 8601 datetime when the agent started work (optional). |
agent_completed_at |
string | ISO 8601 datetime when the agent finished (optional). |
These agent metadata fields support both progress and completion reports. Token totals appear beside priority on board cards and task subtitles, refreshed every five seconds. Omitted fields preserve existing values; explicit null on PATCH clears them. Usage remains unknown until measured and reported.
Acquire, renew, and release a task lease¶
Task leases prevent two agents from working the same card. HoneyDew acquires
them atomically and returns HTTP 409 when another live lease already owns the
card. Epics and archived cards cannot be leased.
POST /api/cards/{id}/lease/acquire
{"owner":"umbra","worker_session":"foreman-pending","ttl_seconds":1800}
POST /api/cards/{id}/lease/renew
{"lease_id":"<lease id>","worker_session":"<session key>","ttl_seconds":1800}
POST /api/cards/{id}/lease/release
{"lease_id":"<lease id>"}
Only the matching opaque lease_id may renew or release a lease. ttl_seconds
must be between 60 seconds and six hours and defaults to 30 minutes. An expired
lease is inactive and may be atomically replaced. Card responses expose the
lease fields plus task_lease_active; the UI shows Umbra working only while
that value is true. Moving a non-Epic card into a Done-equivalent or exact
Blocked column clears every lease field in the same database transaction.
Task dependencies¶
POST /api/cards/{id}/dependencies/{prerequisite_id} links a prerequisite;
DELETE on the same path removes the link. Self-links, cross-board links,
and cycles are rejected. Card responses include prerequisites, dependents,
dependencies_satisfied, and blocked_by_dependency_ids. An incomplete
prerequisite prevents lease acquisition with HTTP 409.
Tasks may use a task or Epic as a prerequisite; the selected card must reach a
completion column to satisfy the link. Epics themselves cannot have prerequisites.
Dependency summaries include is_epic to distinguish tasks and Epics.
Move a card¶
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
column_id |
int | Yes | — | Target column ID. |
position |
int | No | 0 |
Position within the target column (0-based). |
Handles position reordering automatically within and across columns.
Entering a Done-equivalent column sets completed_at; leaving it clears
completed_at and archived_at. Entering Done or Blocked also clears an active
task lease atomically; similarly named nonterminal columns such as Unblocked
do not.
Move a card to another board¶
| Field | Type | Required | Description |
|---|---|---|---|
board_id |
int | Yes | Target board ID. |
column_name |
string | No | Preferred column on the target board. |
Target column resolution:
- If
column_nameis provided and exists on the target board, it is used. - Otherwise, the card's current column name is matched on the target board.
- If no match, the first column of the target board is used.
Transfer a card¶
| Field | Type | Required | Description |
|---|---|---|---|
target_profile |
string | Yes | Profile ID to transfer the card to. Must be a valid profile from config. |
Delete a card¶
Deletes the card and reorders remaining cards in the column. Returns 204 No Content.
Labels¶
List all labels¶
Create a label¶
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name |
string | Yes | — | Label name (1–100 chars). |
color |
string | No | #6366f1 |
Hex color string (e.g. #ff00aa). |
Add a label to a card¶
Idempotent — adding an already-attached label is a no-op.
Remove a label from a card¶
Returns 204 No Content.
Comments¶
List comments on a card¶
Returns an array of comments for the card, ordered by created_at.
Add a comment to a card¶
Optional agent_tokens_used reports a measured cumulative task total atomically with the comment (same integer limits as PATCH). Omitted or null preserves existing usage; zero records measured zero. A repeated total replaces rather than adds. Invalid counts reject the entire request.
| Field | Type | Required | Description |
|---|---|---|---|
body |
string | Yes | Comment text (1–5000 chars). |
profile |
string | Yes | Explicit profile ID of the commenter. Omitting it is rejected so agent activity cannot be attributed to the configured user. |
Returns the created comment object:
{
"id": 1,
"card_id": 5,
"profile": "tony",
"body": "Looks good, moving to Done.",
"created_at": "2026-02-22T14:30:00"
}
Priority Values¶
| Value | Name | Description |
|---|---|---|
| 1 | Low | Low-priority work. |
| 2 | Medium | Default priority. |
| 3 | High | Important work that should be addressed soon. |
| 4 | Urgent | Critical work that needs immediate attention. |
Issue activity timestamps¶
Card.updated_at powers Date last updated. It records the most recent
persisted direct change to an issue, not the most recent change anywhere in its
rendered/derived response. New relationship timestamps use the same installation-
local, timezone-naive clock as existing card field updates, not storage objects'
UTC clock.
| Mutation | Cards whose updated_at changes |
|---|---|
| Changed card fields, profile, column, position, completion/archive or agent metadata | The changed cards (including cards shifted by reordering). |
| Successful lease acquire, renew or release | The leased card; renewal is real expiry/heartbeat activity. |
| Add a comment | Its parent card. Every accepted POST creates a new comment, even with repeated text. Comments currently have no edit/delete API. |
| Add/remove a label | The card, only if membership changes. |
| Rename/recolor/delete a shared label | All directly labeled cards, including archived cards, only on a real change. |
| Add/remove a prerequisite link | Both endpoints, only if the link changes. |
| Create/link/unlink/reassign an Epic child | The child and old/new parent Epics whose membership changes. |
| Delete a card (also via column/board deletion) | Surviving prerequisite/dependent endpoints, its parent Epic, and children unlinked from a deleted Epic. |
| Publish/link/detach/rename an attachment | Its parent card, only if the link or normalized display filename changes. |
| Rename a column/status | Cards directly in that column, only if the name changes. |
Relationship timestamps are written in the same database transaction as the relationship mutation. Rejected operations and rolled-back writes leave them unchanged. A failed upload never bumps a card unless its attachment is successfully published. Duplicate label/prerequisite additions, removal of absent links, idempotent upload retries, duplicate object attachments, same-name attachment renames, same-value field patches and same-position moves do not bump timestamps.
Reads, polling, downloads, standalone object operations, board renames and column reordering do not count as issue activity. There is no transitive timestamp propagation: changes in prerequisite completion/readiness, linked card titles, Epic child progress, or inherited Epic labels can change a displayed result without updating the observing card. Direct membership changes still count as specified above. Automatic archival retains its existing direct-write semantics.
This policy applies prospectively. No migration/backfill rewrites historical
created_at, updated_at, completion or comment timestamps; earlier unrecorded
relationship activity cannot be reconstructed from today's state.
Card Response Shape¶
All card endpoints return a consistent object:
{
"id": 1,
"column_id": 2,
"profile": "jarvis",
"title": "Implement feature X",
"description": "Details here",
"priority": 3,
"due_date": "2026-03-01",
"position": 0,
"created_at": "2026-02-22T10:30:00",
"updated_at": "2026-02-22T11:45:00",
"labels": [
{ "id": 1, "name": "frontend", "color": "#06b6d4" }
],
"comments": [
{ "id": 1, "card_id": 1, "profile": "tony", "body": "Started working on this.", "created_at": "2026-02-22T12:00:00" }
],
"agent_tokens_used": null,
"agent_model": null,
"agent_execution_time_seconds": null,
"agent_started_at": null,
"agent_completed_at": null
}
Error Responses¶
Errors return a JSON body with a detail field:
| Status | Meaning |
|---|---|
| 400 | Bad request (invalid profile, missing fields, board has no columns). |
| 404 | Resource not found. |
| 422 | Validation error (Pydantic). |
File attachments and storage¶
See Attachments and S3-compatible storage for issue/Epic uploads, managed-object APIs, native MCP, host file roots, limits, retention and backup/restore.
Settings¶
PATCH /api/config: updateuser_display_name,agent_display_name, and/orarchive_completed_after_hours(null or zero disables archiving). Existing profile IDs cannot be changed through this endpoint.POST /api/profiles: create an additional profile withprofile_id,display_name, androle(useroragent, defaultuser). IDs use lowercase letters, numbers, hyphens, and underscores, begin with a letter or number, and must be unique. Duplicate IDs return 409.PATCH /api/boards/{id}/theme: setthemetomidnight,umbra,ember,verdant,executive, orlinen.
These endpoints return the updated application configuration and persist narrow, atomic updates to the active config file while preserving unrelated fields. Changes take effect without restarting. POST /api/boards creates a board with default columns when none are supplied; boards now survive startup even when not listed in config.