REST API
Pad exposes a REST API at http://localhost:7777/api/v1/. All responses are JSON.
Authentication
Fresh Pad instances must be initialized with pad auth setup on the server host before normal login and registration flows are available. The bootstrap path is only intended for host-local setup.
Bootstrap First Admin
POST /api/v1/auth/bootstrap
Content-Type: application/json
{
"email": "[email protected]",
"name": "Admin User",
"password": "your-password"
} Creates the first admin account for a fresh instance. This endpoint is only available from localhost on the machine or container running the Pad server.
Session State
GET /api/v1/auth/session Returns explicit setup/auth state for the current client, including whether the instance still requires setup.
Login
POST /api/v1/auth/login Normal email/password login for initialized Pad instances.
Register
POST /api/v1/auth/register Creates a user account after setup. Registration is intended for admin-created accounts or invitation flows; it is not used to bootstrap the first admin user.
Logout
POST /api/v1/auth/logout Destroys the current session.
Current User
GET /api/v1/auth/me Returns the authenticated user’s profile (id, email, name, username, created_at, etc.).
PATCH /api/v1/auth/me
Content-Type: application/json
{ "name": "New Name", "password": "NewPassword123!" } Updates the authenticated user’s name and/or password. Accepts only name and password — admin-only fields use /admin/users/{id} instead.
Forgot Password
POST /api/v1/auth/forgot-password
Content-Type: application/json
{ "email": "[email protected]" } Triggers a password-reset email when Maileroo is configured. Always returns 200 regardless of whether the email exists (avoid account enumeration).
Reset Password
POST /api/v1/auth/reset-password
Content-Type: application/json
{ "token": "<reset-token>", "password": "NewPassword123!" } Resets the password using a token from the forgot-password email. Tokens are single-use and short-lived.
API Tokens
User-scoped tokens for CLI tools, AI agents, and CI. Bearer-style — pass as Authorization: Bearer <token>.
GET /api/v1/auth/tokens # List the caller's tokens
POST /api/v1/auth/tokens # Create a new token
DELETE /api/v1/auth/tokens/{tokenID} # Revoke a token Create body:
{
"name": "ci-bot",
"scopes": ["read"],
"expires_in_days": 90
} scopes accepts ["*"] for full access or ["read"] for read-only. Unrecognized scope strings are denied. The response body includes the raw token once — store it immediately; subsequent reads return only the prefix.
Workspaces
List Workspaces
GET /api/v1/workspaces Get Workspace
GET /api/v1/workspaces/{workspace} Workspace Members
GET /api/v1/workspaces/{workspace}/members Returns workspace members and pending invitations. Each member entry includes user_id, email, name, role (owner / editor / viewer), and timestamps.
POST /api/v1/workspaces/{workspace}/members/invite
Content-Type: application/json
{ "email": "[email protected]", "role": "editor" } Invites a user. If the user already has an account, they’re added directly. Otherwise an invitation join code is generated and (when email is configured) emailed to them.
PATCH /api/v1/workspaces/{workspace}/members/{userID}
DELETE /api/v1/workspaces/{workspace}/members/{userID}
DELETE /api/v1/workspaces/{workspace}/members/invitations/{invID} Update a member’s role, remove a member, or cancel a pending invitation.
Accept an Invitation
POST /api/v1/invitations/{code}/accept Public-ish endpoint — does not require workspace membership; the invitation code is the proof. Authenticated callers are added to the target workspace with the role embedded in the invitation.
Agent Roles
GET /api/v1/workspaces/{workspace}/agent-roles
POST /api/v1/workspaces/{workspace}/agent-roles
GET /api/v1/workspaces/{workspace}/agent-roles/{roleID}
PATCH /api/v1/workspaces/{workspace}/agent-roles/{roleID}
DELETE /api/v1/workspaces/{workspace}/agent-roles/{roleID} CRUD for the role definitions used to organize work by capability profile (Planner / Implementer / Reviewer / etc.). Items can be assigned to a (user, agent_role_id) pair.
Create body:
{
"name": "Designer",
"slug": "designer",
"description": "UX research, IA, visual design",
"icon": "🎨"
} Collections
List Collections
GET /api/v1/workspaces/{workspace}/collections Response:
[
{
"id": "uuid",
"name": "Tasks",
"slug": "tasks",
"icon": "✓",
"description": "Track work items, bugs, and to-dos",
"schema": { "fields": [...] },
"item_count": 12
}
] Create Collection
POST /api/v1/workspaces/{workspace}/collections
Content-Type: application/json
{
"name": "Bugs",
"icon": "🐛",
"schema": {
"fields": [
{ "key": "severity", "type": "select", "options": ["low", "medium", "high"] }
]
}
} Items
List Items
GET /api/v1/workspaces/{workspace}/collections/{collection}/items Query parameters:
status— filter by statuspriority— filter by priorityall— include done/archived items (true/false)
Create Item
POST /api/v1/workspaces/{workspace}/collections/{collection}/items
Content-Type: application/json
{
"title": "Fix OAuth redirect",
"fields": {
"status": "open",
"priority": "high"
},
"content": "## Description
The OAuth redirect is broken..."
} Get Item
GET /api/v1/workspaces/{workspace}/items/{slug} Update Item
PATCH /api/v1/workspaces/{workspace}/items/{slug}
Content-Type: application/json
{
"fields": {
"status": "done"
}
} Delete Item
DELETE /api/v1/workspaces/{workspace}/items/{slug} Item Children
GET /api/v1/workspaces/{workspace}/items/{slug}/children Returns child items linked to this parent (via the --parent flag at create time). Used for plan → tasks tree views and progress aggregation.
Item Progress
GET /api/v1/workspaces/{workspace}/items/{slug}/progress Returns { total, done, in_progress, percent } summarising child completion status. Powers the dashboard’s Active Plans progress bars.
Item Links
GET /api/v1/workspaces/{workspace}/items/{slug}/links
POST /api/v1/workspaces/{workspace}/items/{slug}/links
DELETE /api/v1/workspaces/{workspace}/links/{linkID} Item-to-item relationships beyond parent/child: dependencies (blocks, blocked_by) and lineage (split_from, supersedes, implements). Each link has a type, a source_id, and a target_id.
Create body:
{ "target_slug": "TASK-12", "type": "blocks" } Search
Full-Text Search
GET /api/v1/search?q=OAuth&workspace={workspace} Returns items matching the query across all collections, ranked by relevance.
Real-Time Events
SSE Stream
GET /api/v1/events?workspace={workspace} Server-Sent Events stream for real-time updates. Events are emitted when items are created, updated, or deleted.
Event format:
{
"type": "item.updated",
"workspace": "my-project",
"collection": "tasks",
"item_slug": "fix-oauth-redirect",
"timestamp": "2026-03-26T12:00:00Z"
} Dashboard
Get Dashboard
GET /api/v1/workspaces/{workspace}/dashboard Returns computed project overview including:
- summary — Total items + per-collection status breakdown
- active_items — Items currently in progress with refs, priority, status
- active_plans — Plans with progress percentages and task counts
- attention — Overdue, stalled, blocked, and orphaned items
- suggested_next — Recommended next tasks from active plans
- recent_activity — Last 10 workspace events
Activity
List Activity
GET /api/v1/workspaces/{workspace}/activity?limit=30&offset=0&action=created&source=cli Returns workspace activity entries. Supports filtering by action type and source.
Query parameters:
limit— Max entries to return (default: 30)offset— Pagination offsetaction— Filter by action:created,updated,archived,restoredsource— Filter by source:web,cli
Webhooks
List Webhooks
GET /api/v1/workspaces/{workspace}/webhooks Create Webhook
POST /api/v1/workspaces/{workspace}/webhooks {
"url": "https://example.com/webhook",
"events": "["item.created", "item.updated"]",
"secret": "optional-hmac-secret"
} Events: item.created, item.updated, item.deleted, item.moved, comment.created, or * for all.
When a secret is provided, each delivery includes an X-Pad-Signature header with an HMAC-SHA256 signature of the payload.
Webhooks are automatically deactivated after 10 consecutive delivery failures.
Delete Webhook
DELETE /api/v1/workspaces/{workspace}/webhooks/{id} Test Webhook
POST /api/v1/workspaces/{workspace}/webhooks/{id}/test Sends a test payload to verify the webhook is receiving events correctly.
Admin
Endpoints below require an admin account. They control platform-level settings, user lifecycle, and operational tooling.
Platform Settings
GET /api/v1/admin/settings
PATCH /api/v1/admin/settings Fetch or update server-wide settings stored in the platform_settings table. Used for plan limits, feature flags, and email templates that need to be tunable without a redeploy.
Test Email
POST /api/v1/admin/test-email
Content-Type: application/json
{ "to": "[email protected]" } Sends a one-off test email through the configured Maileroo provider. Useful for verifying SMTP/API configuration after rotating keys.
User Administration
GET /api/v1/admin/users # List users
GET /api/v1/admin/users/{userID} # User detail
PATCH /api/v1/admin/users/{userID} # Update profile / role / status
POST /api/v1/admin/users/{userID}/reset-password # Generate password-reset link
GET /api/v1/admin/users/{userID}/workspaces # User's workspace memberships
POST /api/v1/admin/users/{userID}/disable # Suspend the account
POST /api/v1/admin/users/{userID}/enable # Re-enable a suspended account Invitations Administration
GET /api/v1/admin/invitations # All pending invitations
POST /api/v1/admin/invitations/{invID}/resend # Re-send the invitation email
DELETE /api/v1/admin/invitations/{invID} # Cancel an invitation Plan Limits
GET /api/v1/admin/limits
PATCH /api/v1/admin/limits Read or update the plan-limit table (workspaces, items_per_workspace, members_per_workspace, api_tokens, storage_bytes, webhooks, automated_backups — per plan tier). DB-stored, idempotent on restart, so admin tweaks survive deploys.
Stats
GET /api/v1/admin/stats Returns aggregate counts (active users, total items, signups in the last 30 days, plan distribution).