Supervea-n8n Backend API Documentation
Version: 1.3.0
Base URL: http://localhost:8000
Interactive Docs: GET /docs (Swagger UI) | GET /redoc (ReDoc)
Table of Contents
- Architecture Overview
- Authentication
- Plan Tiers & Feature Gates
- Health Check
- Tasks API
- Calendar API
- Recurring Series API
- Meeting Actions API
- Webhooks API
- Proposals API
- Resources API
- Intent Router API
- Pilot SDK API
- Data Models
- Error Reference
Architecture Overview
Supervea-n8n is a deterministic orchestration backend built with FastAPI. It acts as the governance and execution layer that sits between n8n workflows and the underlying database.
Client / n8n Workflow
│
▼
┌──────────────────────┐
│ FastAPI Backend │
│ (Deterministic) │
│ - Plan Guard │
│ - State Machine │
│ - Audit Logging │
│ - Redis (SLA/Cache) │
└──────────┬───────────┘
│
┌──────┴──────┐
│ │
SQLite DB Redis
(via ORM) (cache/SLA)Key principles:
- No autonomous AI mutation — all execution is rule-based and deterministic
- Multi-tenant — every request is scoped to an
org_id - Append-only audit trail — every mutation is logged
- Plan-tier gating — features are enforced per subscription level
Tech stack:
- Framework: FastAPI (Python)
- Database: SQLite (dev) / PostgreSQL (prod-ready via SQLAlchemy)
- Cache / SLA timers: Redis
- Workflow engine: n8n (external, called via webhooks)
- Background workers: Celery
Authentication
Most endpoints are accessible without authentication for the demo. However, the Intent Router and Pilot SDK support optional API key authentication for tenant-scoped access.
API Key Header
X-Supervea-Key: <your_api_key>When provided, the API key is validated against the organizations.api_key column. Mismatch between the key's org and the org_id in the request body returns 403 Forbidden.
Demo credentials:
| Org ID | API Key |
|---|---|
org_test_001 | key_test_001 |
org-demo-001 | key_demo_001 |
Endpoints that don't require the key still need a valid org_id in the request body/query params.
Plan Tiers & Feature Gates
Every organisation has a plan_tier. Features are gated as follows:
| Tier | Rank | Description |
|---|---|---|
free | 0 | Basic tasks, events, webhooks, resource booking |
starter | 1 | + AI inference, smart calendar, proposals |
pro | 2 | + Workflow orchestration, cross-tool automation |
enterprise | 3 | + SSO, custom webhooks, compliance audit logs |
Features available on FREE tier:
create_task, complete_task, update_task, create_event, check_conflicts, detect_conflicts, book_resource, list_tasks, webhook_inbound, audit_log_read, recurrence_basic
Exceeding plan tier returns: 403 Forbidden with detail message.
Health Check
`GET /`
Root health check.
Response:
{
"service": "Supervea-n8n Deterministic Orchestration Demo",
"version": "1.0.0",
"status": "healthy",
"docs": "/docs"
}Detailed health check including Redis connectivity.
Response:
{
"status": "healthy",
"database": "connected",
"redis": "connected"
}Status values: healthy (all systems up) | degraded (Redis unavailable)
Tasks API
Prefix: /api/v1/tasks
Tags: tasks
Tasks follow a deterministic state machine:
open ──► in_progress ──► completed
│ │
└──► blocked ◄┘
│
└──► cancelledTransitions blocked → open are allowed. Moving in_progress → cancelled is allowed. Invalid transitions return 422.
Create a new task.
Plan required: free
Request body:
{
"org_id": "org_test_001",
"title": "Prepare Q3 report",
"due_at": "2025-07-15T17:00:00Z",
"priority": "high",
"owner_id": "user-uuid-here",
"description": "Include sales figures and KPIs",
"dependencies": ["task-uuid-1"],
"idempotency_key": "unique-key-to-prevent-duplicates"
}| Field | Type | Required | Description | |||
|---|---|---|---|---|---|---|
org_id | string | ✅ | Organisation scope | |||
title | string (1–512) | ✅ | Task title | |||
due_at | ISO-8601 datetime | ✅ | Deadline (stored in UTC) | |||
priority | `low\ | medium\ | high\ | critical` | ❌ | Default: medium |
owner_id | string | ❌ | User ID assigned to this task | |||
description | string | ❌ | Optional longer description | |||
dependencies | string[] | ❌ | Task IDs that must complete first | |||
idempotency_key | string (max 128) | ❌ | Prevents duplicate creation on retries |
Response: 201 Created
{
"id": "uuid",
"org_id": "org_test_001",
"title": "Prepare Q3 report",
"due_at": "2025-07-15T17:00:00Z",
"status": "open",
"priority": "high",
"owner_id": null,
"dependencies": [],
"created_at": "2025-06-03T10:00:00Z",
"completed_at": null,
"sla_breached": false
}On creation, an SLA timer is registered in Redis (expires 1 hour after due_at). An audit log entry is appended automatically.
Retrieve a single task.
Query params: ?org_id=org_test_001 (required)
Response: 200 OK — TaskResponse object
Error: 404 if task not found in org
List tasks for an organisation.
Query params:
| Param | Type | Description |
|---|---|---|
org_id | string | ✅ Required |
status | string | Filter by status |
limit | int (1–200) | Default: 50 |
offset | int | Default: 0 |
Response: 200 OK — Array of TaskResponse
Transition a task to a new status.
Query params: ?org_id=org_test_001
Request body:
{
"new_status": "in_progress",
"actor_id": "user-uuid",
"reason": "Started working on this"
}Business rules enforced:
- Transition must follow the state machine (422 otherwise)
- Moving to
in_progressrequires alldependenciesto becompleted(409 if blocked) - Moving to
completedsetscompleted_atand clears SLA timer in Redis
Get full audit trail for a task (most recent first).
Query params: ?org_id=org_test_001&limit=50
Response:
[
{
"id": 1,
"entity_type": "task",
"entity_id": "uuid",
"action": "status_changed",
"actor_id": "user-uuid",
"timestamp": "2025-06-03T10:00:00Z",
"extra_data": {"from": "open", "to": "in_progress"}
}
]Calendar API
Prefix: /api/v1/calendar
Tags: calendar
Create a calendar event.
Plan required: free
Request body:
{
"org_id": "org_test_001",
"title": "Q3 Review Meeting",
"start": "2025-07-15T09:00:00Z",
"end": "2025-07-15T10:00:00Z",
"attendees": ["user1@company.com", "user2@company.com"],
"required_attendees": ["user1@company.com"],
"locked": false,
"source_timezone": "Europe/Berlin",
"duration_minutes": 60
}| Field | Type | Required | Description |
|---|---|---|---|
org_id | string | ✅ | Organisation scope |
title | string (1–512) | ✅ | Event title |
start | datetime | ✅ | Start time (any tz, stored as UTC) |
end | datetime | ✅ | End time (must be after start) |
attendees | string[] | ❌ | All attendees (user IDs or emails) |
required_attendees | string[] | ❌ | Must be a subset of attendees |
locked | bool | ❌ | Locked events cannot be deleted |
source_timezone | string | ❌ | IANA tz name, e.g. Europe/Berlin |
duration_minutes | int (≥1) | ❌ | Gap 4: enforces exact event length |
Duration rule (Gap 4): If duration_minutes is set, (end - start) must equal exactly that many minutes after UTC normalization. Violation returns 422.
Conflict detection: If required_attendees are supplied, the API checks for overlapping events. Conflict returns 409 with conflict details.
Response: 201 Created — EventResponse
Check for scheduling conflicts without creating an event.
Request body:
{
"org_id": "org_test_001",
"attendees": ["user1@company.com"],
"start": "2025-07-15T09:00:00Z",
"end": "2025-07-15T10:00:00Z",
"source_timezone": null,
"exclude_event_id": null
}Response:
{
"has_conflict": true,
"conflicting_events": [
{"id": "uuid", "title": "Standup", "start_utc": "...", "end_utc": "..."}
],
"checked_attendees": ["user1@company.com"]
}Gap 5 — Per-attendee availability check before booking.
Returns a per-attendee status report without creating anything. Designed to be called by n8n workflows before POST /events.
Request body:
{
"org_id": "org_test_001",
"attendees": ["user1@company.com", "user2@company.com"],
"required_attendees": ["user1@company.com"],
"start": "2025-07-15T09:00:00Z",
"end": "2025-07-15T10:00:00Z",
"exclude_event_id": null
}Response:
{
"can_schedule": true,
"required_blocked": [],
"attendees": [
{
"attendee_id": "user1@company.com",
"status": "available",
"is_required": true,
"conflicts": []
},
{
"attendee_id": "user2@company.com",
"status": "conflict",
"is_required": false,
"conflicts": [{"id": "uuid", "title": "...", "start_utc": "...", "end_utc": "..."}]
}
]
}Attendee statuses:
available— exists in org, no overlapping eventsconflict— exists in org, has overlapping eventsunknown— not found in org's users table (external guest)
can_schedule: true only when all required attendees are available.
Get a single event.
Query params: ?org_id=org_test_001
List events with optional time-range filter.
Query params:
| Param | Type | Description |
|---|---|---|
org_id | string | ✅ Required |
from_utc | datetime | Filter events starting after |
to_utc | datetime | Filter events ending before |
limit | int (1–200) | Default: 50 |
Delete an event.
Query params: ?org_id=org_test_001
Locked events cannot be deleted — returns 409 Conflict.
Recurring Series API
Prefix: /api/v1/calendar
Tags: recurring
Gap 1 — RFC 5545 rrule-based recurring event management.
A "series" is a group of CalendarEvent rows sharing a common series_id. The template event (first instance) stores the rrule string. Subsequent instances carry only the series_id.
Create a recurring series of events.
Request body:
{
"org_id": "org_test_001",
"title": "Weekly Standup",
"frequency": "weekly",
"interval": 1,
"byday": ["MO", "WE", "FR"],
"count": 12,
"dtstart": "2025-07-07T09:00:00Z",
"duration_minutes": 30,
"attendees": ["user1@company.com"],
"required_attendees": ["user1@company.com"],
"source_timezone": "Europe/London",
"locked": false
}Recurrence options (mutually exclusive):
Option A — human-friendly fields:
| Field | Type | Description | ||
|---|---|---|---|---|
frequency | `daily\ | weekly\ | monthly` | Repeat frequency |
interval | int (≥1) | Every N units | ||
byday | string[] | Weekday abbreviations e.g. ["MO","WE","FR"] | ||
count | int | Total occurrences | ||
until | datetime | Hard end date |
Option B — raw rrule string:
{
"rrule": "FREQ=WEEKLY;BYDAY=MO,WE,FR;COUNT=12"
}Response: 201 Created
{
"series_id": "uuid",
"rrule": "FREQ=WEEKLY;BYDAY=MO,WE,FR;COUNT=12",
"instance_count": 12,
"instances": [
{"id": "uuid", "start_utc": "...", "end_utc": "...", "title": "...", "locked": false}
]
}Expansion is capped at 365 instances per series. Run POST /calendar/events/preflight-attendees beforehand to check availability.
List all instances in a series (chronological order).
Query params: ?org_id=org_test_001
Cancel all future instances of a series.
Past instances (already started) are preserved for audit integrity. Locked future instances are still deleted (series-level cancellation overrides individual locks).
Response:
{
"series_id": "uuid",
"deleted_future_instances": 8,
"preserved_past_instances": 4
}Remove a single instance from a series.
Locked instances cannot be individually removed — returns 409 Conflict.
Meeting Actions API
Prefix: /api/v1/calendar
Tags: meeting-actions
Gap 2 — When a meeting ends, an n8n workflow POSTs action specs to spawn follow-up tasks and events. All actions are committed atomically.
Spawn tasks and/or follow-up events from a completed meeting.
Request body:
{
"org_id": "org_test_001",
"actions": [
{
"action_type": "task",
"title": "Send meeting recap",
"due_at": "2025-07-15T18:00:00Z",
"priority": "high",
"owner_id": "user-uuid"
},
{
"action_type": "event",
"title": "Follow-up Review",
"start": "2025-07-22T09:00:00Z",
"end": "2025-07-22T10:00:00Z",
"attendees": ["user1@company.com"],
"required_attendees": ["user1@company.com"],
"duration_minutes": 60
}
]
}Action types:
task action spec:
| Field | Type | Required | |||
|---|---|---|---|---|---|
action_type | "task" | ✅ | |||
title | string | ✅ | |||
due_at | datetime | ✅ | |||
priority | `low\ | medium\ | high\ | critical` | ❌ |
owner_id | string | ❌ | |||
description | string | ❌ | |||
dependencies | string[] | ❌ |
event action spec:
| Field | Type | Required |
|---|---|---|
action_type | "event" | ✅ |
title | string | ✅ |
start | datetime | ✅ |
end | datetime | ✅ |
attendees | string[] | ❌ |
required_attendees | string[] | ❌ |
duration_minutes | int | ❌ Gap 4 enforcement |
Limits: Max 50 actions per call. Batch is atomic — any failure rolls back all.
Response: 201 Created
{
"source_event_id": "uuid",
"spawned_tasks": [
{"id": "uuid", "title": "Send recap", "due_at": "...", "priority": "high", "status": "open", "source_event_id": "uuid"}
],
"spawned_events": [
{"id": "uuid", "title": "Follow-up Review", "start_utc": "...", "end_utc": "...", "attendees": [...], "source_event_id": "uuid"}
],
"total_spawned": 2
}List all tasks and events previously spawned from a source event.
Query params: ?org_id=org_test_001
Webhooks API
Prefix: /api/v1/webhooks
Tags: webhooks
n8n-compatible inbound webhook endpoints for task creation.
n8n webhook: create a task from an n8n HTTP Request node.
Rate limit: 100 requests/minute per org
Request body:
{
"type": "deterministic",
"org_id": "org_test_001",
"title": "Review SLA report",
"due_at": "2025-07-15T17:00:00Z",
"priority": "medium",
"owner_id": null,
"idempotency_key": "n8n-run-12345"
}| Field | Type | Required | Description | |
|---|---|---|---|---|
type | `deterministic\ | inference` | ❌ | Default: deterministic. inference requires Starter+ |
org_id | string | ✅ | ||
title | string | ✅ | ||
due_at | ISO-8601 | ✅ | ||
priority | string | ❌ | Default: medium | |
idempotency_key | string | ❌ | Prevents duplicate on n8n retry |
Extra fields from n8n payloads are silently ignored (configured with extra = "ignore").
Response: 201 Created
{
"success": true,
"task_id": "uuid",
"org_id": "org_test_001",
"title": "Review SLA report",
"status": "open",
"due_at": "2025-07-15T17:00:00Z",
"created_at": "2025-06-03T10:00:00Z",
"idempotent_hit": false
}idempotent_hit: true means the task already existed (duplicate prevented).
Health check for n8n connection testing.
Response:
{"status": "ok", "service": "supervea-n8n-demo", "timestamp": "2025-06-03T10:00:00Z"}Proposals API
Prefix: /api/v1/proposals
Tags: proposals
The Proactive Intelligence Engine — AI/rule-generated suggestions that are staged for human governance review before any execution occurs.
Lifecycle:
pending → approved → converted (Task/Event created)
pending → ignoredAt status=pending, NOTHING executes. Execution only happens after explicit human approval through the governance endpoint.
Ingest a proposal (from n8n or signal generator).
Request body:
{
"org_id": "org_test_001",
"signal_type": "overdue_threshold_exceeded",
"signal_data": {"task_count": 5, "avg_days_overdue": 3.2},
"goal": "Reduce overdue tasks by assigning a review meeting",
"suggested_action": {
"title": "Task Review Session",
"type": "calendar_event",
"priority": "high"
},
"confidence": 0.87,
"source": "rule"
}| Field | Type | Required | Description | ||
|---|---|---|---|---|---|
org_id | string | ✅ | |||
signal_type | string (max 128) | ✅ | e.g. overdue_threshold_exceeded | ||
signal_data | object | ❌ | Raw signal payload | ||
goal | string | ✅ | Human-readable goal statement | ||
suggested_action | object | ✅ | Structured action dict | ||
confidence | float (0.0–1.0) | ✅ | Confidence score | ||
source | `rule\ | ai\ | n8n` | ❌ | Default: n8n |
Response: 201 Created — ProposalResponse with status: "pending"
List proposals for an organisation.
Query params:
| Param | Type | Description | |||
|---|---|---|---|---|---|
org_id | string | ✅ Required | |||
status | `pending\ | approved\ | ignored\ | converted` | Filter (default: pending) |
limit | int | Default: 50 | |||
offset | int | Default: 0 |
Approve a proposal → converts it into a real Task.
Query params: ?org_id=org_test_001
Request body:
{
"actor_id": "manager-user-uuid",
"title_override": "Task Review Session - Urgent",
"due_at_override": "2025-07-20T17:00:00Z",
"priority_override": "critical"
}On approval:
- Creates a real
Taskfromsuggested_action+ overrides - Marks proposal as
converted - Appends two audit entries (proposal approval + task creation)
Only pending proposals can be approved. Attempting to approve an already-processed proposal returns 409 Conflict.
Dismiss a proposal without taking action.
Request body:
{
"actor_id": "manager-user-uuid",
"reason": "Already handled manually"
}Resources API
Prefix: /api/v1/resources
Tags: resources
Gap 3 — Deterministic resource booking (rooms, projectors, equipment). No AI — all decisions are rule-based overlap checks.
Business rules:
- A resource cannot be double-booked (half-open interval overlap check)
- Booking requires the resource to exist, be active, and belong to the same org
- Bookings are linked to existing
CalendarEventIDs - Same (resource, event) pair is idempotent (returns existing booking)
Register a new bookable resource.
Request body:
{
"org_id": "org_test_001",
"name": "Boardroom A",
"resource_type": "room",
"capacity": 12,
"meta": {"floor": 3, "has_projector": true}
}Names must be unique within the org. Violation returns 409.
List bookable resources for an organisation.
Query params:
| Param | Type | Description |
|---|---|---|
org_id | string | ✅ Required |
resource_type | string | Filter by type (e.g. room) |
active_only | bool | Default: true |
Pre-seeded resources (org_test_001):
| ID | Name | Type | Capacity |
|---|---|---|---|
boardroom | Boardroom | room | 12 |
conference_room | Conference Room | room | 8 |
projector | Projector | equipment | 1 |
Get a single resource.
Query params: ?org_id=org_test_001
Dry-run availability check (no booking created).
Request body:
{
"org_id": "org_test_001",
"resource_ids": ["boardroom", "projector"],
"start": "2025-07-15T09:00:00Z",
"end": "2025-07-15T10:00:00Z",
"exclude_event_id": null
}Response:
{
"all_available": false,
"conflicts": [
{
"resource_id": "boardroom",
"resource_name": "Boardroom",
"conflicting_event_ids": ["event-uuid-1"]
}
]
}Book resources for an existing CalendarEvent.
Request body:
{
"org_id": "org_test_001",
"event_id": "calendar-event-uuid",
"resource_ids": ["boardroom", "projector"]
}All bookings committed atomically. Partial failures roll back all. Conflict returns 409.
Response: 201 Created — Array of BookingResponse
Release a resource booking.
Query params: ?org_id=org_test_001
Frees the resource and updates the CalendarEvent.resources JSON list.
Intent Router API
Prefix: /api/v1/intent
Tags: intent-router
The Deterministic Intent Router (DIR) classifies natural language intents into known use cases and routes them to the correct backend operation or n8n workflow — without any LLM inference.
Pipeline:
Natural Language Intent
│
▼
1. Keyword/Feature Extraction
│
▼
2. Route Decision (atomic vs workflow)
│
▼
3. Parameter Normalisation
│
▼
4. Plan Guard Check
│
▼
5. Domain Execution (API call or n8n trigger)
│
▼
6. Persist IntentExecution recordAuthentication: Optional X-Supervea-Key header for tenant scoping.
Classify an intent without executing anything.
Request body:
{
"intent": "Create a task for Sarah due tomorrow",
"org_id": "org_test_001",
"user_id": "user-uuid",
"org_plan": "free"
}| Field | Type | Required | Description | |||
|---|---|---|---|---|---|---|
intent | string (3–1000) | ✅ | Natural language input | |||
org_id | string | ✅ | Organisation scope | |||
user_id | string | ❌ | For audit logging | |||
org_plan | `free\ | starter\ | pro\ | enterprise` | ❌ | Default: free |
Response:
{
"route_decision": {
"route": "atomic",
"target": "create_task",
"confidence": 0.95,
"reasoning": "Matched keyword 'create a task'",
"complexity_score": 0.1
},
"features": {
"has_multi_step_connectors": false,
"has_multi_system_coordination": false,
"has_scheduling": false,
"has_aggregation": false,
"has_conditional": false,
"action_count": 1,
"detected_services": [],
"matched_use_case": "create_task"
},
"normalized": {
"use_case_id": "create_task",
"parameters": {"title": "Task for Sarah", "org_id": "org_test_001"},
"confidence": 0.95,
"missing_params": []
},
"processed_at": "2025-06-03T10:00:00Z",
"use_case_info": {...},
"ready_to_execute": true,
"missing_params": [],
"safety_tier": 2,
"safety_threshold": 0.8,
"cached": false,
"execution": null
}Classify and execute an intent end-to-end.
Same request body as /route. On success, includes the execution field in the response:
{
"execution": {
"success": true,
"use_case_id": "create_task",
"n8n_execution_id": "n8n-exec-uuid",
"status": "triggered",
"result": {...}
}
}Execution statuses:
triggered— n8n webhook called successfullyskipped— missing required params prevented executionfailed— n8n returned errorplan_blocked— org plan insufficientshadowed— executed in shadow mode (observability only)
List all registered use cases.
Response:
{
"atomic": [
{
"id": "create_task",
"name": "Create Task",
"plan_tier": "free",
"keywords": ["create task", "add task", ...],
"required_params": ["title", "org_id"]
}
],
"workflow": [
{
"id": "prepare_business_review",
"name": "Prepare Business Review",
"plan_tier": "pro",
"keywords": ["business review", ...],
"required_params": ["org_id"],
"services": ["hubspot", "salesforce", "powerbi"]
}
],
"total_atomic": 5,
"total_workflow": 4
}Registered atomic use cases:
| ID | Name | Plan | Backend |
|---|---|---|---|
create_task | Create Task | free | POST /api/v1/tasks/ |
complete_task | Complete Task | free | PATCH /api/v1/tasks/{id}/status |
create_event | Create Calendar Event | free | POST /api/v1/calendar/events |
check_conflicts | Check Calendar Conflicts | free | POST /api/v1/calendar/events/check-conflicts |
book_resource | Book a Resource | free | POST /api/v1/resources/book |
list_tasks | List Tasks | free | GET /api/v1/tasks/ |
Registered workflow use cases:
| ID | Name | Plan | Services |
|---|---|---|---|
prepare_business_review | Prepare Business Review | pro | HubSpot, Salesforce, PowerBI |
onboard_new_employee | Onboard New Employee | pro | Slack, Gmail, Notion, Jira |
weekly_report | Generate Weekly Report | pro | Gmail, Slack, Notion |
sync_crm_calendar | Sync CRM and Calendar | pro | HubSpot, Salesforce |
List recent intent executions for an org.
Query params: ?org_id=org_test_001&limit=20
Get multi-tenant intent gateway metrics.
Query params: ?org_id=org_test_001
Response includes:
requests_total,avg_latency_ms,replay_rate,sei_scorecache_hit_rate,total_tokens_saved,cost_savings_usd,error_ratepilot_metrics— detailed breakdown of pilot SDK eventspolicy— org routing policy settings
List all workflow patterns and their active state / metrics.
Query params: ?org_id=org_test_001
Toggle a workflow pattern (kill switch).
Request body:
{
"org_id": "org_test_001",
"pattern_key": "prepare_business_review",
"is_active": false
}Disabling a pattern prevents it from being executed. Redis cache is invalidated on toggle.
Update organisation routing policy.
Request body:
{
"org_id": "org_test_001",
"shadow_enabled": false,
"bypass_threshold": 0.85,
"bypass_percentage": 1.0,
"never_bypass_list": ["onboard_new_employee"]
}| Field | Description |
|---|---|
shadow_enabled | Execute in shadow mode (observe without acting) |
bypass_threshold | Minimum confidence to bypass governance gate |
bypass_percentage | Percentage of requests allowed to bypass |
never_bypass_list | Use case IDs that always require human approval |
Export full pattern library and routing policies as a portable JSON backup.
Query params: ?org_id=org_test_001
Restore a previously exported pattern library and policies.
Request body:
{
"org_id": "org_test_001",
"bundle": {
"patterns": [...],
"policy": {...}
}
}Pilot SDK API
Prefix: /api/v1/pilot
Tags: pilot-sdk
Tracks LLM call telemetry from the Supervea Python SDK, enabling cache hit tracking, cost savings reporting, and pilot metrics dashboards.
Authentication required: X-Supervea-Key header.
SDK posts telemetry after every LLM call.
Headers: X-Supervea-Key: key_test_001
Request body:
{
"org_id": "org_test_001",
"latency_ms": 234.5,
"tokens_in": 150,
"tokens_out": 80,
"tokens_saved": 0,
"estimated_cost_usd": 0.0032,
"cache_hit": false,
"fallback_triggered": false,
"error": false,
"provider": "openai",
"model": "gpt-4o-mini"
}Response: 201 Created
{"status": "success", "event_id": "uuid"}High-speed Redis cache lookup for identical prompt contexts.
Request body:
{
"org_id": "org_test_001",
"messages": [{"role": "user", "content": "Summarize the report"}],
"model": "gpt-4o-mini"
}Response:
{"hit": true, "response": {...cached_response...}}or
{"hit": false, "response": null}Cache key is a SHA-256 hash of model + messages. TTL: 24 hours.
Store a successful completion response in Redis.
Request body:
{
"org_id": "org_test_001",
"messages": [...],
"model": "gpt-4o-mini",
"response": {...completion_response...}
}Aggregate pilot statistics for an organization.
Response:
{
"org_id": "org_test_001",
"total_requests": 150,
"cache_hits": 62,
"cache_hit_rate": 41.33,
"avg_latency_ms": 312.4,
"avg_cache_latency_ms": 18.2,
"avg_non_cache_latency_ms": 543.7,
"latency_reduction_pct": 96.65,
"total_tokens_in": 22500,
"total_tokens_out": 12000,
"total_tokens_saved": 14700,
"total_cost_potential": 0.4820,
"total_cost_saved": 0.1993,
"total_cost_actual": 0.2827,
"cost_savings_pct": 41.33,
"fallback_activations": 3,
"error_count": 1,
"error_rate": 0.67
}Render an HTML investor-grade pilot impact report.
Returns text/html. Navigate to this URL in a browser. Report includes cache hit rate, latency reduction, token savings, and cost impact.
Execute a chat completion via the Supervea SDK caching layer (playground).
Request body:
{
"provider": "openai",
"apiKey": "sk-...",
"prompt": "Summarize the weekly tasks",
"org_id": "org_test_001"
}Supported providers: openai (model: gpt-4o-mini) | gemini (model: gemini-2.5-flash)
Response:
{
"success": true,
"response": "Here is your summary...",
"latency_ms": 412.3,
"cached": false,
"tokens_in": 25,
"tokens_out": 87,
"tokens_saved": 0,
"cost_saved_usd": 0.0
}Data Models
Organization
| Column | Type | Description | |||
|---|---|---|---|---|---|
id | string(36) | Primary key | |||
name | string(255) | Organization name | |||
plan_tier | enum | `free\ | starter\ | pro\ | enterprise` |
api_key | string(128) | API key for authentication | |||
shadow_enabled | bool | Shadow mode flag | |||
bypass_threshold | float | Confidence threshold to bypass governance | |||
bypass_percentage | float | % of requests allowed to bypass | |||
never_bypass_list | JSON array | Use case IDs always requiring human review | |||
created_at | datetime | UTC |
Task
| Column | Type | Description | ||||
|---|---|---|---|---|---|---|
id | string(36) | UUID primary key | ||||
org_id | string(36) | FK → organizations | ||||
title | string(512) | Task title | ||||
description | text | Optional description | ||||
due_at | datetime | Deadline (UTC) | ||||
status | enum | `open\ | in_progress\ | blocked\ | completed\ | cancelled` |
priority | enum | `low\ | medium\ | high\ | critical` | |
owner_id | string(36) | FK → users (nullable) | ||||
dependencies | JSON | List of task IDs | ||||
idempotency_key | string(128) | Deduplication key | ||||
created_at | datetime | UTC | ||||
completed_at | datetime | UTC, set on completion | ||||
sla_breached | bool | Set by escalation worker | ||||
source_event_id | string(36) | Meeting that spawned this task (nullable) |
CalendarEvent
| Column | Type | Description |
|---|---|---|
id | string(36) | UUID primary key |
org_id | string(36) | FK → organizations |
title | string(512) | Event title |
start_utc | datetime | Start time (UTC) |
end_utc | datetime | End time (UTC) |
attendees | JSON | List of attendee IDs/emails |
required_attendees | JSON | Subset of attendees (hard blockers) |
locked | bool | Prevents deletion when true |
series_id | string(36) | Groups recurring instances (nullable) |
rrule | text | RFC 5545 recurrence rule on template event |
source_event_id | string(36) | Parent meeting that spawned this (nullable) |
resources | JSON | List of booked resource IDs |
duration_minutes | int | Enforced meeting duration (nullable) |
created_at | datetime | UTC |
Resource
| Column | Type | Description |
|---|---|---|
id | string(36) | UUID primary key |
org_id | string(36) | FK → organizations |
name | string(255) | Resource name (unique per org) |
resource_type | string(64) | e.g. room, equipment |
capacity | int | Max users (null = unlimited) |
meta | JSON | Extra attributes |
active | bool | Soft-delete flag |
ResourceBooking
| Column | Type | Description |
|---|---|---|
id | string(36) | UUID |
resource_id | string(36) | FK → resources |
event_id | string(36) | FK → calendar_events |
org_id | string(36) | Denormalised for fast queries |
start_utc | datetime | Mirrors event start |
end_utc | datetime | Mirrors event end |
booked_at | datetime | When booking was created |
Unique constraint: (resource_id, event_id) — idempotent booking per resource/event pair.
Proposal
| Column | Type | Description | |||
|---|---|---|---|---|---|
id | string(36) | UUID | |||
org_id | string(36) | FK → organizations | |||
signal_type | string(128) | e.g. overdue_threshold_exceeded | |||
signal_data | JSON | Raw signal payload | |||
goal | text | Human-readable goal | |||
suggested_action | JSON | Structured action dict | |||
confidence | string(8) | Stored as string, e.g. "0.87" | |||
source | enum | `rule\ | ai\ | n8n` | |
status | enum | `pending\ | approved\ | ignored\ | converted` |
reviewed_at | datetime | When governance action taken | |||
reviewed_by | string | Actor who reviewed | |||
converted_entity_type | string | task or calendar_event | |||
converted_entity_id | string | ID of created entity |
IntentExecution
| Column | Type | Description | ||||
|---|---|---|---|---|---|---|
id | string(36) | UUID | ||||
org_id | string(36) | Tenant scope | ||||
raw_intent | text | Original natural language input | ||||
use_case_id | string(128) | e.g. create_task | ||||
route_type | string(32) | atomic or workflow | ||||
confidence | float | Routing confidence score | ||||
parameters | JSON | Extracted params snapshot | ||||
missing_params | JSON | List of missing param names | ||||
status | enum | `triggered\ | skipped\ | failed\ | plan_blocked\ | shadowed` |
n8n_execution_id | string | ID returned by n8n | ||||
error_detail | text | Error message if failed | ||||
latency_ms | float | Execution latency | ||||
created_at | datetime | UTC |
AuditLog
Append-only — rows are never updated or deleted.
| Column | Type | Description |
|---|---|---|
id | int | Auto-increment PK |
org_id | string(36) | Tenant scope |
entity_type | string(64) | e.g. task, calendar_event |
entity_id | string(36) | ID of the affected entity |
action | string(128) | e.g. created, status_changed |
actor_id | string(36) | User who triggered the action |
timestamp | datetime | UTC |
extra_data | JSON | Additional context |
Error Reference
| HTTP Code | When |
|---|---|
400 Bad Request | Missing required parameters |
401 Unauthorized | Missing API key on protected endpoint |
403 Forbidden | Invalid API key, tenant mismatch, or plan tier insufficient |
404 Not Found | Resource, task, event, or org not found |
409 Conflict | Duplicate resource name, scheduling conflict, locked event, invalid state transition, blocking dependencies |
422 Unprocessable Entity | Validation error (invalid enum value, duration rule violation, missing required field) |
429 Too Many Requests | Webhook rate limit exceeded (100/min per org) |
500 Internal Server Error | Unhandled exception (check server logs) |
501 Not Implemented | Feature not available in demo mode |
Error response format:
{
"detail": "Human-readable error message or structured object"
}For conflict errors, detail may be a structured object:
{
"detail": {
"message": "Event conflicts with existing events for required attendees.",
"conflicts": [
{"id": "...", "title": "...", "start_utc": "...", "end_utc": "..."}
]
}
}