---
title: Splice for developers and agents
description: "Connect to Splice over MCP, REST or the CLI: auth, errors, rate limits, idempotency, async jobs, pagination, versioning and pricing."
url: "https://splice.film.fun/developers.md"
canonical: "https://splice.film.fun/developers"
updated: 2026-10-07
api_version: 2026-10-01
---
# Splice for developers and agents

Splice is film.fun's AI filmmaking studio. Agents and scripts can do what the dashboard does: generate images, video, voice, music and sound; edit, upscale and reframe media; render motion graphics; and run the full idea-to-film pipeline. Everything is made on a user's Splice account and shows up in their dashboard.

There are three ways in: a **remote MCP server** (best for AI assistants), a **REST API** (best for scripts and backends) and a **CLI**. All three use the same accounts, credits and prices.

## When to use Splice

Use Splice when a task needs:

- generated media (image, video, voice, music, sound effects) with a choice of current models and a known price per generation;
- edits to existing media: image edits, upscaling, video reframing to 9:16 / 1:1 / 16:9, clipping, merging, captions, lip sync, transcription;
- motion graphics (titles, lower-thirds, kinetic type) rendered to MP4;
- results kept in a project the user can open, edit and cut in the browser.

Don't use it for text-only tasks, or on behalf of someone who doesn't have (or want) a Splice account. Every generation spends that user's credits, so confirm the cost before an expensive run.

## Quickstart: MCP

The product MCP server is `https://splice.film.fun/api/mcp` (Streamable HTTP). It signs the user in with OAuth 2.1, or takes an agent key as `Authorization: Bearer sk_…`.

- **Claude Code:** `claude mcp add --transport http splice https://splice.film.fun/api/mcp`, then run `/mcp` and sign in. To use a key instead, add `--header "Authorization: Bearer sk_..."`.
- **claude.ai and Claude Desktop:** Settings → Connectors → Add custom connector, and enter `https://splice.film.fun/api/mcp`.
- **Cursor:** [Add to Cursor](https://cursor.com/en/install-mcp?name=splice&config=eyJ1cmwiOiJodHRwczovL3NwbGljZS5maWxtLmZ1bi9hcGkvbWNwIn0%3D), or add `{"mcpServers": {"splice": {"url": "https://splice.film.fun/api/mcp"}}}` to `~/.cursor/mcp.json`.
- **VS Code:** [Install in VS Code](https://vscode.dev/redirect/mcp/install?name=splice&config=%7B%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fsplice.film.fun%2Fapi%2Fmcp%22%7D), or run `code --add-mcp '{"name":"splice","type":"http","url":"https://splice.film.fun/api/mcp"}'`.
- **Any other client:** point a Streamable HTTP MCP client at `https://splice.film.fun/api/mcp`; it discovers OAuth from the 401.

Tools: `list_models`, `get_balance`, `list_productions`, `generate_image`, `generate_video`, `generate_voice`, `generate_music`, `edit_image`, `upscale_image`, `upscale_video`, `get_job`, `list_compositions`, `get_composition`, `render_composition`, `list_characters`. Read-only tools carry `readOnlyHint`; tools that spend credits are not idempotent unless you pass `idempotency_key`. Resources: `splice://models` (live prices) and `splice://docs/*`.

A **public docs server** needs no sign-in and spends nothing: `https://splice.film.fun/api/mcp/docs` (`search_docs`, `get_doc`, `list_models`, `get_pricing`, `list_templates`, `get_template`). Use it to look up models, prices and templates before connecting an account.

## Quickstart: REST

```bash
export SPLICE_API_KEY=sk_...        # from https://splice.film.fun/dashboard/api-keys
B=https://splice.film.fun/api/agents
H="Authorization: Bearer $SPLICE_API_KEY"

# 1. The default production (created on first call).
curl -s "$B/session" -H "$H"

# 2. Models and prices for a generator.
curl -s "$B/tools/generator-tools/video/models" -H "$H"

# 3. Start a generation. It returns 201 straight away.
curl -s -X POST "$B/generate/video" -H "$H" -H 'Content-Type: application/json' \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"production_id":"<production_id>","prompt":"A paper boat drifts down a rainy street, slow dolly","parameters":{"duration":5,"aspectRatio":"9:16"}}'

# 4. Poll until status is completed (media_url) or failed (error_message).
curl -s "$B/productions/<production_id>/items/<production_item_id>" -H "$H"
```

The CLI wraps all of this: `curl -fsSL https://splice.film.fun/cli/splice.mjs -o splice.mjs && node splice.mjs help` (Node 18+, no dependencies).

## Authentication

- **OAuth 2.1** for MCP connectors: dynamic client registration, PKCE (S256), scopes `splice:read` and `splice:generate`, rotating refresh tokens. Metadata: `https://splice.film.fun/.well-known/oauth-authorization-server` and `https://splice.film.fun/.well-known/oauth-protected-resource`.
- **Agent keys** (`sk_…`) for REST, the CLI and MCP-with-a-header. Create and revoke them at https://splice.film.fun/dashboard/api-keys. A key acts as the user who made it, and can be limited by scope and to one production.
- A request without valid credentials gets `401` with `WWW-Authenticate: Bearer resource_metadata="…"`, which points at the protected-resource metadata.

The step-by-step flow for agents is in [auth.md](https://splice.film.fun/auth.md).

## API reference

- [OpenAPI 3 spec](https://splice.film.fun/api/openapi), also browsable at [/api-docs](https://splice.film.fun/api-docs).
- [Agent manifest](https://splice.film.fun/api/agents/manifest.json): every `/api/agents/*` route with methods, scopes and error codes, kept in sync with the code by CI.
- [llms-full.txt](https://splice.film.fun/llms-full.txt): the complete reference, with request bodies and the planning pipeline.
- Public reads need no key: `GET /pricing.json`, `GET /api/public/generation-templates` and `GET /api/public/generation-templates/{slug}`.

## Errors

Every error from `/api/agents/*` is JSON with one envelope:

```json
{ "error": { "code": "insufficient_credits", "message": "Not enough credits.", "details": {} } }
```

`code` is a stable snake_case string: match on it, not on `message`. Some errors add fields beside `error` (`required`, `balance`, `shortfall`, `quote`, `payment_required`).

| Status | Common codes | What to do |
|---|---|---|
| 400 | `invalid_request`, `invalid_body` | Fix the request; `details` names the field |
| 401 | `unauthorized` | Send a valid key or token (see Authentication) |
| 402 | `insufficient_credits`, `payment_required` | Top up, then retry with the same Idempotency-Key |
| 403 | `forbidden` | The key or token lacks the scope in `details.required_scope` |
| 404 | `not_found` | The id isn't the caller's, or doesn't exist |
| 409 | `conflict`, `idempotency_in_progress`, `idempotency_outcome_unknown`, `quote_exceeds_max_credits`, `version_conflict` | See Idempotency, or re-read and retry |
| 415 / 422 | `unsupported_media_type`, `unprocessable_entity` | Send the content type and shape the route expects |
| 429 | `rate_limited` | Wait `Retry-After` seconds |
| 501 | `not_implemented` and feature codes (`cancel_unavailable`, `quote_unavailable`) | The feature is off; see `features` in the manifest |
| 502 / 503 / 504 | `upstream_error`, `service_unavailable`, `upstream_timeout` | Retry with backoff and the same Idempotency-Key |

An unknown `/api/*` path answers `404 {"error": {"code": "not_found", …, "docs_url": …}}`. Over MCP, a failed tool call is a tool result with `isError: true`; protocol mistakes are JSON-RPC errors.

## Rate limits

- `/api/agents/*`: 100 reads and 30 writes per minute per client IP. `/api/mcp`: 120 requests per minute per credential.
- Every API response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` (seconds). Over the limit you get `429` with `Retry-After`.
- Generation concurrency is capped per account: keep a handful of generations in flight, not hundreds.

## Idempotency

Send an `Idempotency-Key` header (any unique printable string, up to 255 characters) on every generate and edit call; over MCP, pass `idempotency_key`. A retry with the same key returns the first result and never charges twice. If the first request is still running you get `409 idempotency_in_progress`; if its outcome is unknown, `409 idempotency_outcome_unknown` (look it up with `GET /api/agents/idempotency/{key}` rather than retrying with a new key).

## Asynchronous jobs

Generation is asynchronous. A generate or edit call returns `201 {production_item_id, job_id?, production_id}` at once. Poll `GET /api/agents/productions/{production_id}/items/{production_item_id}` (MCP: `get_job`) every 5-10 seconds. `status` goes `pending` → `processing` → `completed` (read `media_url`, or `answer` for vision) or `failed` (read `error_message`; failed generations are refunded). Cancel a running one with `POST …/items/{itemId}/cancel`. Images take 5-30 s, video 1-5 minutes. There are no webhooks for agent calls.

## Pagination

List routes take `?limit=` and `?offset=` and return a `pagination` block:

```json
{ "pagination": { "limit": 50, "offset": 0, "returned": 50, "total": 120, "has_more": true, "next_offset": 50 } }
```

Fetch the next page with `?offset=<next_offset>`; it is `null` on the last page. Without a `limit`, routes that always returned everything still do. The maximum `limit` is 200.

## Batch and bulk

- `POST /api/agents/productions/{id}/shot-sheet/stills/all` and `…/shot-sheet/seedance/all`: stills or video for every shot in a shot sheet. They take `dry_run` and `max_credits`, reuse unchanged takes at 0 credits, and return `pending` when more remains (call again).
- `POST /api/agents/productions/{id}/variants`: A/B variants of a shotlist that each change one thing.
- `POST /api/agents/edit/image-multiple`: several image edits in one call.
- `POST /api/agents/productions/{id}/quote`: an itemised price for a multi-step job; spends nothing.

## Versioning and deprecation

- The agent API is versioned by date. The current version is `2026-10-01`, sent on every `/api/agents/*` response as `Splice-Api-Version`.
- Within a version, changes are additive only: new routes, new optional fields, new error codes. Clients must ignore fields they don't know.
- A breaking change ships as a new version. The old behaviour is kept for at least 90 days, and responses from deprecated routes carry `Deprecation` and `Sunset` headers (RFC 9745, RFC 8594) with a `Link` to the migration notes.
- Changes are announced in [llms.txt](https://splice.film.fun/llms.txt) and the [agent manifest](https://splice.film.fun/api/agents/manifest.json).

## Pricing and credits

Pay as you go, no subscription. Starter $10 = 1,000 credits · Creator $45 = 5,000 credits · Pro $99 = 11,500 credits · Studio $225 = 27,000 credits. New accounts get 100 free credits; credits don't expire. Model prices are dynamic: read them from [/pricing.json](https://splice.film.fun/pricing.json), `list_models` or `GET /api/agents/tools/generator-tools/{generator}/models`. Human version: [/pricing](https://splice.film.fun/pricing); markdown: [/pricing.md](https://splice.film.fun/pricing.md). Agents can top up with Solana Pay through `POST /api/agents/credits/purchase`.

## Sandbox and testing

There is no separate sandbox host: test against production with a new account.

- The 100 free sign-up credits cover a test integration (an image is about 6 credits; a 5-second default video about 30).
- Spend nothing while testing a pipeline: `POST …/quote`, and `dry_run: true` on the bulk routes, return prices without running anything.
- Cap spend with `max_credits` on bulk routes, and test Motion renders with `previewSeconds` (a short range at the lower preview price).
- The public docs MCP server and `/pricing.json` need no account at all.

## Status and support

- Health: `GET https://splice.film.fun/api/health` returns `{"status": "healthy", …}`.
- Support: support@film.fun. Security reports: see [security.txt](https://splice.film.fun/.well-known/security.txt).
- Splice is run by Automaton Limited (film.fun). [Terms](https://www.film.fun/terms) · [Privacy](https://www.film.fun/privacy).

## Machine-readable discovery

- [llms.txt](https://splice.film.fun/llms.txt) and [agents.md](https://splice.film.fun/agents.md)
- [MCP server card](https://splice.film.fun/.well-known/mcp/server-card.json) and [AI Catalog](https://splice.film.fun/.well-known/ai-catalog.json)
- [Agent Skills index](https://splice.film.fun/.well-known/agent-skills/index.json)
- [API catalog (RFC 9727)](https://splice.film.fun/.well-known/api-catalog) and [ARD manifest](https://splice.film.fun/.well-known/ard.json)
- Every docs page answers `Accept: text/markdown` with markdown.
