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

  1. Architecture Overview
  2. Authentication
  3. Plan Tiers & Feature Gates
  4. Health Check
  5. Tasks API
  6. Calendar API
  7. Recurring Series API
  8. Meeting Actions API
  9. Webhooks API
  10. Proposals API
  11. Resources API
  12. Intent Router API
  13. Pilot SDK API
  14. Data Models
  15. 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.

code
Client / n8n Workflow
        │
        ▼
┌──────────────────────┐
│  FastAPI Backend     │
│  (Deterministic)     │
│  - Plan Guard        │
│  - State Machine     │
│  - Audit Logging     │
│  - Redis (SLA/Cache) │
└──────────┬───────────┘
           │
    ┌──────┴──────┐
    │             │
 SQLite DB     Redis
 (via ORM)   (cache/SLA)

Key principles:

Tech stack:


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

code
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 IDAPI Key
org_test_001key_test_001
org-demo-001key_demo_001
note

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:

TierRankDescription
free0Basic tasks, events, webhooks, resource booking
starter1+ AI inference, smart calendar, proposals
pro2+ Workflow orchestration, cross-tool automation
enterprise3+ 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:

json
{
  "service": "Supervea-n8n Deterministic Orchestration Demo",
  "version": "1.0.0",
  "status": "healthy",
  "docs": "/docs"
}

GET/health

Detailed health check including Redis connectivity.

Response:

json
{
  "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:

code
open  ──►  in_progress  ──►  completed
 │              │
 └──►  blocked ◄┘
 │
 └──►  cancelled

Transitions blocked → open are allowed. Moving in_progress → cancelled is allowed. Invalid transitions return 422.


POST/api/v1/tasks/

Create a new task.

Plan required: free

Request body:

json
{
  "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"
}
FieldTypeRequiredDescription
org_idstringOrganisation scope
titlestring (1–512)Task title
due_atISO-8601 datetimeDeadline (stored in UTC)
priority`low\medium\high\critical`Default: medium
owner_idstringUser ID assigned to this task
descriptionstringOptional longer description
dependenciesstring[]Task IDs that must complete first
idempotency_keystring (max 128)Prevents duplicate creation on retries

Response: 201 Created

json
{
  "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
}
note

On creation, an SLA timer is registered in Redis (expires 1 hour after due_at). An audit log entry is appended automatically.


GET/api/v1/tasks/{task_id}

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


GET/api/v1/tasks/

List tasks for an organisation.

Query params:

ParamTypeDescription
org_idstring✅ Required
statusstringFilter by status
limitint (1–200)Default: 50
offsetintDefault: 0

Response: 200 OK — Array of TaskResponse


PATCH/api/v1/tasks/{task_id}/status

Transition a task to a new status.

Query params: ?org_id=org_test_001

Request body:

json
{
  "new_status": "in_progress",
  "actor_id": "user-uuid",
  "reason": "Started working on this"
}

Business rules enforced:


GET/api/v1/tasks/{task_id}/audit

Get full audit trail for a task (most recent first).

Query params: ?org_id=org_test_001&limit=50

Response:

json
[
  {
    "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


POST/api/v1/calendar/events

Create a calendar event.

Plan required: free

Request body:

json
{
  "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
}
FieldTypeRequiredDescription
org_idstringOrganisation scope
titlestring (1–512)Event title
startdatetimeStart time (any tz, stored as UTC)
enddatetimeEnd time (must be after start)
attendeesstring[]All attendees (user IDs or emails)
required_attendeesstring[]Must be a subset of attendees
lockedboolLocked events cannot be deleted
source_timezonestringIANA tz name, e.g. Europe/Berlin
duration_minutesint (≥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


POST/api/v1/calendar/events/check-conflicts

Check for scheduling conflicts without creating an event.

Request body:

json
{
  "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:

json
{
  "has_conflict": true,
  "conflicting_events": [
    {"id": "uuid", "title": "Standup", "start_utc": "...", "end_utc": "..."}
  ],
  "checked_attendees": ["user1@company.com"]
}

POST/api/v1/calendar/events/preflight-attendees

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:

json
{
  "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:

json
{
  "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:

can_schedule: true only when all required attendees are available.


GET/api/v1/calendar/events/{event_id}

Get a single event.

Query params: ?org_id=org_test_001


GET/api/v1/calendar/events

List events with optional time-range filter.

Query params:

ParamTypeDescription
org_idstring✅ Required
from_utcdatetimeFilter events starting after
to_utcdatetimeFilter events ending before
limitint (1–200)Default: 50

DELETE/api/v1/calendar/events/{event_id}

Delete an event.

Query params: ?org_id=org_test_001

warning

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.


POST/api/v1/calendar/series

Create a recurring series of events.

Request body:

json
{
  "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:

FieldTypeDescription
frequency`daily\weekly\monthly`Repeat frequency
intervalint (≥1)Every N units
bydaystring[]Weekday abbreviations e.g. ["MO","WE","FR"]
countintTotal occurrences
untildatetimeHard end date

Option B — raw rrule string:

json
{
  "rrule": "FREQ=WEEKLY;BYDAY=MO,WE,FR;COUNT=12"
}

Response: 201 Created

json
{
  "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}
  ]
}
note

Expansion is capped at 365 instances per series. Run POST /calendar/events/preflight-attendees beforehand to check availability.


GET/api/v1/calendar/series/{series_id}

List all instances in a series (chronological order).

Query params: ?org_id=org_test_001


DELETE/api/v1/calendar/series/{series_id}

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:

json
{
  "series_id": "uuid",
  "deleted_future_instances": 8,
  "preserved_past_instances": 4
}

DELETE/api/v1/calendar/series/{series_id}/instances/{event_id}

Remove a single instance from a series.

warning

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.


POST/api/v1/calendar/events/{event_id}/spawn-actions

Spawn tasks and/or follow-up events from a completed meeting.

Request body:

json
{
  "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:

FieldTypeRequired
action_type"task"
titlestring
due_atdatetime
priority`low\medium\high\critical`
owner_idstring
descriptionstring
dependenciesstring[]

event action spec:

FieldTypeRequired
action_type"event"
titlestring
startdatetime
enddatetime
attendeesstring[]
required_attendeesstring[]
duration_minutesint❌ Gap 4 enforcement

Limits: Max 50 actions per call. Batch is atomic — any failure rolls back all.

Response: 201 Created

json
{
  "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
}

GET/api/v1/calendar/events/{event_id}/spawned

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.


POST/api/v1/webhooks/task-created

n8n webhook: create a task from an n8n HTTP Request node.

Rate limit: 100 requests/minute per org

Request body:

json
{
  "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"
}
FieldTypeRequiredDescription
type`deterministic\inference`Default: deterministic. inference requires Starter+
org_idstring
titlestring
due_atISO-8601
prioritystringDefault: medium
idempotency_keystringPrevents duplicate on n8n retry
important

Extra fields from n8n payloads are silently ignored (configured with extra = "ignore").

Response: 201 Created

json
{
  "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).


GET/api/v1/webhooks/ping

Health check for n8n connection testing.

Response:

json
{"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:

code
pending  →  approved  →  converted (Task/Event created)
pending  →  ignored
important

At status=pending, NOTHING executes. Execution only happens after explicit human approval through the governance endpoint.


POST/api/v1/proposals/

Ingest a proposal (from n8n or signal generator).

Request body:

json
{
  "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"
}
FieldTypeRequiredDescription
org_idstring
signal_typestring (max 128)e.g. overdue_threshold_exceeded
signal_dataobjectRaw signal payload
goalstringHuman-readable goal statement
suggested_actionobjectStructured action dict
confidencefloat (0.0–1.0)Confidence score
source`rule\ai\n8n`Default: n8n

Response: 201 Created — ProposalResponse with status: "pending"


GET/api/v1/proposals/

List proposals for an organisation.

Query params:

ParamTypeDescription
org_idstring✅ Required
status`pending\approved\ignored\converted`Filter (default: pending)
limitintDefault: 50
offsetintDefault: 0

PATCH/api/v1/proposals/{proposal_id}/approve

Approve a proposal → converts it into a real Task.

Query params: ?org_id=org_test_001

Request body:

json
{
  "actor_id": "manager-user-uuid",
  "title_override": "Task Review Session - Urgent",
  "due_at_override": "2025-07-20T17:00:00Z",
  "priority_override": "critical"
}

On approval:

  1. Creates a real Task from suggested_action + overrides
  2. Marks proposal as converted
  3. Appends two audit entries (proposal approval + task creation)

Only pending proposals can be approved. Attempting to approve an already-processed proposal returns 409 Conflict.


PATCH/api/v1/proposals/{proposal_id}/ignore

Dismiss a proposal without taking action.

Request body:

json
{
  "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:


POST/api/v1/resources

Register a new bookable resource.

Request body:

json
{
  "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.


GET/api/v1/resources

List bookable resources for an organisation.

Query params:

ParamTypeDescription
org_idstring✅ Required
resource_typestringFilter by type (e.g. room)
active_onlyboolDefault: true

Pre-seeded resources (org_test_001):

IDNameTypeCapacity
boardroomBoardroomroom12
conference_roomConference Roomroom8
projectorProjectorequipment1

GET/api/v1/resources/{resource_id}

Get a single resource.

Query params: ?org_id=org_test_001


POST/api/v1/resources/check-availability

Dry-run availability check (no booking created).

Request body:

json
{
  "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:

json
{
  "all_available": false,
  "conflicts": [
    {
      "resource_id": "boardroom",
      "resource_name": "Boardroom",
      "conflicting_event_ids": ["event-uuid-1"]
    }
  ]
}

POST/api/v1/resources/book

Book resources for an existing CalendarEvent.

Request body:

json
{
  "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


DELETE/api/v1/resources/bookings/{booking_id}

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:

code
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 record

Authentication: Optional X-Supervea-Key header for tenant scoping.


POST/api/v1/intent/route

Classify an intent without executing anything.

Request body:

json
{
  "intent": "Create a task for Sarah due tomorrow",
  "org_id": "org_test_001",
  "user_id": "user-uuid",
  "org_plan": "free"
}
FieldTypeRequiredDescription
intentstring (3–1000)Natural language input
org_idstringOrganisation scope
user_idstringFor audit logging
org_plan`free\starter\pro\enterprise`Default: free

Response:

json
{
  "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
}

POST/api/v1/intent/submit

Classify and execute an intent end-to-end.

Same request body as /route. On success, includes the execution field in the response:

json
{
  "execution": {
    "success": true,
    "use_case_id": "create_task",
    "n8n_execution_id": "n8n-exec-uuid",
    "status": "triggered",
    "result": {...}
  }
}

Execution statuses:


GET/api/v1/intent/use-cases

List all registered use cases.

Response:

json
{
  "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:

IDNamePlanBackend
create_taskCreate TaskfreePOST /api/v1/tasks/
complete_taskComplete TaskfreePATCH /api/v1/tasks/{id}/status
create_eventCreate Calendar EventfreePOST /api/v1/calendar/events
check_conflictsCheck Calendar ConflictsfreePOST /api/v1/calendar/events/check-conflicts
book_resourceBook a ResourcefreePOST /api/v1/resources/book
list_tasksList TasksfreeGET /api/v1/tasks/

Registered workflow use cases:

IDNamePlanServices
prepare_business_reviewPrepare Business ReviewproHubSpot, Salesforce, PowerBI
onboard_new_employeeOnboard New EmployeeproSlack, Gmail, Notion, Jira
weekly_reportGenerate Weekly ReportproGmail, Slack, Notion
sync_crm_calendarSync CRM and CalendarproHubSpot, Salesforce

GET/api/v1/intent/executions

List recent intent executions for an org.

Query params: ?org_id=org_test_001&limit=20


GET/api/v1/intent/metrics

Get multi-tenant intent gateway metrics.

Query params: ?org_id=org_test_001

Response includes:


GET/api/v1/intent/patterns

List all workflow patterns and their active state / metrics.

Query params: ?org_id=org_test_001


POST/api/v1/intent/patterns/toggle

Toggle a workflow pattern (kill switch).

Request body:

json
{
  "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.


POST/api/v1/intent/patterns/policy

Update organisation routing policy.

Request body:

json
{
  "org_id": "org_test_001",
  "shadow_enabled": false,
  "bypass_threshold": 0.85,
  "bypass_percentage": 1.0,
  "never_bypass_list": ["onboard_new_employee"]
}
FieldDescription
shadow_enabledExecute in shadow mode (observe without acting)
bypass_thresholdMinimum confidence to bypass governance gate
bypass_percentagePercentage of requests allowed to bypass
never_bypass_listUse case IDs that always require human approval

GET/api/v1/intent/patterns/export

Export full pattern library and routing policies as a portable JSON backup.

Query params: ?org_id=org_test_001


POST/api/v1/intent/patterns/import

Restore a previously exported pattern library and policies.

Request body:

json
{
  "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.


POST/api/v1/pilot/track

SDK posts telemetry after every LLM call.

Headers: X-Supervea-Key: key_test_001

Request body:

json
{
  "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

json
{"status": "success", "event_id": "uuid"}

POST/api/v1/pilot/cache/lookup

High-speed Redis cache lookup for identical prompt contexts.

Request body:

json
{
  "org_id": "org_test_001",
  "messages": [{"role": "user", "content": "Summarize the report"}],
  "model": "gpt-4o-mini"
}

Response:

json
{"hit": true, "response": {...cached_response...}}

or

json
{"hit": false, "response": null}

Cache key is a SHA-256 hash of model + messages. TTL: 24 hours.


POST/api/v1/pilot/cache/store

Store a successful completion response in Redis.

Request body:

json
{
  "org_id": "org_test_001",
  "messages": [...],
  "model": "gpt-4o-mini",
  "response": {...completion_response...}
}

GET/api/v1/pilot/metrics/{org_id}

Aggregate pilot statistics for an organization.

Response:

json
{
  "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
}

GET/api/v1/pilot/report/{org_id}

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.


POST/api/v1/pilot/sandbox/execute

Execute a chat completion via the Supervea SDK caching layer (playground).

Request body:

json
{
  "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:

json
{
  "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

ColumnTypeDescription
idstring(36)Primary key
namestring(255)Organization name
plan_tierenum`free\starter\pro\enterprise`
api_keystring(128)API key for authentication
shadow_enabledboolShadow mode flag
bypass_thresholdfloatConfidence threshold to bypass governance
bypass_percentagefloat% of requests allowed to bypass
never_bypass_listJSON arrayUse case IDs always requiring human review
created_atdatetimeUTC

Task

ColumnTypeDescription
idstring(36)UUID primary key
org_idstring(36)FK → organizations
titlestring(512)Task title
descriptiontextOptional description
due_atdatetimeDeadline (UTC)
statusenum`open\in_progress\blocked\completed\cancelled`
priorityenum`low\medium\high\critical`
owner_idstring(36)FK → users (nullable)
dependenciesJSONList of task IDs
idempotency_keystring(128)Deduplication key
created_atdatetimeUTC
completed_atdatetimeUTC, set on completion
sla_breachedboolSet by escalation worker
source_event_idstring(36)Meeting that spawned this task (nullable)

CalendarEvent

ColumnTypeDescription
idstring(36)UUID primary key
org_idstring(36)FK → organizations
titlestring(512)Event title
start_utcdatetimeStart time (UTC)
end_utcdatetimeEnd time (UTC)
attendeesJSONList of attendee IDs/emails
required_attendeesJSONSubset of attendees (hard blockers)
lockedboolPrevents deletion when true
series_idstring(36)Groups recurring instances (nullable)
rruletextRFC 5545 recurrence rule on template event
source_event_idstring(36)Parent meeting that spawned this (nullable)
resourcesJSONList of booked resource IDs
duration_minutesintEnforced meeting duration (nullable)
created_atdatetimeUTC

Resource

ColumnTypeDescription
idstring(36)UUID primary key
org_idstring(36)FK → organizations
namestring(255)Resource name (unique per org)
resource_typestring(64)e.g. room, equipment
capacityintMax users (null = unlimited)
metaJSONExtra attributes
activeboolSoft-delete flag

ResourceBooking

ColumnTypeDescription
idstring(36)UUID
resource_idstring(36)FK → resources
event_idstring(36)FK → calendar_events
org_idstring(36)Denormalised for fast queries
start_utcdatetimeMirrors event start
end_utcdatetimeMirrors event end
booked_atdatetimeWhen booking was created

Unique constraint: (resource_id, event_id) — idempotent booking per resource/event pair.


Proposal

ColumnTypeDescription
idstring(36)UUID
org_idstring(36)FK → organizations
signal_typestring(128)e.g. overdue_threshold_exceeded
signal_dataJSONRaw signal payload
goaltextHuman-readable goal
suggested_actionJSONStructured action dict
confidencestring(8)Stored as string, e.g. "0.87"
sourceenum`rule\ai\n8n`
statusenum`pending\approved\ignored\converted`
reviewed_atdatetimeWhen governance action taken
reviewed_bystringActor who reviewed
converted_entity_typestringtask or calendar_event
converted_entity_idstringID of created entity

IntentExecution

ColumnTypeDescription
idstring(36)UUID
org_idstring(36)Tenant scope
raw_intenttextOriginal natural language input
use_case_idstring(128)e.g. create_task
route_typestring(32)atomic or workflow
confidencefloatRouting confidence score
parametersJSONExtracted params snapshot
missing_paramsJSONList of missing param names
statusenum`triggered\skipped\failed\plan_blocked\shadowed`
n8n_execution_idstringID returned by n8n
error_detailtextError message if failed
latency_msfloatExecution latency
created_atdatetimeUTC

AuditLog

Append-only — rows are never updated or deleted.

ColumnTypeDescription
idintAuto-increment PK
org_idstring(36)Tenant scope
entity_typestring(64)e.g. task, calendar_event
entity_idstring(36)ID of the affected entity
actionstring(128)e.g. created, status_changed
actor_idstring(36)User who triggered the action
timestampdatetimeUTC
extra_dataJSONAdditional context

Error Reference

HTTP CodeWhen
400 Bad RequestMissing required parameters
401 UnauthorizedMissing API key on protected endpoint
403 ForbiddenInvalid API key, tenant mismatch, or plan tier insufficient
404 Not FoundResource, task, event, or org not found
409 ConflictDuplicate resource name, scheduling conflict, locked event, invalid state transition, blocking dependencies
422 Unprocessable EntityValidation error (invalid enum value, duration rule violation, missing required field)
429 Too Many RequestsWebhook rate limit exceeded (100/min per org)
500 Internal Server ErrorUnhandled exception (check server logs)
501 Not ImplementedFeature not available in demo mode

Error response format:

json
{
  "detail": "Human-readable error message or structured object"
}

For conflict errors, detail may be a structured object:

json
{
  "detail": {
    "message": "Event conflicts with existing events for required attendees.",
    "conflicts": [
      {"id": "...", "title": "...", "start_utc": "...", "end_utc": "..."}
    ]
  }
}