API, Webhooks & MCP
Drive your workspace from code — REST API, outbound webhooks, OpenAPI skill imports, and Model Context Protocol access
Saltare exposes a full programmatic surface for teams who want to automate, integrate, or drive their workspace from external systems. Everything the web app does — creating tasks, posting messages, editing documents, running agents — is available over HTTPS behind a bearer-token auth chain.
Four entry points, all sharing the same auth model:
| Surface | Endpoint | Use it for |
|---|---|---|
| REST API | /api/v1/* |
CRUD on tasks, messages, channels, documents, agents, uploads, databases, rows |
| MCP | POST /mcp |
Plug MCP-aware hosts (Claude Desktop, Cursor, custom agents) directly into a workspace |
| Outbound webhooks | Your URL | Receive signed HMAC-SHA256 event deliveries when things happen in Saltare |
| OpenAPI skill imports | Settings → Skills | Turn any OpenAPI 3.x spec into dynamic tools your agents can call |
The developer reference at /docs has payload shapes, example requests, and error codes. This page covers the workflow.
API Keys
Every programmatic call authenticates with a workspace-scoped bearer token. Mint one under Settings → API Keys (workspace admins only).
Each key has:
- Scopes — restrict what the key can touch. Grants are resource-scoped:
tasks:read,tasks:write,messages:read,messages:write,documents:*,mcp:tools:read, and so on. Use*for full access, or compose narrow sets for specific integrations. - IP allowlist (optional) — limit use to known egress IPs. Leave blank for any origin.
- Expiry (optional) — keys with an expiry auto-revoke on the given date.
Tokens are prefixed sk_sal_ and shown exactly once at creation. Saltare stores a SHA256 digest at rest and keeps only the last four characters for display; if you lose the token you mint a new one.
Pass it on every request:
Authorization: Bearer sk_sal_...
All API traffic is rate-limited at 600 requests/minute per key (tasks#create has an additional 50/min cap). The limit is keyed by the key itself, so sharing a key across a NAT won't throttle your whole team.
REST API
The REST surface lives at /api/v1 and returns JSON. It covers:
auth#me— confirm the token's identity and workspacetasks— list, get, create, update, completemessages— read threads, post replies, mention agentschannels— browse the workspace's chat treedocuments— CRUD on markdown documents with version historyagents— list agents, enqueuePOST /:slug/messageto trigger an agent response jobuploads— multipart file upload, retrieve, listdatabases/rows— manage structured tables
Responses include pagination headers (X-Total-Count, X-Page, X-Per-Page, X-Total-Pages) on index endpoints. Errors come back as { error: { code:, message: } }.
The full OpenAPI 3.1 spec is served at GET /api/v1/openapi.json — drop it into Postman, Insomnia, or your OpenAPI client of choice.
MCP Server
The Model Context Protocol endpoint at POST /mcp lets external LLM hosts drive your workspace as if they were Saltare's own agents. The same 67 built-in tools are exposed, gated by MCP-specific scopes:
mcp:tools:read— list and describe toolsmcp:tools:write— call tools that modify statemcp:tools:destructive— call tools that delete thingsmcp:resources:read— read workspace resources (documents, tasks, uploads)
Point Claude Desktop, Cursor, or any MCP client at https://your-workspace.saltare.ai/mcp with a bearer token that carries the scopes you want. The full transport spec is at /docs/mcp.
Outbound Webhooks
When you need Saltare to push events into your own systems — Zapier, n8n, an internal audit pipeline, a custom bot — create an outbound webhook under Settings → Webhooks.
Each subscription has:
- Target URL — must be publicly reachable and HTTPS. Private/loopback/cloud-metadata IPs are blocked at save time.
- Shared secret — used to sign deliveries with HMAC-SHA256.
- Event types — subscribe to any of:
task.created,task.completed,message.posted,document.published,webhook.test.
Every delivery carries two headers:
X-Saltare-Signature: sha256=<hex>
X-Saltare-Timestamp: <unix seconds>
Verify on your end by re-signing timestamp.body with the shared secret. Deliveries that fail auto-retry with backoff, and a subscription that racks up 20 consecutive failures auto-pauses until you re-enable it. Every attempt is audit-logged so you can diff what Saltare sent against what your endpoint received.
The "Send test" button on each subscription fires a webhook.test payload — great for wiring up your receiver before real events start flowing.
OpenAPI Skill Imports
If the API you care about publishes an OpenAPI 3.x spec, you don't need to write a connector at all. Go to Settings → Skills → Import OpenAPI, paste JSON or YAML, and Saltare:
- Validates the base URL through the same SSRF filter agents use for
fetch_url. - Normalizes operations into a cached list on the skill (capped at 100 per spec).
- Creates one dynamic tool per operation, named
openapi__<skill-slug>__<operation-id>.
Attach the skill to an agent and it can now call those operations with structured path, query, and body parameters — auth resolves against the linked connector (Bearer, Basic, or API key header). Timeouts are tight (5s open, 15s read) and response bodies are capped at 8 KB.
Out of scope for v1: OAuth2 flows, multipart uploads, file uploads, and deep $ref chains. If your spec needs any of those, a hand-rolled connector is still the right call.
Tips
- Start with narrow scopes. Mint a separate key per integration. Revoking one shouldn't break the others.
- Set IP allowlists on server-side keys. Desktop/mobile clients can omit them, but server-side callers should lock down the origin.
- Use the OpenAPI spec for client generation.
GET /api/v1/openapi.jsonis the source of truth — don't hand-transcribe endpoints. - Verify webhook signatures. The signing window is five minutes; requests with a stale or missing timestamp should be rejected on your end.
- Prefer OpenAPI imports over custom tool code. If the remote service has a spec, let Saltare do the wrapping.
- Watch the rate limit headers. 600/min is generous for interactive use but can bite batch jobs — queue writes if you're bulk-syncing.