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; filters status, columnId, q
  • POST /tickets — create; subject, body, contactEmail, contactName, optional priority, tags, columnId
  • GET /tickets/:id — ticket plus full message thread
  • PATCH /tickets/:idstatus, priority, columnId, tags, assigneeId (null unassigns)
  • POST /tickets/:id/replybody; returns mode: "pending_approval" while the reply gate is on

Board

  • GET /board — columns in order with tickets by position

Feedback

  • GET /feedback — list; filters status, boardId
  • POST /feedback — create; title, body, optional boardId, authorEmail, authorName, tags
  • PATCH /feedback/:idstatus; setting shipped notifies voters and drafts a help article

Help center

  • GET /articles — list; filter status
  • POST /articles — create a draft-status article
  • POST /articles/:id/publish — publish; 403 until agentCanPublish is on
  • GET /drafts — pending article drafts
  • POST /drafts — file a draft for human review
  • POST /drafts/:id/approve — approve and publish; 403 until agentCanPublish is on
  • POST /drafts/:id/dismiss — dismiss a draft

Changelog

  • GET /changelog — list entries; filter status
  • POST /changelog — draft an entry; title, body, optional tags
  • POST /changelog/:id/send — publish and queue subscriber emails; 403 until agentCanPublish is 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 type
  • x-superboard-timestamp — unix ms, included in the signature
  • x-superboard-signaturesha256= + HMAC-SHA256 of timestamp.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.