API Reference
Integrate with fdback.io using the REST API
The fdback.io REST API gives you programmatic access to feedback posts, comments, votes, changelogs, and more.
Base URL:
https://app.fdback.io/api/v1Authentication
All requests require a Bearer token in the Authorization header. Create API keys from Settings > API Keys in your workspace.
curl https://app.fdback.io/api/v1/posts \
-H "Authorization: Bearer sk_live_your_api_key"Key Prefixes
| Prefix | Mode | Behavior |
|---|---|---|
sk_live_ | Live | Reads and writes real data |
sk_test_ | Test | Write operations return mock data without persisting |
Rate Limiting
Requests are rate limited per API key:
- Read (GET): 200 requests per minute
- Write (POST, PATCH, DELETE): 60 requests per minute
Rate limit information is returned in response headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests per window |
X-RateLimit-Remaining | Requests remaining |
X-RateLimit-Reset | Unix timestamp when the window resets |
When rate limited, you'll receive a 429 status with a Retry-After header.
Response Format
All responses follow a consistent envelope:
Success:
{
"data": { ... }
}Error:
{
"error": {
"code": "NOT_FOUND",
"message": "Post not found.",
"status": 404
}
}Every response includes an X-Request-Id header for debugging.
Test Mode
API keys prefixed with sk_test_ enable test mode. Write operations (POST, PATCH, DELETE) return realistic mock responses with "test": true without modifying any data. Read operations work normally against real data.
{
"data": { "id": "post-1", "title": "Test Post", ... },
"test": true
}Authorization & Ownership
API keys authenticate your application, not individual end users. The key holder has full read/write access to the workspace and is responsible for enforcing user-level permissions on their side.
Example: letting a user delete their own post
- Your backend knows who is logged in (your own auth).
- Fetch the post via
GET /posts/{id}and check the author email. - If it matches the logged-in user, call
DELETE /posts/{id}. - If not, return 403 to your user.
// 1. Get the post
const post = await fetch(`https://app.fdback.io/api/v1/posts/${postId}`, {
headers: { Authorization: `Bearer ${API_KEY}` },
}).then(r => r.json());
// 2. Check ownership
if (post.data.author?.email !== loggedInUser.email) {
return res.status(403).json({ error: "Not your post" });
}
// 3. Delete it
await fetch(`https://app.fdback.io/api/v1/posts/${postId}`, {
method: "DELETE",
headers: { Authorization: `Bearer ${API_KEY}` },
});Never expose your API key to client-side code. All API calls should go through your backend.
Query Parameters
GET endpoints accept three structured query parameter categories alongside standard pagination.
include
Opt-in to related resources using semicolon-separated values. By default, responses only contain core fields to keep payloads lean.
Prop
Type
GET /posts?include=attachments
GET /posts/abc123?include=attachments;comments.repliesUnknown include values are silently ignored — your integration won't break if we add new values later.
filters
Filter results using semicolon-separated key:value pairs.
Prop
Type
GET /posts?filters=typeId:abc123
GET /posts?filters=typeId:abc;statusId:def;search:dark modeValues can contain colons — only the first : is treated as the key/value separator (e.g. search:error:timeout searches for "error:timeout").
sortBy
Sort order for list endpoints. Passed as a standalone query parameter.
Prop
Type
Pagination
Prop
Type
Full example
GET /posts?filters=typeId:abc;search:bug&sortBy=votes&limit=10&include=attachmentsFile Uploads
The POST /posts and PATCH /posts/{id} endpoints support file attachments via multipart/form-data:
Prop
Type
Allowed types: image/*, video/*, application/pdf