← Back to home

Cuevue API

Build integrations with the Cuevue REST API. Manage projects, workflow stages, custom fields, comments, subtasks, team members, and webhooks programmatically.

OpenAPI Spec→Base URL: https://cuevue.io/api/v1

Authentication

API and MCP access require a Studio plan. All API requests require a bearer token. Generate an API key from Settings → Integrations → API keys (Personal) in your workspace. Keys use the cue_sk_ prefix.

curl https://cuevue.io/api/v1/projects \
  -H "Authorization: Bearer cue_sk_your_key_here" \
  -H "X-Cuevue-Space: your_space_id"

Set X-Cuevue-Space to the Space you want to access. It can be omitted when the key has a bound default Space or exactly one allowed Space. Multi-Space keys without a default must include it.

Keys carry one of three permission tiers: read (browse everything), write (create and update content), and admin. Admin-grade operations — managing members, workflow stages, custom field definitions, and webhooks, plus deletes — require an admin key. A plain write key no longer performs admin operations.

Endpoints

All endpoints are relative to /api/v1. Request and response bodies use JSON.

Projects

GET/projects
POST/projects
GET/projects/:id
PATCH/projects/:id
DELETE/projects/:id
GET/projects/:id/files
PATCH/projects/:id/custom-fields
PATCH/projects/batch

Versions

GET/projects/:id/versions
POST/projects/:id/versions
POST/projects/:id/versions/import
POST/versions/:id/render

Comments

GET/projects/:id/comments
POST/projects/:id/comments
GET/projects/:id/comments/:commentId
PATCH/projects/:id/comments/:commentId
DELETE/projects/:id/comments/:commentId

Subtasks

GET/projects/:id/subtasks
POST/projects/:id/subtasks
GET/subtasks/:id
PATCH/subtasks/:id
DELETE/subtasks/:id

Workflow

GET/workflow
GET/workflow/stages
POST/workflow/stages
GET/workflow/stages/:id
PATCH/workflow/stages/:id
DELETE/workflow/stages/:id

Custom Fields

GET/fields
POST/fields
GET/fields/:id
PATCH/fields/:id
DELETE/fields/:id
PATCH/fields/reorder

Members

GET/members
POST/members
GET/members/:id
PATCH/members/:id
DELETE/members/:id

Webhooks

GET/webhooks
POST/webhooks
GET/webhooks/:id
PATCH/webhooks/:id
DELETE/webhooks/:id
GET/webhooks/:id/deliveries
POST/webhooks/:id/test

Space

GET/space

Pagination

List endpoints return cursor-based pagination. Pass limit (max 100, default 25) and use the returned cursor value to fetch the next page.

{
  "data": [ ... ],
  "pagination": {
    "cursor": "eyJ2IjoiMjAyNi0wMy0xMCIsImlkIjoiYWJjMTIzIn0",
    "has_more": true,
    "total": 142
  }
}

When has_more is false, you have reached the end. Pass sort and order to control sort direction.

Error handling

Errors return a consistent JSON envelope with an error object:

{
  "error": {
    "code": "validation_error",
    "message": "Invalid request body",
    "details": {
      "title": "Required"
    }
  }
}
StatusCode
400space_required / invalid_json
401unauthorized
403forbidden
404not_found
409conflict
422validation_error
429rate_limited
500internal_error

Rate limits

Reads and writes share one limit of 100 requests per minute per API key. Exceeding it applies a 30-second block. API-key authentication also limits each key-prefix/IP pair to 60 requests per minute, with a five-minute block when exceeded. Available response headers:

HeaderDescription
X-RateLimit-RemainingRequests remaining, when available on successful responses
Retry-AfterSeconds to wait after a 429 response

When rate limited, the response also includes retry_after_ms inside the error object. Wait before retrying; use backoff for repeated failures. Individual endpoints may return additional error codes.

Webhooks

Receive real-time notifications when events happen in your workspace. Register a webhook endpoint and subscribe to the events you need.

Available events

project.createdA project was created
project.updatedA project was updated
project.deletedA project was deleted
status.changedA project changed workflow stage
custom_field.updatedCustom field values changed
comment.createdA comment was added
comment.updatedA comment was updated
comment.deletedA comment was deleted
version.createdA new version was uploaded
version.updatedA version was updated
version.deletedA version was deleted
subtask.createdA subtask was created
subtask.updatedA subtask was updated
subtask.deletedA subtask was deleted
member.addedA member joined the space
member.removedA member was removed
marker.createdA marker was added
marker.updatedA marker was updated
marker.deletedA marker was deleted
document.createdA document was created
document.updatedA document was updated
document.deletedA document was deleted
review_link.createdA review link was created
review_link.revokedA review link was revoked

Payload format

{
  "id": "event_uuid",
  "type": "project.updated",
  "timestamp": "2026-03-26T14:30:00.000Z",
  "space_id": "uuid",
  "data": {
    "id": "project_uuid"
  }
}

Signature verification

Each webhook delivery includes a X-Cuevue-Signature header containing a hex HMAC-SHA256 signature, plus X-Cuevue-Timestamp (Unix seconds), X-Cuevue-Event and X-Cuevue-Delivery-Id. The signature covers the timestamp, a period, and the exact raw request body. Verify before parsing JSON or acting on the event, using the secret returned when you create the webhook. This Node.js example allows five minutes of clock skew:

import crypto from "crypto";

function verifyWebhook(body, signature, timestamp, secret, now = Date.now()) {
  if (typeof signature !== "string" || !/^[a-f0-9]{64}$/i.test(signature)) return false;
  if (typeof timestamp !== "string" || !/^[0-9]+$/.test(timestamp)) return false;
  const signedAt = Number(timestamp) * 1000;
  if (!Number.isSafeInteger(signedAt) || Math.abs(now - signedAt) > 300_000) return false;
  const expected = crypto
    .createHmac("sha256", secret)
    .update(timestamp + "." + body)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(signature, "hex"),
    Buffer.from(expected, "hex"),
  );
}

// rawBody is the untouched UTF-8 request body, before JSON parsing.
const valid = verifyWebhook(rawBody, request.headers.get("X-Cuevue-Signature"),
  request.headers.get("X-Cuevue-Timestamp"), signingSecret);

Reject invalid signatures and stale timestamps. After verification, deduplicate payload.id in durable storage before applying side effects: retries reuse that event ID. X-Cuevue-Delivery-Id also carries the event ID. Data fields vary by event type. Failed deliveries get up to five total attempts, with increasing delays. An endpoint is disabled after 50 consecutive failed attempts.

MCP integration

Cuevue supports the Model Context Protocol (MCP), allowing AI assistants and LLM-powered tools to interact with your workspace. The MCP server exposes resources, resource templates, prompts, and a broad set of tools that map to the REST API. Per-tool permission gating mirrors your key's tier: read tools browse, write tools mutate, and admin-grade tools (member, stage, custom-field definition, and webhook management, plus deletes) require an admin key or scope.

Connect your client

Pick your assistant for the exact config. Hosted clients (Claude.ai, ChatGPT) connect over OAuth with no key; desktop and SDK clients use a config snippet or API key.

On Claude.ai (Pro/Max/Team/Enterprise), open Settings → Connectors, click "Add custom connector", and paste this URL — then approve access. Claude Desktop uses the same Connectors flow. No API key needed either way.

Server URLURL
https://cuevue.io/api/mcp

No key to copy — you approve access on a consent screen, and the connection spans every space you can access.

Open Claude Connectors

Read-only keys can browse resources like cuevue://projects/recent, cuevue://workflow/stages, and templates such as cuevue://projects/{episode_id}.

Tool coverage

Tools span projects, subtasks, versions, transcripts (including word edits and speaker names), comments, markers, clips (create, render, and clip gain), audience stats, Megaphone export, playlists, automations, tabs, tags, version media (delivered as short-lived signed URLs), review links, files, documents, directory entries, custom fields, members, workflow, webhooks, and space config, plus list_spaces for discovery. High-cardinality lists are cursor-paginated. Directory listings may include people and bookmark information visible to space members.

MCP via OAuth

Hosted clients such as Claude.ai and ChatGPT can connect over OAuth 2.1 instead of a static key. Add Cuevue as a custom connector and point it at the MCP server URL:

https://cuevue.io/api/mcp

The client discovers authentication automatically — Cuevue serves RFC 9728 protected-resource metadata at /.well-known/oauth-protected-resource/api/mcp and supports dynamic client registration. On connect, you approve access on a consent screen; no key copy-paste is needed.

An OAuth connection spans all of your spaces. Every tool accepts an optional space_id; call list_spaces to discover the spaces you can target. Approved scopes follow the same read/write/admin tiers as API keys.