Docs

FeatQ REST API: read, create and update requests

The FeatQ REST API has four endpoints: check your key, list requests, create a request and change a request's status. Every call uses your board key and returns JSON, with a limit of 120 calls per minute per board. Use it from your own scripts or from automation tools that can send HTTP requests.

How do I authenticate?

Send your board key as a bearer token: Authorization: Bearer fq_.... It is the same key the MCP server uses. Find it in your board admin, in the Connect your coding agent panel. Each key belongs to one board, and every call works on that board only.

A new key breaks connected integrations. Removing a teammate from the board creates a new key, because teammates could read the old one. Regenerating the key in your board admin (owner only) does the same. After either, paste the new key into every script or tool that uses the old one.

What are the endpoints?

The base URL is https://featq.com/api/v1.

GET /api/v1/me

Returns the board the key belongs to: board_id, board_name, board_slug and board_url. Use it to test a key.

curl -fsS \
  -H "Authorization: Bearer $FEATQ_KEY" \
  "https://featq.com/api/v1/me"

GET /api/v1/requests

Returns { "requests": [...] }. Merged requests are left out. Query parameters:

  • sort=newest (default): newest requests first.
  • sort=status_changed: only requests whose status has changed, latest change first. Each item also has change_id, the request ID and status_changed_at joined by a colon. It is unique per status change, so you can use it to skip changes you have already seen.
  • status: only requests with this status.
  • limit: 1 to 100, default 25.
curl -fsS \
  -H "Authorization: Bearer $FEATQ_KEY" \
  "https://featq.com/api/v1/requests?sort=status_changed&status=done&limit=25"

POST /api/v1/requests

Creates a request from a JSON body with title (required, up to 200 characters) and description (optional, up to 5,000 characters). It is posted under the board owner with one vote, like a request you add yourself, and sends the same Slack or Discord alert as a request posted on the board. Returns the new request with status 201. Each board can create up to 60 requests per hour this way.

curl -fsS -X POST \
  -H "Authorization: Bearer $FEATQ_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title": "Dark mode", "description": "For the dashboard"}' \
  "https://featq.com/api/v1/requests"

PATCH /api/v1/requests/{id}

Changes the status from a JSON body with status, one of new, considering, planned, in_progress or done. It works exactly like a change from your board admin: any status change emails the voters who asked to hear about status changes, and your board's Slack or Discord alert fires. Setting the status it already has does nothing. Returns the updated request.

curl -fsS -X PATCH \
  -H "Authorization: Bearer $FEATQ_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status": "planned"}' \
  "https://featq.com/api/v1/requests/REQUEST_ID"

What does a request look like?

Every endpoint that returns a request uses this object. Times are ISO 8601 in UTC.

{
  "id": "V1StGXR8_Z5jdHi6B-myT",
  "title": "Dark mode",
  "description": "For the dashboard",
  "status": "planned",
  "votes": 12,
  "url": "https://featq.com/b/your-board",
  "created_at": "2026-11-02T09:15:00.000Z",
  "updated_at": "2026-11-02T10:01:12.000Z",
  "status_changed_at": "2026-11-02T10:01:12.345Z"
}
FieldMeaning
idThe request ID. Use it in PATCH /api/v1/requests/{id}.
titleUp to 200 characters.
descriptionUp to 5,000 characters, or null.
statusOne of new, considering, planned, in_progress, done. done shows as Shipped on the board.
votesVote count, including vote counts brought in by an import.
urlThe public board page, on your custom domain when one is active.
created_atWhen the request was posted.
updated_atWhen the request last changed.
status_changed_atWhen the status last changed, or null if it has not changed since this field was added.

What errors can it return?

Errors are JSON with one field: { "error": "..." }.

StatusWhen
400Bad input: a body that is not valid JSON or not a JSON object, a missing title, a title or description that is too long, an unknown status or sort.
401The Authorization header is missing or the key is wrong.
403The board is inactive (billing ended), or the key is a read-only sandbox key.
404No request with that ID on this board.
429More than 120 calls in a minute, or more than 60 new requests in an hour. Wait the number of seconds in the Retry-After header.

What is the rate limit?

120 calls per minute per board, counted across all four endpoints. Past that, calls get 429 with a Retry-After header in seconds. On top of that, POST /api/v1/requests creates at most 60 requests per hour per board, so a looping automation cannot flood your Slack or Discord channel. Calls with a missing or wrong key are limited per IP address. The older top-requests and top-spec endpoints keep their own limits.

What can the API not do yet?

  • No votes, comments or delete endpoints. Use your board admin for those.
  • No webhooks to your own URL (board alerts go to Slack or Discord only). Poll GET /api/v1/requests for new requests and status changes.
  • POST takes no submitter email: every API request is posted under the board owner.
  • Keys from the sandbox are read-only: GET works, POST and PATCH return 403.

Checked against the API code on November 2, 2026 by the FeatQ team. More guides in the FeatQ docs.