REST API · For developers

featury over plain HTTP

Everything featury exposes to agents is also a versioned REST API: discover workspaces and projects, read the feature inventory and the complete change feed, file and groom requests, and ask the codebase agent: one personal API key, a Bearer header, JSON back.

1. Create an API key

In the app, go to Account → API keys → Create API key. The full key is shown only once. Store it somewhere safe. Only its hash is kept server-side, so it can't be recovered later.

A key acts as you: the agent works with your identity and your exact permissions in every workspace you belong to, no more, no less. Revoke a key from the same page the moment it leaks.

Open Account settings

2. Conventions

All URLs are relative to your API origin (self-hosted? use your own):

https://api.featury.app

Responses always come in an envelope: { "data": … } on success, { "error": { "code", "message" } } on failure. Status codes are plain: 400 for a malformed call, 401 for a missing or revoked key, 403 when your role can't reach the resource, 404 when it doesn't exist.

Every workspace and project parameter accepts the slug or the id: the same slugs you see in the app's URLs. And a key acts as its owner: each endpoint sees exactly what you can see in the app, no more.

Optional attribution: send an X-Featury-Agent header (or bind an agent to the key when you mint it) and everything the key does shows as “{agent} · via you” instead of just you. Without it, featury still picks up the client's own name when it can.

3. Changes

The complete internal feed of classified changes: every item carries visibility: PUBLIC | INTERNAL, including the internal entries that never reach the curated public changelog at /feed/{workspace}/{project}.json. Defaults to 50 items, max 200.

EndpointWhat it does
GET /v1/changesClassified changes, newest first. Filter by kind, impactSurface, from/to date; paginate with limit/offset
curl -H "Authorization: Bearer fk_…" \
  "https://api.featury.app/v1/changes?workspace=acme&project=web&limit=50"

4. Requests

Bugs and feature asks, end to end. Without a status filter, the list returns only the live lanes; repeat the parameter to filter by several. BUILDING and SHIPPED stay derived from real code signals. You can't set them by hand, same rule as in the app.

EndpointWhat it does
GET /v1/requestsList requests. Filters: status, size, impact (each repeatable), kind, horizon, search; paginate with limit/offset. Compact rows carry updatedAt, shippedAt and area
GET /v1/requests/:idFull request detail: journey, comments, spec artifacts, reality read
POST /v1/requestsFile a request ({ workspace, project, kind, title, body?, severity? }). Goes through the standard triage
PATCH /v1/requests/:idGroom a request: title, body, severity, and horizon/size/fit overrides
POST /v1/requests/:id/statusMove a request through the manual lanes. { status, note?, declinedReason? }
POST /v1/requests/:id/commentsComment on a request ({ body }). Notifies participants; @Name mentions ping
curl -X POST "https://api.featury.app/v1/requests" \
  -H "Authorization: Bearer fk_…" \
  -H "Content-Type: application/json" \
  -d '{"workspace":"acme","project":"web","kind":"BUG","title":"Export button returns 500"}'

5. Features & discovery

Start here: list your workspaces, then the projects inside one, then the living feature inventory of a project.

EndpointWhat it does
GET /v1/workspacesThe workspaces you belong to: id, name, slug, your role
GET /v1/projectsThe projects you can access in a workspace
GET /v1/featuresThe project's living feature inventory
curl -H "Authorization: Bearer fk_…" \
  "https://api.featury.app/v1/features?workspace=acme&project=web"

6. Ask the codebase

One question in, a grounded answer out. Non-streaming, so expect a long call. Pass the returned conversationId back to continue the thread. Spends the workspace AI budget, like a chat message in the app.

EndpointWhat it does
POST /v1/askAsk the codebase agent: { question, conversationId? } → { data: { answer, conversationId, sources } }. `sources` names the repo docs and features the turn actually read.
curl -X POST "https://api.featury.app/v1/ask" \
  -H "Authorization: Bearer fk_…" \
  -H "Content-Type: application/json" \
  -d '{"workspace":"acme","project":"web","question":"How does billing retry failed payments?"}'

7. Public changelog (no key needed)

Every product's published changelog is served logged-out, in four formats, from a stable address, and it answers any origin, so your own site can fetch the JSON and build a page from it. This is the call behind featury.app/changelog.

EndpointWhat it does
GET /feed/{ws}/{proj}.{html|json|md|xml}The index. Newest first, 20 editions to a page
GET /feed/{ws}/{proj}.{ext}?before={n}Older pages; the JSON's next carries the link
GET /feed/{ws}/{proj}/{n}.{html|json|md}One edition's permanent address
GET /feed/{ws}/{proj}/og.png · /{n}/og.pngShare cards: the feed's, and one edition's
curl https://api.featury.app/feed/featury/featury.json

See it live: featury's own changelog →

8. Good to know

  • BUILDING and SHIPPED are derived from real code signals and can never be set by hand. Same rule as in the app.
  • Cite a request's refCode in a commit or PR message ("Closes idea/dark-mode", "Fixes bug/login-white-screen") and the ticket auto-ships and notifies its requester.
  • Mutations behave exactly like the in-app actions (journey events, notifications) and are attributed to you.
  • Want your coding agent to use all of this without writing code? That's the MCP endpoint. Same keys, same capabilities, tool-shaped. MCP docs →