Integrator API
The Integrator API enables B2B partners to resell Snipara to their clients with isolated workspaces, dedicated API keys, configurable resource limits, and project-context health signals for client documentation workflows.
Helvabase is the reference business frontend on this layer. Direct Snipara customers see the developer-focused dashboard; integrators use this API to package project context into managed client bundles.
Partner Program Only
The Integrator API is available to approved partners. Apply to the Partner Program to get started.
Overview
The Integrator system has a hierarchical structure:
Authentication
Snipara exposes three public integrator-facing surfaces. Choose the one that matches your use case instead of mixing session routes, workspace API keys, and MCP API keys.
curl -H "Authorization: Bearer YOUR_SESSION_TOKEN" https://www.snipara.com/api/integrator/...For server-to-server partner management, create a workspace API key in the dashboard and send it as X-API-Key to /api/v1/partners. For MCP backend access on api.snipara.com, use a client API key (snp-client-*) for the client project, or a regular Snipara key for your own project/team access.
Base URLs
| Service | Base URL | Use Case |
|---|---|---|
| Dashboard | https://www.snipara.com/api/integrator | Dashboard operations (requires session) |
| Partner REST API | https://www.snipara.com/api/v1/partners | Server-to-server client and key management (requires workspace API key) |
| MCP Server | https://api.snipara.com/mcp/{project_slug} | Client project MCP access with snp-client-* keys or regular Snipara keys |
Helvabase-Style Partner Context Model
Integrators should treat Snipara as the optimized context layer, not as the system of record for Google Drive, Microsoft 365, Gmail, Teams, or local file shares. Your product, agent, or MCP wrapper fetches files from the source system, extracts or normalizes the content, and sends it to Snipara with source metadata.
This keeps OAuth consent, ACL handling, sync policy, and source-specific retries under your control while still giving the LLM searchable context across current client work, reusable templates, and approved historical examples.
Direct Snipara now exposes a simpler developer dashboard: Code Context holds engineering defaults, and Projects hold source-scoped work. Integrators can mirror the richer Helvabase-style model in their own UI or wrap it in their own MCP layer.
The hosted MCP surface exposes the same split with snipara_list_business_collections, snipara_ensure_business_collection, snipara_upload_business_document, snipara_list_client_projects, and snipara_create_client_project. Use these for structure; use snipara_upload_document or snipara_sync_documents for actual client files that need metadata, freshness, and health signals.
| Client Project Mode | Stored Lifecycle | Integrator Behavior |
|---|---|---|
active_client | ACTIVE_CLIENT | Use for living client truth. Business health can request reupload, reindex, metadata review, or quality review. |
reference_archive | REFERENCE_ARCHIVE | Use for past-client precedent. Search remains available, but stale source snapshots do not create reupload pressure. |
Packaging rule
For direct Snipara customers, business workflows are handled by Helvabase. For partners, the same backend capabilities are included inside each client bundle; the integrator tier controls the client limit and the discount on those bundle charges.
| Context Type | Metadata | How the LLM Should Use It |
|---|---|---|
| Current Sources | usageMode: "current_truth" | Authoritative for the current client or project. |
| Partner Library reference | usageMode: "historical_reference" | Reusable precedent, never active truth unless the user explicitly promotes it. |
| Partner Library template | usageMode: "template" | Starting structure for new proposals, diagrams, runbooks, or deliverables. |
| Partner Library knowledge | usageMode: "global_knowledge" | Shared policies, offers, product catalog, standards, and terminology. |
Source Metadata for Uploads and Sync
Attach metadata to each document when calling snipara_sync_documents, file upload endpoints, or your own MCP wrapper. For current files, include the upstream modified time, snapshot time, and content hash so Snipara can detect stale project context without owning the original connector.
await callSniparaTool("snipara_sync_documents", { documents: [ { path: "clients/xyz/current/discovery-notes.md", content: "...", kind: "DOC", format: "md", metadata: { assetClass: "BUSINESS_DOCUMENT", usageMode: "current_truth", clientId: "xyz", sourceKind: "google_drive", sourceUri: "gdrive://file/1Abc...", sourceModifiedAt: "2026-04-24T09:20:00Z", sourceSnapshotAt: "2026-04-25T12:00:00Z", sourceContentHash: "sha256:..." } }, { path: "references/acme/network-diagram.vsdx", content: "base64:<payload>", kind: "BINARY", format: "vsdx", metadata: { assetClass: "DIAGRAM", usageMode: "historical_reference", clientId: "acme", sourceKind: "upload", sourceSnapshotAt: "2026-02-12T10:00:00Z", referenceProvenance: { sourceClientId: "acme", sourceProjectId: "acme-network-redesign", approvalStatus: "approved_reference" } } } ], reindex: true});For bulk provider-neutral uploads, supported text formats are .md, .markdown, .mdx, .txt, .rst, and .adoc. Supported binary parser formats are .pdf, .docx, .pptx, .svg, and .vsdx; send them as base64:<payload> with kind="BINARY" and the matching format.
With snipara-companion, partners can validate the same manifest locally before upload:
snipara-companion sync-documents --file ./helvabase-context.json --dry-run --jsonsnipara-companion sync-documents --file ./helvabase-context.json --reindexThe dry-run validates payload shape, known metadata fields, and local freshness signals without calling hosted MCP. Remote created, updated, and unchanged counts are only known after a real sync.
Health and Reupload Signals
Use snipara_index_health or the dashboard index health API to know when project context is stale, missing provenance, or ready for reindexing. These signals are designed for partner-owned connectors: when Snipara reports reupload, fetch the latest source file from Drive, SharePoint, Teams, Gmail, or your own storage, then sync the updated content back to the client project.
snipara-companion business-health --json{ "business_context": { "tracked_documents": 42, "needs_reupload": 3, "needs_reindex": 1, "needs_metadata_review": 2, "signals": [ { "action": "reupload", "reason": "source_modified_after_upload" }, { "action": "review_source_metadata", "reason": "missing_reference_provenance" } ] }}Reference-Based Client Delivery
A common partner workflow is: "Use the approved ACME network diagram as a reference for new client XYZ, but adapt it to the requirements in XYZ document ABC." In that case, keep ACME files as historical_reference, keep XYZ files as current_truth, and make the prompt tell the LLM which context is precedent and which context is authoritative.
Integrator Tiers
| Tier | Price | Client Limit | Client Bundle Discount |
|---|---|---|---|
| STARTER | $199/mo | 100 clients | 20% |
| GROWTH | $499/mo | 500 clients | 25% |
| SCALE | $999/mo | 2,000 clients | 30% |
| ENTERPRISE | Custom | Unlimited | 30-50% negotiated |
The discount applies only to the client bundle charges below. It does not discount the integrator tier subscription itself.
Client Bundles
Each client is assigned a bundle that determines their resource limits. All bundles can use the Partner Library, Current Sources, Diagrams, and context-health model; the bundle controls scale through query, memory, document, and storage limits.
| Bundle | Price | Queries/mo | Memories | Swarms | Agents/Swarm | Documents | Storage |
|---|---|---|---|---|---|---|---|
LITE | $19/mo | 1,000 | 250 | 2 | 5 | 100 | 250 MB |
STANDARD | $49/mo | 10,000 | 1,500 | 10 | 10 | 500 | 3 GB |
UNLIMITED | $99/mo | Unlimited | Unlimited | Unlimited | 25 | Unlimited | 25 GB |
Client Bundle Discount Examples
| Tier | LITE | STANDARD | UNLIMITED |
|---|---|---|---|
| STARTER (20%) | $15.20/mo | $39.20/mo | $79.20/mo |
| GROWTH (25%) | $14.25/mo | $36.75/mo | $74.25/mo |
| SCALE (30%) | $13.30/mo | $34.30/mo | $69.30/mo |
| ENTERPRISE | Custom discount, typically 30-50% | ||
Workspace API
Get Workspace
GET /api/integrator/workspaceReturns your workspace details, including client count and limits.
Response
{ "success": true, "data": { "id": "ws_abc123", "name": "Acme Workspace", "slug": "acme", "webhookUrl": "https://acme.com/webhooks/snipara", "hasWebhookSecret": true, "clientCount": 5, "clientLimit": 100, "tier": "STARTER", "pricing": { "clientBundleDiscountPercent": 20, "discountAppliesTo": "client_bundles" } }}Create Workspace
POST /api/integrator/workspace{ "name": "Acme Workspace", "slug": "acme" // lowercase, alphanumeric + hyphens only}Update Workspace
PATCH /api/integrator/workspace{ "name": "New Name", // optional "webhookUrl": "https://...", // optional "webhookSecret": "your-secret" // optional}Integrator Status
GET /api/integrator/statusUse this lightweight dashboard route to confirm whether the current session belongs to an approved integrator and whether a workspace already exists.
Workspace API Keys
Workspace API keys use the snp-int- prefix and are meant for server-to-server partner operations on /api/v1/partners. They are distinct from client keys (snp-client-) and team API keys.
| Route | Purpose |
|---|---|
GET /api/integrator/workspace/api-keys | List active workspace API keys |
POST /api/integrator/workspace/api-keys | Create a new workspace API key with scopes and optional expiration |
DELETE /api/integrator/workspace/api-keys/:keyId | Revoke a workspace API key |
{ "name": "Production Partner API", "scopes": ["clients:read", "clients:write", "keys:read", "keys:write"], "expiresAt": "2027-01-01T00:00:00Z" // optional}Partner REST API
Once you have a workspace API key, use the partner REST surface for automation and backend integrations. This surface mirrors the client-management model without requiring a browser session.
| Route | Auth | Purpose |
|---|---|---|
GET /api/v1/partners/info | X-API-Key: snp-int-... | Workspace metadata, tier, remaining client capacity, pricing, and key scopes |
GET /api/v1/partners/clients | X-API-Key: snp-int-... | List clients programmatically |
POST /api/v1/partners/clients | X-API-Key: snp-int-... | Create a client and provision its workspace project |
GET/PATCH/DELETE /api/v1/partners/clients/:clientId | X-API-Key: snp-int-... | Inspect, update, or deactivate a single client |
GET /api/v1/partners/clients/:clientId/api-keys | X-API-Key: snp-int-... | List client API keys |
POST /api/v1/partners/clients/:clientId/api-keys | X-API-Key: snp-int-... | Create a new client API key |
DELETE /api/v1/partners/clients/:clientId/api-keys/:keyId | X-API-Key: snp-int-... | Revoke a client API key |
Clients API
List Clients
GET /api/integrator/clients?limit=50&offset=0&is_active=true&bundle=STANDARDQuery Parameters
limit- Results per page (default: 50, max: 100)offset- Pagination offsetis_active- Filter by status:trueorfalsebundle- Filter by bundle:LITE,STANDARD,UNLIMITED
Response
{ "success": true, "data": { "clients": [ { "id": "client_456", "projectId": "proj_789", "projectSlug": "acme-client-a", "name": "Client A", "email": "admin@clienta.com", "externalId": "cust_123", "bundle": "STANDARD", "isActive": true, "limits": { "queries_per_month": 10000, ... }, "pricing": { "listMonthlyCents": 4900, "discountPercent": 20, "discountedMonthlyCents": 3920 } } ], "pagination": { "total": 5, "limit": 50, "offset": 0, "hasMore": false } }}Create Client
POST /api/integrator/clients{ "name": "Client A", "email": "admin@clienta.com", "external_id": "cust_123", // optional, your internal ID "bundle": "STANDARD" // LITE, STANDARD, or UNLIMITED}Creating a client automatically provisions an isolated Snipara project with the slug format: {workspace_slug}-{client_name}.
Get Client
GET /api/integrator/clients/:clientIdUpdate Client
PATCH /api/integrator/clients/:clientId{ "name": "New Name", // optional "email": "new@email.com", // optional "bundle": "UNLIMITED", // optional "is_active": false // optional, deactivate client}Delete Client
DELETE /api/integrator/clients/:clientIdWarning: Permanent Deletion
Deleting a client permanently removes their project and all associated data. This action cannot be undone.
Client API Keys
Client API keys use the snp-client-prefix to distinguish them from regular API keys. These keys grant access only to the client's project.
List API Keys
GET /api/integrator/clients/:clientId/api-keysCreate API Key
POST /api/integrator/clients/:clientId/api-keys{ "name": "Production Key", "expires_in_days": 365 // optional, null for no expiration}Response
{ "success": true, "data": { "id": "key_abc123", "name": "Production Key", "key": "snp-client-a1b2c3d4...", // ONLY shown once! "keyPrefix": "snp-client-a1b2", "expiresAt": "2027-02-19T00:00:00Z" }}Save the API Key
The full API key is only returned once during creation. Store it securely and provide it to your client.
Revoke API Key
DELETE /api/integrator/clients/:clientId/api-keys/:keyIdWebhooks
Configure a webhook URL in your workspace to receive real-time notifications about client lifecycle events.
Events
| Event | Trigger |
|---|---|
client.created | New client added to workspace |
client.updated | Client details changed (name, email, bundle, status) |
client.deleted | Client removed from workspace |
api_key.created | New API key generated for a client |
api_key.revoked | API key revoked |
| Swarm & Task Events | |
task.created | New task created in swarm |
task.claimed | Agent claimed a task |
task.completed | Agent completed a task successfully |
task.failed | Task execution failed |
task.blocked | Task blocked by dependency or issue |
task.timeout | Task exceeded deadline — emitted automatically by the platform watchdog (see below) |
htask.completed | Hierarchical task (N3) completed with evidence |
htask.blocked | Hierarchical task blocked with propagation |
htask.closure_ready | Parent task ready to close (all children done) |
Payload Format
{ "event": "client.created", "timestamp": "2026-02-19T15:30:00Z", "workspace_id": "ws_abc123", "data": { "client_id": "client_456", "name": "Client A", "email": "admin@clienta.com", "bundle": "STANDARD", "project_id": "proj_789", "project_slug": "acme-client-a" }}Task Event Payload
{ "event_id": "evt_abc123", "event_type": "task.completed", "workspace_id": "ws_abc123", "created_at": "2026-03-27T14:30:00Z", "data": { "task_id": "task_xyz789", "swarm_id": "swarm_456", "agent_id": "mike", "status": "COMPLETED", "result": { "output": "..." } }}Task Watchdog — Automatic Timeout Detection
Snipara runs a platform-level watchdog that automatically monitors all swarm tasks and hierarchical tasks across every integrator workspace. You do not need to configure anything — timeouts are emitted as task.timeout webhooks to your endpoint.
| Scenario | Trigger | reason field |
|---|---|---|
| Task claimed but never completed | claimedAt older than swarm taskTimeout (default 5 min) | execution_timeout |
| Task assigned but agent never claimed it | createdAt older than swarm claimTimeout (default 10 min) | never_claimed |
| Task created with no agent assigned | createdAt older than swarm claimTimeout | unclaimed |
| Hierarchical task stalled | No updatedAt change for 24 hours while IN_PROGRESS | htask_stalled |
Timeouts are per-swarm. Configure them via snipara_swarm_update with taskTimeout and claimTimeout (in seconds). The watchdog scans every 2 minutes.
Task Timeout Payload
{ "event_id": "evt_abc123", "event_type": "task.timeout", "workspace_id": "ws_abc123", "created_at": "2026-03-27T17:00:00Z", "data": { "task_id": "task_xyz789", "swarm_id": "swarm_456", "agent_id": "mike", "reason": "execution_timeout", "stalled_for_seconds": 720 }}Use the reason field to differentiate scenarios in your handler — for example, re-dispatch on execution_timeout, alert on never_claimed, or escalate on htask_stalled.
Signature Verification
If you configure a webhook secret, all deliveries include an X-Snipara-Signature header for verification:
X-Snipara-Signature: sha256=abc123...Verify using HMAC-SHA256:
import crypto from "crypto";function verifyWebhook(payload: string, signature: string, secret: string): boolean { const expected = "sha256=" + crypto.createHmac("sha256", secret).update(payload).digest("hex"); return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));}Webhook Event Log
Inspect delivery history through the dashboard event-log route. The public dashboard surface exposes event listing and test-send endpoints.
List Delivery Events
GET /api/integrator/webhook-events| Parameter | Type | Description |
|---|---|---|
limit | integer | Number of results to return (default 20) |
offset | integer | Pagination offset |
status | string | Filter by delivery status: pending, delivered, failed |
event_type | string | Filter by event type (e.g. task.completed) |
Send a Test Event
POST /api/integrator/webhook-testSends a test.ping event to your configured webhook URL. Useful for verifying endpoint reachability and signature verification without waiting for a real event.
Bundle Limit Enforcement
When a client exceeds their bundle limits, the MCP API returns a 429 error:
{ "success": false, "error": { "code": "BUNDLE_LIMIT_EXCEEDED", "message": "Monthly query limit exceeded", "limit": 1000, "current": 201, "reset_at": "2026-03-01T00:00:00Z" }}Enforced Limits
| Limit | Enforcement Point |
|---|---|
| Queries/month | Every MCP tool call |
| Memories | snipara_remember tool |
| Swarms | snipara_swarm_create tool |
| Agents/swarm | snipara_swarm_join tool |
| Documents | Document upload endpoints |
| Storage | File upload size validation |
Client API Key Usage
Once you provide a client with their snp-client-* API key, they can use it with any MCP-compatible client.
Claude Code Configuration
// .mcp.json{ "mcpServers": { "snipara": { "type": "http", "url": "https://api.snipara.com/mcp/{project_slug}", "headers": { "X-API-Key": "snp-client-..." } } }}The project_slug is automatically set when you create the client (format: {workspace_slug}-{client_name}).
Wrapping Snipara in Your Own MCP Server
You can wrap the Snipara MCP API inside your own MCP server. Forward the client's snp-client-* key to Snipara, and call the hosted endpoint from your wrapper. For user-scoped memory, also pass a stable external_user_idin memory tool arguments. Snipara hashes and namespaces that value per integrator client, so the end user's personal memory is isolated from the integrator owner and from other clients.
await callSniparaTool("snipara_remember", { scope: "user", external_user_id: "user_123_in_your_system", type: "preference", text: "Prefers concise weekly summaries"});If scope is user and the request uses a client API key, external_user_id is required. Project, team, and agent-scoped memories do not need it.
Error Responses
| Status | Code | Description |
|---|---|---|
| 400 | BAD_REQUEST | Invalid request body or parameters |
| 401 | UNAUTHORIZED | Missing or invalid authentication |
| 403 | FORBIDDEN | Not an approved integrator |
| 404 | NOT_FOUND | Workspace, client, or key not found |
| 409 | CONFLICT | Duplicate email, external_id, or slug |
| 429 | CLIENT_LIMIT_EXCEEDED | Tier client limit reached |
| 500 | INTERNAL_ERROR | Server error |