Issue model (stories & bugs)
Flik stores stories and bugs as a single kind of record: an issue. The type field is either story or bug. Everything below is the canonical JSON shape returned by the API and accepted on create/update (snake_case keys). The CLI and MCP are thin clients over this model—they do not define a separate schema.
Authentication: All issue endpoints use the CLI API: Authorization: Bearer <api_key>, and org context via X-Flik-Org when your key is org-scoped. Paths below are under /api/cli.
API routes (summary)
| Method | Path | Purpose |
|---|---|---|
GET |
/projects/:acronym/stories |
List stories in the project |
POST |
/projects/:acronym/stories |
Create a story (type is story) |
GET |
/projects/:acronym/bugs |
List bugs |
POST |
/projects/:acronym/bugs |
Create a bug (type is bug) |
GET |
/projects/:acronym/stories/:id or .../bugs/:id |
Get one issue by id |
PATCH |
/projects/:acronym/stories/:id or .../bugs/:id |
Update one issue (partial) |
DELETE |
/projects/:acronym/stories/:id or .../bugs/:id |
Delete one issue |
GET |
/projects/:acronym/objects/:id |
Get story or bug by id (same payload) |
PATCH |
/projects/:acronym/objects/:id |
Update story or bug by id |
DELETE |
/projects/:acronym/objects/:id |
Delete story or bug by id |
Query parameters on list: optional assigned_to (Clerk user id, or the API may resolve me where supported).
List responses: { "ok", "code", "count", "items": [ ... ] }. Single-issue responses: { "ok", "code", "item": { ... } }. Create responses: { "ok", "code", ... } with the same fields as one issue object at the top level (plus ok / code).
Identity & scope
| JSON key | Type | Description |
|---|---|---|
id |
string | Stable display id: <project_acronym>-<sequence> (e.g. mypr-1). Assigned by the server on create. |
type |
string | story or bug. Fixed by whether you POST to /stories or /bugs. |
project_id |
string | Internal project id (not the acronym). Read-only for clients. |
Field reference
Applies to: both = meaningful for every issue; story / bug = primarily used for that type (other type may store empty or zero values).
Create: fields omitted from the JSON body use the defaults below (where noted). PATCH: only include keys you want to change; omitted keys are left unchanged.
Arrays on PATCH: labels, blocks, and blocked_by are replaced in full when you send them—send the complete new list.
| JSON key | Type | Applies to | Required on create | Default on create (if omitted) | PATCH | Description |
|---|---|---|---|---|---|---|
title |
string | both | Yes | — | Yes | Short summary of the work item. |
assigned_to |
string | both | No | (empty) | Yes | Clerk user id of the assignee. Empty means unassigned. |
status |
string | both | No | open |
Yes | Workflow: open, in_progress, done, cancelled (lowercase). Invalid values are rejected. |
priority |
string | both | No | medium |
Yes | Free-form label; default applied by the server is medium. |
points |
integer | story | No | 0 |
Yes | Story points. Typically 0 for bugs unless you use points on bugs too. |
notes |
string | story† | No | (empty) | Yes | Short notes. |
severity |
string | bug | No | medium |
Yes | Bug severity (e.g. low/medium/high); server default medium. |
description |
string | both | No | (empty) | Yes | Longer body text. Recommended for detailed specs (stories) and bug narratives. |
acceptance_criteria |
string | story | No | (empty) | Yes | Story acceptance criteria (often markdown-style text). |
steps_to_reproduce |
string | bug | No | (empty) | Yes | Bug reproduction steps. |
expected |
string | bug | No | (empty) | Yes | Expected behavior. |
actual |
string | bug | No | (empty) | Yes | Actual behavior observed. |
environment |
string | bug | No | (empty) | Yes | Where it happens (e.g. prod, staging, browser). |
regression |
boolean | bug | No | false |
Yes | Whether this is a regression. |
affected_version |
string | bug | No | (empty) | Yes | Version affected. |
fixed_in_version |
string | bug | No | (empty) | Yes | Version containing the fix (when known). |
due_at |
string | both | No | (empty) | Yes | Due date/time; use RFC3339 (e.g. 2026-03-20T17:00:00Z). |
labels |
array of string | both | No | (none) | Yes | Tags; empty strings are stripped on write. |
component |
string | both | No | (empty) | Yes | Component, area, or subsystem name. |
external_ref |
string | both | No | (empty) | Yes | Link to an external system (e.g. GitHub issue URL). |
metadata |
object | both | No | (none) | Yes | Arbitrary JSON-serializable key/value map for integrations. Replaced in full when sent on PATCH. |
parent_id |
string | both | No | (empty) | Yes | Parent issue id (same project). Must exist; cannot equal this issue’s id. |
blocks |
array of string | both | No | (none) | Yes | Ids this issue blocks. |
blocked_by |
array of string | both | No | (none) | Yes | Ids that block this issue. |
sprint_id |
string | both | No | (empty) | Yes | Sprint or iteration identifier (convention up to your team). |
created_at |
string | both | — | Set by server | No | RFC3339 creation time. |
updated_at |
string | both | — | Set by server | No | RFC3339 last update time. |
created_by |
string | both | — | Current user on create | No | Clerk user id who created the issue. |
updated_by |
string | both | — | Current user on each PATCH | No | Clerk user id who last updated the issue. |
resolved_at |
string | both | — | See Status & timestamps | No | Set/cleared by the server with status. |
closed_at |
string | both | — | See Status & timestamps | No | Set/cleared by the server with status. |
† notes is oriented toward stories; the API may still store text for bugs if sent.
Status & timestamps
You normally change status only; the server maintains closure fields.
New status |
Effect on resolved_at / closed_at |
|---|---|
done |
Both set to now (RFC3339). |
cancelled |
closed_at set to now; resolved_at cleared. |
open or in_progress |
If moving from a terminal state (done / cancelled), both timestamps are cleared. |
Statuses are normalized to lowercase on write. Legacy documents with other status values may still appear in lists until updated.
Project summaries (open points)
When the API aggregates open work for a project (e.g. project list), an issue counts toward open points if its status is not done or cancelled. So in_progress items are included.
Examples (JSON)
Create story (minimal)
{ "title": "OAuth login" }
Create bug (with triage)
{
"title": "Login fails on Safari",
"severity": "high",
"description": "Spinner never stops after submit.",
"steps_to_reproduce": "1. Open Safari …",
"environment": "Safari 17, macOS",
"regression": true
}
PATCH (partial)
{ "status": "in_progress", "labels": ["backend", "auth"] }
See also
- Stories and bugs (CLI commands & flags)
- MCP tools (parameter names mirror JSON keys)
- Architecture (persistence & indices) — developer-oriented detail