Developer docs
Superboard API
Everything your team clicks, your agent can call. One API key unlocks the REST API, the MCP server, and outbound webhooks.
Approval gates are on by default: agent replies wait for a human send, and help-article publishing and changelog sends wait for a human approve. Turn either off in Settings.
Authentication
Create a key in Settings → API keys. Send it as a bearer token:
curl https://superboard.dev/api/v1/tickets?status=new \
-H "Authorization: Bearer sb_live_..."
The full key is shown once. We store only its sha256 hash. Revoking a key stops its requests immediately.
Connect an agent (MCP)
The MCP server exposes the same surface as tools with agent-friendly
descriptions — streamable HTTP at /api/mcp:
claude mcp add superboard --url https://superboard.dev/api/mcp \
--header "Authorization: Bearer sb_live_..."
16 tools: get_board_overview, list_tickets, get_ticket,
update_ticket, move_ticket, reply_to_ticket, list_feedback,
create_feedback_post, set_feedback_status, list_articles,
draft_article, list_drafts, approve_draft, list_changelog,
draft_changelog_entry, and send_changelog_entry.
REST endpoints
Base URL: https://superboard.dev/api/v1. JSON in, JSON out. POST
returns the full created object. Errors come back as
{ "error": "code", "message": "what happened" } with the matching HTTP
status.
Tickets
GET /tickets— list; filtersstatus,columnId,qPOST /tickets— create;subject,body,contactEmail,contactName, optionalpriority,tags,columnIdGET /tickets/:id— ticket plus full message threadPATCH /tickets/:id—status,priority,columnId,tags,assigneeId(null unassigns)POST /tickets/:id/reply—body; returnsmode: "pending_approval"while the reply gate is on
Board
GET /board— columns in order with tickets by position
Feedback
GET /feedback— list; filtersstatus,boardIdPOST /feedback— create;title,body, optionalboardId,authorEmail,authorName,tagsPATCH /feedback/:id—status; settingshippednotifies voters and drafts a help article
Help center
GET /articles— list; filterstatusPOST /articles— create a draft-status articlePOST /articles/:id/publish— publish; 403 untilagentCanPublishis onGET /drafts— pending article draftsPOST /drafts— file a draft for human reviewPOST /drafts/:id/approve— approve and publish; 403 untilagentCanPublishis onPOST /drafts/:id/dismiss— dismiss a draft
Changelog
GET /changelog— list entries; filterstatusPOST /changelog— draft an entry;title,body, optionaltagsPOST /changelog/:id/send— publish and queue subscriber emails; 403 untilagentCanPublishis on
Webhooks
Add endpoints in Settings → Webhooks. We POST JSON on:
ticket.created, ticket.updated, feedback.created,
feedback.shipped, article.published, changelog.published.
Delivery is fire-and-forget with one retry after 1s.
Each delivery is signed with your endpoint secret (shown once when you add the endpoint):
x-superboard-event— the event typex-superboard-timestamp— unix ms, included in the signaturex-superboard-signature—sha256=+ HMAC-SHA256 oftimestamp.body
Verify in Node:
import crypto from 'node:crypto'
function verifySuperboardWebhook(headers, rawBody, secret) {
const timestamp = headers['x-superboard-timestamp']
const expected =
'sha256=' +
crypto
.createHmac('sha256', secret)
.update(timestamp + '.' + rawBody)
.digest('hex')
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(headers['x-superboard-signature'] ?? ''),
)
}
Reject anything older than 5 minutes to stop replays.