Typed TypeScript SDK
First-class `@planoda/sdk` ships with full request/response types, runtime Zod validators, automatic retries with exponential backoff, idempotency-key support, and edge/node/bun adapters. `npm i @planoda/sdk` and your IDE knows every endpoint, every field, every enum.
const { issue } = await planoda.issues.create({
workspace: 'acme',
title: 'Auth fails on Safari 17',
priority: 2,
});
OAuth 2.0 + PKCE
Public + confidential clients, refresh-token rotation, granular scopes (`issues:read`, `boards:write`, `webhooks:manage`, …), per-workspace consent screens, and revocable installation tokens. Built on the same Clerk-backed identity layer that protects the product UI.
GET /oauth/authorize?
client_id=…&
scope=issues:read+boards:write&
code_challenge_method=S256
Signed webhooks
30+ event types across issues, comments, automations, releases, and inbox. Every payload is HMAC-SHA-256 signed, idempotency-keyed, and delivered with exponential backoff up to 24 hours. Replay any delivery from the dashboard, inspect the raw body, and rotate signing secrets without dropping a packet.
X-Planoda-Signature: t=1716700000,v1=4f…
// Verify with `verifyWebhook(req, secret)`
MCP server
Native Model Context Protocol endpoint so Claude, Cursor, Zed, and Continue can read your workspace through a single OAuth-scoped tool surface. Resources for issues / boards / projects, tools for `create-issue`, `triage`, `search`, and prompts pinned to your team's conventions.
{
"mcpServers": {
"planoda": { "url": "https://planoda.com/api/mcp/streamable-http" }
}
}
Plugin runtime
Ship UI extensions that mount inside the issue panel, the board sidebar, or the command palette — sandboxed in a Web Worker, capability-scoped to the workspace, and reviewed before listing. Plugins use the same tRPC API the product uses; there is no second-class surface.
export default definePlugin({
slot: 'issue.panel',
render: ({ issue }) => <FigmaPreview url={issue.figma} />,
});
Rotateable signing keys
Every integration owns a key pair. Rotate on demand with overlapping windows — old + new keys both validate for 24 hours so you never break a downstream consumer. Audit log records who rotated, when, and the previous key's last successful verify timestamp.
planoda keys rotate --integration=slack --overlap=24h