# info.description
Public Bevyl API surface: the user-scoped REST API (/api/v1), MCP clients, service health discovery, and partner workspace integrations.

# tags[].description
Authenticated Model Context Protocol transport.

# tags[].description
User-scoped REST API for OAuth-connected tools and workflow connectors.

# tags[].description
First-party mobile API authenticated with a Supabase user access token.

# tags[].description
Partner-scoped JSON API. Inbound requests use bearer API keys stored as SHA-256 hashes in `integration_partner_api_keys`; each request names a `workspaceId` authorized through `integration_partner_workspaces`. Outbound partner webhooks are signed separately with HMAC-SHA256 secrets from `integration_partner_secrets`.

# paths./api/v1/projects.post.description
Starts an asynchronous video generation for the connected workspace. Poll /api/v1/generations/{generationId} until completed.

# paths./api/v1/projects.post.requestBody.content.application/json.schema.properties.sourceVideoIds.description
Source video ids from video.upload.complete, video.list, or video.search.

# paths./api/v1/projects.post.requestBody.content.application/json.schema.properties.voiceoverProfileId.description
Optional voiceover profile id for voiceover projects.

# paths./api/v1/projects.post.requestBody.content.application/json.schema.properties.videoIdea.description
Optional edit instructions for Bevyl generation.

# paths./api/v1/projects.post.requestBody.content.application/json.schema.properties.lastInteractionId.description
Optional Gemini interaction id to continue from when generating the edit.

# paths./api/v1/projects.post.requestBody.content.application/json.schema.properties.auto_export.description
When true, start an MP4 export automatically after generation succeeds.

# paths./api/v1/projects.post.responses.422.description
Generation could not start (plan limits, invalid inputs).

# paths./api/v1/projects.post.responses.429.headers.Retry-After.description
Seconds until the current rate-limit window resets.

# paths./api/v1/projects.get.responses.429.headers.Retry-After.description
Seconds until the current rate-limit window resets.

# paths./api/v1/projects/{projectId}.get.responses.429.headers.Retry-After.description
Seconds until the current rate-limit window resets.

# paths./api/v1/generations/{generationId}.get.parameters[].description
Generation id returned by createProject.

# paths./api/v1/generations/{generationId}.get.responses.200.description
Generation status; includes the project once completed.

# paths./api/v1/generations/{generationId}.get.responses.429.headers.Retry-After.description
Seconds until the current rate-limit window resets.

# paths./api/v1/videos.get.description
Source videos in the connected workspace, newest first — footage available for createProject.

# paths./api/v1/videos.get.responses.429.headers.Retry-After.description
Seconds until the current rate-limit window resets.

# paths./api/v1/videos/import.post.responses.429.headers.Retry-After.description
Seconds until the current rate-limit window resets.

# paths./api/v1/imports/{importId}.get.responses.200.description
Import status; includes the video once completed.

# paths./api/v1/imports/{importId}.get.responses.429.headers.Retry-After.description
Seconds until the current rate-limit window resets.

# paths./api/v1/exports.post.responses.402.description
Export unavailable for the workspace plan.

# paths./api/v1/exports.post.responses.429.headers.Retry-After.description
Seconds until the current rate-limit window resets.

# paths./api/v1/exports.get.description
Sample-data feed for connector trigger tests. Payload shape matches the export.completed webhook; the export id is the dedupe key.

# paths./api/v1/exports.get.responses.429.headers.Retry-After.description
Seconds until the current rate-limit window resets.

# paths./api/v1/exports/{exportId}.get.responses.200.description
Export status; includes a signed download URL once completed.

# paths./api/v1/exports/{exportId}.get.responses.429.headers.Retry-After.description
Seconds until the current rate-limit window resets.

# paths./api/v1/webhooks.post.description
REST-hook subscribe endpoint for connector instant triggers. v1 supports export.completed only. The signing secret is returned only in this create response.

# paths./api/v1/webhooks.post.responses.400.description
Webhook target URL is invalid or not public.

# paths./api/v1/webhooks.post.responses.409.description
Account has reached the maximum active webhook subscriptions for this event.

# paths./api/v1/webhooks.post.responses.429.headers.Retry-After.description
Seconds until the current rate-limit window resets.

# paths./api/v1/webhooks.get.responses.429.headers.Retry-After.description
Seconds until the current rate-limit window resets.

# paths./api/v1/webhooks.delete.responses.429.headers.Retry-After.description
Seconds until the current rate-limit window resets.

# paths./api/mobile/v1/push-subscriptions.post.summary
Register the signed-in user push endpoint

# paths./api/mobile/v1/push-subscriptions.post.responses.200.description
The push endpoint is active for this installation.

# paths./api/mobile/v1/push-subscriptions.post.responses.401.description
The Supabase bearer token is missing or invalid.

# paths./api/mobile/v1/push-subscriptions.post.responses.429.description
The authenticated user exceeded the request limit.

# paths./api/mobile/v1/push-subscriptions.post.responses.429.headers.Retry-After.description
Seconds until the request may be retried.

# paths./api/mobile/v1/push-subscriptions/{installationId}.delete.summary
Disable push endpoints for this signed-in app installation

# paths./api/mobile/v1/push-subscriptions/{installationId}.delete.parameters[].description
Random app-installation UUID generated by the client.

# paths./api/mobile/v1/push-subscriptions/{installationId}.delete.responses.401.description
The Supabase bearer token is missing or invalid.

# paths./api/mobile/v1/push-subscriptions/{installationId}.delete.responses.429.description
The authenticated user exceeded the request limit.

# paths./api/mobile/v1/push-subscriptions/{installationId}.delete.responses.429.headers.Retry-After.description
Seconds until the request may be retried.

# paths./api/mobile/v1/workspaces.get.summary
List workspaces visible to the signed-in user

# paths./api/mobile/v1/workspaces.get.parameters[].description
Opaque cursor returned by the previous page.

# paths./api/mobile/v1/workspaces.get.responses.401.description
The Supabase bearer token is missing or invalid.

# paths./api/mobile/v1/workspaces.get.responses.429.description
The authenticated user exceeded the request limit.

# paths./api/mobile/v1/workspaces.get.responses.429.headers.Retry-After.description
Seconds until the request may be retried.

# paths./api/mobile/v1/videos.get.summary
List source videos in the selected workspace

# paths./api/mobile/v1/videos.get.parameters[].description
Opaque cursor returned by the previous page.

# paths./api/mobile/v1/videos.get.responses.200.description
Source videos and project-create readiness.

# paths./api/mobile/v1/videos.get.responses.400.description
The workspace header or list query is invalid.

# paths./api/mobile/v1/videos.get.responses.401.description
The Supabase bearer token is missing or invalid.

# paths./api/mobile/v1/videos.get.responses.403.description
The user cannot access the selected workspace.

# paths./api/mobile/v1/videos.get.responses.429.description
The authenticated user exceeded the request limit.

# paths./api/mobile/v1/videos.get.responses.429.headers.Retry-After.description
Seconds until the request may be retried.

# paths./api/mobile/v1/uploads/{uploadId}.get.summary
Read upload, processing, and resulting video status

# paths./api/mobile/v1/uploads/{uploadId}.get.parameters[].description
Server-minted tus storage key returned by the native uploader.

# paths./api/mobile/v1/uploads/{uploadId}.get.responses.400.description
The workspace header or list query is invalid.

# paths./api/mobile/v1/uploads/{uploadId}.get.responses.401.description
The Supabase bearer token is missing or invalid.

# paths./api/mobile/v1/uploads/{uploadId}.get.responses.403.description
The user cannot access the selected workspace.

# paths./api/mobile/v1/uploads/{uploadId}.get.responses.404.description
The upload was not found in the selected workspace.

# paths./api/mobile/v1/uploads/{uploadId}.get.responses.429.description
The authenticated user exceeded the request limit.

# paths./api/mobile/v1/uploads/{uploadId}.get.responses.429.headers.Retry-After.description
Seconds until the request may be retried.

# paths./api/mobile/v1/projects.get.parameters[].description
Opaque cursor returned by the previous page.

# paths./api/mobile/v1/projects.get.responses.400.description
The workspace header or list query is invalid.

# paths./api/mobile/v1/projects.get.responses.401.description
The Supabase bearer token is missing or invalid.

# paths./api/mobile/v1/projects.get.responses.403.description
The user cannot access the selected workspace.

# paths./api/mobile/v1/projects.get.responses.429.description
The authenticated user exceeded the request limit.

# paths./api/mobile/v1/projects.get.responses.429.headers.Retry-After.description
Seconds until the request may be retried.

# paths./api/mobile/v1/projects.post.requestBody.content.application/json.schema.properties.sourceVideoIds.description
Source video ids from video.upload.complete, video.list, or video.search.

# paths./api/mobile/v1/projects.post.requestBody.content.application/json.schema.properties.voiceoverProfileId.description
Optional voiceover profile id for voiceover projects.

# paths./api/mobile/v1/projects.post.requestBody.content.application/json.schema.properties.videoIdea.description
Optional edit instructions for Bevyl generation.

# paths./api/mobile/v1/projects.post.responses.400.description
The workspace header or list query is invalid.

# paths./api/mobile/v1/projects.post.responses.401.description
The Supabase bearer token is missing or invalid.

# paths./api/mobile/v1/projects.post.responses.403.description
The user cannot access the selected workspace.

# paths./api/mobile/v1/projects.post.responses.422.description
Project creation was rejected by account or generation guardrails.

# paths./api/mobile/v1/projects.post.responses.429.description
The authenticated user exceeded the request limit.

# paths./api/mobile/v1/projects.post.responses.429.headers.Retry-After.description
Seconds until the request may be retried.

# paths./api/mobile/v1/project-create-options.get.summary
Read project creation options for the selected workspace

# paths./api/mobile/v1/project-create-options.get.responses.200.description
Project creation limits and accessible voiceover profiles.

# paths./api/mobile/v1/project-create-options.get.responses.400.description
The workspace header or list query is invalid.

# paths./api/mobile/v1/project-create-options.get.responses.401.description
The Supabase bearer token is missing or invalid.

# paths./api/mobile/v1/project-create-options.get.responses.403.description
The user cannot access the selected workspace.

# paths./api/mobile/v1/project-create-options.get.responses.429.description
The authenticated user exceeded the request limit.

# paths./api/mobile/v1/project-create-options.get.responses.429.headers.Retry-After.description
Seconds until the request may be retried.

# paths./api/mobile/v1/projects/{projectId}.get.summary
Read a project in the selected workspace

# paths./api/mobile/v1/projects/{projectId}.get.responses.400.description
The workspace header or list query is invalid.

# paths./api/mobile/v1/projects/{projectId}.get.responses.401.description
The Supabase bearer token is missing or invalid.

# paths./api/mobile/v1/projects/{projectId}.get.responses.403.description
The user cannot access the selected workspace.

# paths./api/mobile/v1/projects/{projectId}.get.responses.404.description
The project was not found in the selected workspace.

# paths./api/mobile/v1/projects/{projectId}.get.responses.429.description
The authenticated user exceeded the request limit.

# paths./api/mobile/v1/projects/{projectId}.get.responses.429.headers.Retry-After.description
Seconds until the request may be retried.

# paths./api/mobile/v1/projects/{projectId}/timeline.get.summary
Read the canonical project timeline for the native editor

# paths./api/mobile/v1/projects/{projectId}/timeline.get.responses.200.description
Canonical editor timeline state and version.

# paths./api/mobile/v1/projects/{projectId}/timeline.get.responses.400.description
The workspace header or list query is invalid.

# paths./api/mobile/v1/projects/{projectId}/timeline.get.responses.401.description
The Supabase bearer token is missing or invalid.

# paths./api/mobile/v1/projects/{projectId}/timeline.get.responses.403.description
The user cannot access the selected workspace.

# paths./api/mobile/v1/projects/{projectId}/timeline.get.responses.404.description
The project was not found in the selected workspace.

# paths./api/mobile/v1/projects/{projectId}/timeline.get.responses.429.description
The authenticated user exceeded the request limit.

# paths./api/mobile/v1/projects/{projectId}/timeline.get.responses.429.headers.Retry-After.description
Seconds until the request may be retried.

# paths./api/mobile/v1/generations/{generationId}.get.responses.200.description
Generation job and completed project reference.

# paths./api/mobile/v1/generations/{generationId}.get.responses.400.description
The workspace header or list query is invalid.

# paths./api/mobile/v1/generations/{generationId}.get.responses.401.description
The Supabase bearer token is missing or invalid.

# paths./api/mobile/v1/generations/{generationId}.get.responses.403.description
The user cannot access the selected workspace.

# paths./api/mobile/v1/generations/{generationId}.get.responses.404.description
The generation was not found in the selected workspace.

# paths./api/mobile/v1/generations/{generationId}.get.responses.429.description
The authenticated user exceeded the request limit.

# paths./api/mobile/v1/generations/{generationId}.get.responses.429.headers.Retry-After.description
Seconds until the request may be retried.

# paths./api/mobile/v1/exports.post.responses.400.description
The workspace header or list query is invalid.

# paths./api/mobile/v1/exports.post.responses.401.description
The Supabase bearer token is missing or invalid.

# paths./api/mobile/v1/exports.post.responses.403.description
The user cannot access the selected workspace.

# paths./api/mobile/v1/exports.post.responses.404.description
The project was not found in the selected workspace.

# paths./api/mobile/v1/exports.post.responses.422.description
The export was rejected by account or project guardrails.

# paths./api/mobile/v1/exports.post.responses.429.description
The authenticated user exceeded the request limit.

# paths./api/mobile/v1/exports.post.responses.429.headers.Retry-After.description
Seconds until the request may be retried.

# paths./api/mobile/v1/exports.post.responses.502.description
The export row was created but the render task could not be dispatched.

# paths./api/mobile/v1/exports/{exportId}.get.summary
Read MP4 export status and signed media URLs

# paths./api/mobile/v1/exports/{exportId}.get.responses.200.description
Export status with separate signed playback and download URLs when complete.

# paths./api/mobile/v1/exports/{exportId}.get.responses.400.description
The workspace header or list query is invalid.

# paths./api/mobile/v1/exports/{exportId}.get.responses.401.description
The Supabase bearer token is missing or invalid.

# paths./api/mobile/v1/exports/{exportId}.get.responses.403.description
The user cannot access the selected workspace.

# paths./api/mobile/v1/exports/{exportId}.get.responses.404.description
The export was not found in the selected workspace.

# paths./api/mobile/v1/exports/{exportId}.get.responses.429.description
The authenticated user exceeded the request limit.

# paths./api/mobile/v1/exports/{exportId}.get.responses.429.headers.Retry-After.description
Seconds until the request may be retried.

# paths./api/mcp.post.description
Accepts JSON-RPC requests from authenticated Model Context Protocol clients over streamable HTTP.

# paths./api/health.get.responses.503.description
The API or database health check failed.

# paths./api/partner/v1/workspaces.post.description
Creates the customer account mapped to `workspaceId`. Repeating the request for an active workspace owned by the same partner is idempotent.

# paths./api/partner/v1/workspaces.post.responses.400.description
The JSON request body did not match the route contract, or the route rejected the parsed input.

# paths./api/partner/v1/workspaces.post.responses.401.description
The bearer API key is missing, unknown, or revoked.

# paths./api/partner/v1/workspaces.post.responses.403.description
The authenticated partner is not authorized for the requested workspace.

# paths./api/partner/v1/workspaces.post.responses.405.description
Only POST is supported for partner API routes.

# paths./api/partner/v1/workspaces.post.responses.409.description
The workspace identifier already belongs to another partner or a revoked workspace.

# paths./api/partner/v1/brand.post.description
Updates the active brand profile for the workspace mapped from `workspaceId`.

# paths./api/partner/v1/brand.post.responses.400.description
The JSON request body did not match the route contract, or the route rejected the parsed input.

# paths./api/partner/v1/brand.post.responses.401.description
The bearer API key is missing, unknown, or revoked.

# paths./api/partner/v1/brand.post.responses.403.description
The authenticated partner is not authorized for the requested workspace.

# paths./api/partner/v1/brand.post.responses.405.description
Only POST is supported for partner API routes.

# paths./api/partner/v1/projects.post.description
Creates a project from uploaded source videos and queues generation.

# paths./api/partner/v1/projects.post.responses.400.description
The JSON request body did not match the route contract, or the route rejected the parsed input.

# paths./api/partner/v1/projects.post.responses.401.description
The bearer API key is missing, unknown, or revoked.

# paths./api/partner/v1/projects.post.responses.402.description
The mapped workspace has no remaining generation access.

# paths./api/partner/v1/projects.post.responses.403.description
The authenticated partner is not authorized for the requested workspace.

# paths./api/partner/v1/projects.post.responses.405.description
Only POST is supported for partner API routes.

# paths./api/partner/v1/projects.post.responses.422.description
Project creation failed after request validation.

# paths./api/partner/v1/projects/status.post.description
Returns the latest generation run for a project, or a specific run when `runId` is provided.

# paths./api/partner/v1/projects/status.post.responses.400.description
The JSON request body did not match the route contract, or the route rejected the parsed input.

# paths./api/partner/v1/projects/status.post.responses.401.description
The bearer API key is missing, unknown, or revoked.

# paths./api/partner/v1/projects/status.post.responses.403.description
The authenticated partner is not authorized for the requested workspace.

# paths./api/partner/v1/projects/status.post.responses.404.description
No generation run exists for the requested project.

# paths./api/partner/v1/projects/status.post.responses.405.description
Only POST is supported for partner API routes.

# paths./api/partner/v1/videos/upload/prepare.post.description
Creates a partner-staged upload session and returns a signed PUT URL.

# paths./api/partner/v1/videos/upload/prepare.post.responses.400.description
The JSON request body did not match the route contract, or the route rejected the parsed input.

# paths./api/partner/v1/videos/upload/prepare.post.responses.401.description
The bearer API key is missing, unknown, or revoked.

# paths./api/partner/v1/videos/upload/prepare.post.responses.402.description
The mapped workspace has no remaining upload access.

# paths./api/partner/v1/videos/upload/prepare.post.responses.403.description
The authenticated partner is not authorized for the requested workspace.

# paths./api/partner/v1/videos/upload/prepare.post.responses.405.description
Only POST is supported for partner API routes.

# paths./api/partner/v1/videos/upload/complete.post.description
Finalizes an uploaded object and starts video processing for the mapped workspace.

# paths./api/partner/v1/videos/upload/complete.post.responses.200.description
Upload was already completed and the current video state is returned.

# paths./api/partner/v1/videos/upload/complete.post.responses.202.description
Upload was completed and video processing was queued.

# paths./api/partner/v1/videos/upload/complete.post.responses.400.description
The JSON request body did not match the route contract, or the route rejected the parsed input.

# paths./api/partner/v1/videos/upload/complete.post.responses.401.description
The bearer API key is missing, unknown, or revoked.

# paths./api/partner/v1/videos/upload/complete.post.responses.402.description
The mapped workspace has no remaining upload access.

# paths./api/partner/v1/videos/upload/complete.post.responses.403.description
The authenticated partner is not authorized for the requested workspace.

# paths./api/partner/v1/videos/upload/complete.post.responses.404.description
The upload session does not exist for this workspace.

# paths./api/partner/v1/videos/upload/complete.post.responses.405.description
Only POST is supported for partner API routes.

# paths./api/partner/v1/videos/upload/complete.post.responses.409.description
The upload object or session is not ready to complete.

# paths./api/partner/v1/videos/status.post.description
Returns processing state for a video in the mapped workspace.

# paths./api/partner/v1/videos/status.post.responses.400.description
The JSON request body did not match the route contract, or the route rejected the parsed input.

# paths./api/partner/v1/videos/status.post.responses.401.description
The bearer API key is missing, unknown, or revoked.

# paths./api/partner/v1/videos/status.post.responses.403.description
The authenticated partner is not authorized for the requested workspace.

# paths./api/partner/v1/videos/status.post.responses.404.description
No active video exists for this workspace.

# paths./api/partner/v1/videos/status.post.responses.405.description
Only POST is supported for partner API routes.

# paths./api/partner/v1/exports.post.description
Queues an MP4 export for a project in the mapped workspace.

# paths./api/partner/v1/exports.post.responses.400.description
The JSON request body did not match the route contract, or the route rejected the parsed input.

# paths./api/partner/v1/exports.post.responses.401.description
The bearer API key is missing, unknown, or revoked.

# paths./api/partner/v1/exports.post.responses.402.description
The mapped workspace has no remaining export access.

# paths./api/partner/v1/exports.post.responses.403.description
The authenticated partner is not authorized for the requested workspace.

# paths./api/partner/v1/exports.post.responses.404.description
The project does not exist in the mapped workspace.

# paths./api/partner/v1/exports.post.responses.405.description
Only POST is supported for partner API routes.

# paths./api/partner/v1/exports.post.responses.422.description
The project cannot currently be exported.

# paths./api/partner/v1/exports.post.responses.502.description
The export record was created but dispatch failed.

# paths./api/partner/v1/exports/status.post.description
Returns export readiness and download URLs for an export in the mapped workspace.

# paths./api/partner/v1/exports/status.post.responses.400.description
The JSON request body did not match the route contract, or the route rejected the parsed input.

# paths./api/partner/v1/exports/status.post.responses.401.description
The bearer API key is missing, unknown, or revoked.

# paths./api/partner/v1/exports/status.post.responses.403.description
The authenticated partner is not authorized for the requested workspace.

# paths./api/partner/v1/exports/status.post.responses.405.description
Only POST is supported for partner API routes.

# components.securitySchemes.supabaseBearerAuth.description
Supabase access token for the signed-in Bevyl user. Workspace routes also require X-Bevyl-Account-Id.

# components.securitySchemes.partnerApiKey.description
Partner API key sent as `Authorization: Bearer bvl_...`. The key authenticates the partner; the JSON body `workspaceId` authorizes the mapped workspace.