Getting started with the Featurebase API
Create an API key, make your first request, sync a customer, page through lists and handle errors in about five minutes.
Written By Robi Rohumaa
Last updated 19 minutes ago
This guide takes you from zero to a working integration: create an API key, make your first request, write data, page through results and handle errors. You need about five minutes and a terminal, or any language that can send HTTP requests.
1. Create an API key
Open Settings → API in your Featurebase dashboard.
Create a key and copy it. It starts with
sk_.Store it as an environment variable, for example
FEATUREBASE_API_KEY.
🔒 An API key has full access to your workspace. Keep it on your server, never in browser or mobile app code, and never commit it to git. If a key leaks, delete it in Settings → API and create a new one.
2. Make your first request
List your feedback boards. Every request sends two headers: your key as a Bearer token, and the API version you build against.
curl https://do.featurebase.app/v2/boards \
-H "Authorization: Bearer $FEATUREBASE_API_KEY" \
-H "Featurebase-Version: 2026-08-19.orbit"const res = await fetch("https://do.featurebase.app/v2/boards", {
headers: {
Authorization: `Bearer ${process.env.FEATUREBASE_API_KEY}`,
"Featurebase-Version": "2026-08-19.orbit",
},
});
if (!res.ok) throw new Error(`Featurebase API error: ${res.status}`);
const boards = await res.json();
console.log(boards.map((b) => b.name));import os
import requests
API_KEY = os.environ["FEATUREBASE_API_KEY"]
res = requests.get(
"https://do.featurebase.app/v2/boards",
headers={
"Authorization": f"Bearer {API_KEY}",
"Featurebase-Version": "2026-08-19.orbit",
},
)
res.raise_for_status()
print([board["name"] for board in res.json()])A 200 response with your boards means your key works.
3. Pin your API version
Send Featurebase-Version: 2026-08-19.orbit on every request. Without the header, your workspace's default version applies, and that default can change when someone updates it in the dashboard. A pinned version never changes under you: new fields can appear in responses, but removed or renamed fields only come in a new version that you choose to adopt.
4. Write data: sync a customer
Most integrations start by syncing customers, so feedback, votes and conversations are tied to the right person. POST /v2/contacts creates the contact or updates it if it already exists, so you can call it every time a user signs up or changes.
curl https://do.featurebase.app/v2/contacts \
-X POST \
-H "Authorization: Bearer $FEATUREBASE_API_KEY" \
-H "Featurebase-Version: 2026-08-19.orbit" \
-H "Content-Type: application/json" \
-d @contact.json
# contact.json
{
"email": "jane@acme.com",
"name": "Jane Cooper",
"userId": "user_123"
}const res = await fetch("https://do.featurebase.app/v2/contacts", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.FEATUREBASE_API_KEY}`,
"Featurebase-Version": "2026-08-19.orbit",
"Content-Type": "application/json",
},
body: JSON.stringify({
email: "jane@acme.com",
name: "Jane Cooper",
userId: "user_123", // your own user ID
}),
});
const contact = await res.json();res = requests.post(
"https://do.featurebase.app/v2/contacts",
headers={
"Authorization": f"Bearer {API_KEY}",
"Featurebase-Version": "2026-08-19.orbit",
},
json={
"email": "jane@acme.com",
"name": "Jane Cooper",
"userId": "user_123", # your own user ID
},
)
contact = res.json()Add companies to link the contact to their company, plan and revenue.
5. Page through lists
List endpoints return up to limit items (1–100, default 10) and a nextCursor. Pass that value as cursor to get the next page. When nextCursor is null, you have everything.
async function listAllPosts() {
const posts = [];
let cursor;
do {
const url = new URL("https://do.featurebase.app/v2/posts");
url.searchParams.set("limit", "100");
if (cursor) url.searchParams.set("cursor", cursor);
const res = await fetch(url, {
headers: {
Authorization: `Bearer ${process.env.FEATUREBASE_API_KEY}`,
"Featurebase-Version": "2026-08-19.orbit",
},
});
const page = await res.json();
posts.push(...page.data);
cursor = page.nextCursor;
} while (cursor);
return posts;
}6. Handle errors
Errors use standard HTTP status codes and always return the same shape:
{
"error": {
"type": "invalid_request_error",
"code": "resource_not_found",
"message": "Post not found",
"param": "id",
"status": 404
}
}💡 Only retry 429 and 5xx responses. Other 4xx errors fail the same way again until you change the request.
What you can build
The API covers most of Featurebase. Common use cases:
Support: list, create, update and reply to conversations and tickets from your own tools.
Help Center: create and update articles and collections, or sync content from another system.
Requests: create and update posts and comments, and add or remove voters from your application.
Updates and surveys: create and publish updates (changelogs in the API), and read survey responses.
Users and companies: sync contacts and companies with attributes such as plan and revenue, so you can filter and prioritize by customer.
Teammates: list admins, roles and teams.
Next steps
Collect feedback: create requests from your own forms and tools with
POST /v2/posts. See Collecting feedback through the API for the intake modes.Get notified: create a webhook to receive an HTTP callback when posts, comments, conversations and more change.
Write rich content: article and changelog bodies accept HTML or Markdown, plus Featurebase blocks such as callouts, code tabs and accordions. See the Content Components section of this reference.
Use AI agents: connect any MCP client to
https://mcp.featurebase.appto work with Featurebase in plain language.Explore every endpoint in the sidebar of this API reference.