# SlicePost API and MCP

SlicePost's beta developer surface lets an approved workspace use the same projects, private media, allowances, and durable jobs as the web dashboard. It does not create a second balance or bypass the invite-only beta.

## Endpoints

- REST base: `https://www.slicepost.com/api`
- MCP Streamable HTTP: `https://www.slicepost.com/mcp/`
- Human documentation: `https://www.slicepost.com/docs`
- Markdown documentation: `https://www.slicepost.com/docs.md`

## Create and protect a key

Open **Account → Developer access → API keys**, choose a name, an available expiry (30, 90, or 365 days; 90 by default), and at least one permission, then create the key. You can create multiple keys for separate clients and revoke them individually. The list loads 50 keys at a time. The secret starts with `sp_beta_` and is shown once. Store it in a password manager or environment variable. Never commit it, paste it into prompts, expose it in browser code, or send it as a query string.

Every REST request uses:

```http
Authorization: Bearer $SLICEPOST_API_KEY
Accept: application/json
```

Keys remain bound to the person and workspace that created them. Removing beta access, suspending the workspace, expiring the key, or revoking it stops access immediately.

To rotate a key, create a replacement with the scopes your client needs, update that client's environment, verify a read request, then revoke the old key in Account. Lost secrets cannot be retrieved; create a replacement. Account key creation and revocation require a signed-in browser session, not another API key.

## Permissions

| Permission | Allows |
| --- | --- |
| `account:read` | Read workspace membership and allowance balances. |
| `projects:read` | Read owned projects, sources, assets, and download tickets. |
| `projects:write` | Create projects. |
| `media:write` | Reserve, complete, and remove private source uploads. |
| `jobs:read` | Read quotes, validated source metadata, processing requests, outputs, and job state. |
| `jobs:write` | Validate sources; start, rerender, transcribe, recreate, or cancel work. |

Publishing, social-account connection, billing, API-key management, beta diagnostics, and operator actions are not available to API keys or MCP. Those actions require the human web dashboard.

## REST quick start

These commands assume a shell with `SLICEPOST_API_KEY` already set. Use `caption_only` or `standalone` instead of `clipping` when creating those project types. Keep project names meaningful to your workspace.

Create a clipping project:

```bash
curl https://www.slicepost.com/api/projects \
  -H "Authorization: Bearer $SLICEPOST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"tool_type":"clipping","name":"Weekly podcast"}'
```

A successful create returns an `id` for subsequent project and upload calls. `GET /api/projects` returns a `projects` array. API responses may include more fields as the beta evolves; use the named fields you need rather than relying on object order.

### Common reads

| Method | Path | Purpose | Scope |
| --- | --- | --- | --- |
| `GET` | `/api/session` | Approved session and feature availability | `account:read` |
| `GET` | `/api/usage` | Allowance balances and unit scale | `account:read` |
| `GET` | `/api/projects` | Projects in the workspace | `projects:read` |
| `GET` | `/api/projects/{project_id}` | One owned project | `projects:read` |
| `GET` | `/api/projects/{project_id}/sources` | Source upload states | `projects:read` |
| `GET` | `/api/projects/{project_id}/jobs` | Source validation jobs | `jobs:read` |

UUIDs in paths are returned by the preceding create, upload, or queue response. A `404` may mean the ID is wrong or belongs to another workspace.

List projects:

```bash
curl https://www.slicepost.com/api/projects \
  -H "Authorization: Bearer $SLICEPOST_API_KEY"
```

Read allowance balances:

```bash
curl https://www.slicepost.com/api/usage \
  -H "Authorization: Bearer $SLICEPOST_API_KEY"
```

## Upload and process a source

1. `POST /api/projects/{project_id}/source-upload` with `filename`, exact `byte_size`, and `idempotency_key` in JSON.
2. Upload the bytes directly to the returned private R2 instructions. Large files use multipart instructions.
3. `POST /api/sources/{asset_id}/complete` or `/multipart-complete`.
4. `POST /api/sources/{asset_id}/validate` and poll `GET /api/jobs/{job_id}`.
5. Read trusted duration/FPS/codecs at `GET /api/sources/{asset_id}/metadata`.
6. Ask for a quote before any chargeable job.
7. Start the job with a stable `Idempotency-Key`, then poll its returned status resource.

Upload completion never starts paid work. Source validation establishes the trusted duration and media identity used by later quotes.

For example, reserve a single-file upload:

```bash
curl https://www.slicepost.com/api/projects/$PROJECT_ID/source-upload \
  -H "Authorization: Bearer $SLICEPOST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"filename":"episode.mp4","byte_size":12345678,"idempotency_key":"episode-upload-1"}'
```

The response contains `asset_id`, `state`, and an `upload` ticket. For a single-file ticket, send the **raw bytes** to its signed `url` using its `method` and required headers. For a multipart ticket, upload each returned part as instructed, then call `/multipart-complete`. Upload tickets are short lived and private; do not publish or log their URLs. If a transfer is interrupted, inspect `GET /api/sources/{asset_id}`. For a still-pending reservation, repeat the original `POST /api/projects/{project_id}/source-upload` body with the same `idempotency_key` to request a fresh ticket; an expired reservation cannot be renewed. Validation is asynchronous: poll the returned job until it reaches a terminal state before requesting metadata or a quote.

| Method | Path | Purpose |
| --- | --- | --- |
| `POST` | `/api/sources/{asset_id}/complete` | Verify one completed direct upload |
| `POST` | `/api/sources/{asset_id}/multipart-complete` | Finish a multipart upload |
| `POST` | `/api/sources/{asset_id}/multipart-abort` | Request multipart cleanup |
| `POST` | `/api/sources/{asset_id}/validate` | Queue codec and duration validation |
| `GET` | `/api/jobs/{job_id}` | Poll validation state |
| `GET` | `/api/sources/{asset_id}/metadata` | Read trusted media metadata |

## Clipping

```text
POST /api/sources/{source_id}/ai-analysis/quote
POST /api/sources/{source_id}/ai-analysis
GET  /api/ai-analysis/{request_id}
POST /api/ai-analysis/{analysis_id}/outputs/quote
POST /api/ai-analysis/{analysis_id}/outputs
GET  /api/ai-outputs/{request_id}
GET  /api/ai-outputs/{request_id}/assets
```

Clipping charges complete analyzed source minutes, rounded down. The initial clip batch and later edits/rerenders of those AI-origin clips are included. Estimated clip count is not a guarantee; the source, requested duration bands, usable moments, and 15-output cap determine the result.

Pass a JSON body such as `{"settings":{}}` to the analysis quote and queue endpoints. The quote checks the validated source and current allowances; it does not reserve work. The queue endpoint requires `Idempotency-Key` and returns `202` with `id` and `request`. Poll `GET /api/ai-analysis/{request_id}` until analysis completes before quoting and queueing outputs. Read `GET /api/ai-outputs/{request_id}/assets` only after the output request settles; individual clips can fail independently.

For a complete browser-independent Clipping run, also pass `visual_settings`
on analysis admission. The server validates and saves those render choices and
returns `background_clipping:true`; it queues the matching output itself.
`GET /api/clipping-runs/active` restores owned active runs, and
`GET /api/clipping-runs/{analysis_id}` reads their lifecycle and returned units.
The existing analysis/output cancellation endpoints now accept active Clipping
work. A `cancel_requested` receipt means stopping/refund is pending; `cancelled`
and `returned_units` confirm settlement. Fully completed runs reject cancellation.

## Caption Maker

```text
GET  /api/caption-presets
POST /api/sources/{source_id}/captions/quote
POST /api/sources/{source_id}/captions
GET  /api/caption-requests/{request_id}
```

Caption Maker uses caption/transcription minutes once per new source minute. Rendering and later revisions are included.

Create a `caption_only` project, validate its source, inspect `GET /api/caption-presets`, and quote the source. The queue endpoint accepts `{"settings":{}}` and an `Idempotency-Key`, returning `202` with an `id` and `request`. Poll the request, then use its published output asset's download endpoint when ready. Let the renderer's returned preset metadata guide settings; do not invent preset IDs.

## Clipping Editor and Recreate

The REST API exposes the dashboard's tenant-owned editor sessions, transcription quotes, saved-blueprint rerenders, AI-output opening, and default-off Recreate workflow under `/api/editor/*` and `/api/recreate/*`. Submit complete renderer-owned blueprints; partial or invented geometry is rejected. Editor transcription quotes only retained timeline media and cached coverage.

Editor REST entry points include `POST /api/editor/ai-outputs/{output_request_id}/clips/{clip_index}`, `POST /api/editor/projects/{project_id}/sessions`, `GET /api/editor/sessions/{document_id}`, `POST /api/editor/sessions/{document_id}/transcription-quote`, `POST /api/editor/sessions/{document_id}/transcribe`, and `POST /api/editor/sessions/{document_id}/re-render`. Standalone session creation needs an owned `source_asset_id`, `start_ms`, `end_ms`, and a stable body `idempotency_key`. An uploaded source can open a provisional full-source document; rendering and transcription wait for validation. Rerender needs the document's current `expected_revision`, complete `blueprint` and `transcript`, plus an `Idempotency-Key` header. A stale revision is a conflict; reload before retrying.

Recreate preserves dialogue timing and omissions from the reference while ordinary selected SlicePost framing modes own the new visual treatment. Existing saved legacy blueprints remain replayable.

Recreate is feature gated and may return `503` for your workspace. Validate both owned reference assets before requesting an export. Do not treat an accepted export as finished; poll its returned status.

## MCP setup

### Codex

Set `SLICEPOST_API_KEY`, then add this to `~/.codex/config.toml`:

```toml
[mcp_servers.slicepost]
url = "https://www.slicepost.com/mcp/"
bearer_token_env_var = "SLICEPOST_API_KEY"
```

### Claude Code

Place this `.mcp.json` in the project where you use Claude Code. It references the environment variable instead of writing your secret into a client command or shared file:

```json
{
  "mcpServers": {
    "slicepost": {
      "type": "http",
      "url": "https://www.slicepost.com/mcp/",
      "headers": {"Authorization": "Bearer ${SLICEPOST_API_KEY}"}
    }
  }
}
```

Restart or reconnect Claude Code after setting the variable. Keep the raw key out of terminal history and project files.

## MCP tools

The beta server exposes the following named tools. A client's tool list may be available even when a processing feature is disabled; that tool will report the workspace gate when called. Tool annotations identify reads, mutations, and destructive cancellation.

| Workflow | Tools |
| --- | --- |
| Workspace | `get_workspace`, `get_workflow_options`, `list_projects`, `get_project`, `create_project` |
| Media | `list_project_sources`, `prepare_source_upload`, `complete_source_upload`, `validate_source`, `get_source_validation_job`, `get_source_metadata`, `get_output_download` |
| Clipping | `quote_ai_clips`, `start_ai_clip_analysis`, `get_ai_clip_analysis`, `quote_ai_clip_outputs`, `render_ai_clip_outputs`, `get_ai_clip_outputs` |
| Caption Maker | `list_caption_styles`, `quote_caption_video`, `create_caption_video`, `get_caption_video`, `get_caption_transcript` |
| Editor | `open_ai_clip_in_editor`, `create_editor_session`, `get_editor_session`, `plan_editor_changes`, `get_editor_export`, `quote_editor_transcription`, `transcribe_editor_session`, `rerender_editor_session` |
| Recreate | `validate_recreate_sources`, `start_recreate_clip` |
| Job control | `cancel_job` |

The MCP server manages project and job calls; your client still has to transfer media bytes to the signed upload ticket. For uploads, use `prepare_source_upload` → transfer bytes → `complete_source_upload` → `validate_source` → poll `get_source_validation_job` → `get_source_metadata`. An upload preparation result is not an uploaded video. Retrieve finished files with `get_output_download(asset_id, workflow)`, using `clipping`, `caption_only`, or `standalone`. Tickets expire quickly; request a new ticket when needed rather than rerendering.

### Describe a clipping or caption job to an assistant

First call `get_workflow_options`: its feature flags, preset IDs, duration bands,
render modes, and defaults come from the application's current validators.
There are 28 caption presets, including `clean_2` and `graham_stephan`.
For clips shorter than one minute, select `under30`, `30-59`, or their combined
selection; `auto` can produce longer clips. Pass `mode: "split_screen_only"`
and `caption_pos: "bottom"` to the output-render step, with the chosen
`caption_preset`. Caption placement uses renderer anchors; visually review
the output if you need a precise lower-third position.

Caption-only processing uses `create_caption_video` with
`{"caption_preset":"graham_stephan","caption_pos":"bottom"}` after upload,
validation, and quotation. It captions the source without AI highlight selection.

A local filename is a client-side input, not a cloud asset ID. A desktop client
with file access transfers its bytes to R2; the hosted service never opens an
arbitrary Windows path. The hosted MCP does not currently offer a YouTube URL
ingestion tool. Do not tell the user a link was downloaded when no import ran.

The editor tools accept source ranges and complete saved blueprints, including
timed media cuts. `plan_editor_changes` (REST:
`POST /api/editor/sessions/{document_id}/plan` with `instructions`) previews
source-clock `keep_ranges`, literal `quoted_passage` selection, captions and
renderer-shaped `text_layers`. A unique quote creates a timed plan; ambiguous
quotes return candidates without an executable blueprint. Semantic passage
interpretation belongs to the assistant reading the transcript. The planner
preserves saved framing and never fabricates speaker-tracking geometry; a center
crop is not proof of tracking. Review the returned complete blueprint/transcript,
quote any needed work, then submit through `rerender_editor_session` using the
returned `expected_revision`. A plan itself never charges or starts a job.
For fresh AI clips, planning resolves the exact tenant-owned document's immutable
blueprint and transcript sidecars; a saved revision takes precedence. This may
read private storage, but never invokes transcription or rendering.

Batch social publishing remains unavailable to API keys/MCP. An agent must not
fall back to undocumented dashboard routes. A future posting integration must
bind approval to the exact selected account, files, copy, and dates. Use the
`America/Chicago` time zone for recurring Central-time schedules, including DST;
do not use a fixed UTC offset or change a scheduled retry into an immediate post.

Agents should follow this sequence:

1. Inspect the workspace and project.
2. Reuse an existing validated source when possible.
3. Quote chargeable work and tell the user the exact allowance impact.
4. Ask for confirmation before queueing costly or destructive work.
5. Use a stable idempotency key for every retry.
6. Poll the returned resource. Do not call a queued job complete early.
7. Return download tickets only to the requesting user; they are short lived.

## Idempotency, rate limits, and errors

Clipping, Caption Maker, and editor rerender queue endpoints require an `Idempotency-Key` header. Source upload reservation and standalone editor session creation take an `idempotency_key` in the JSON body. Reusing a key with the same request returns the original operation; reusing it with different inputs returns a conflict. Never generate a new key merely because a network response was lost.

SlicePost rate-limits reads, writes, uploads, and chargeable requests separately. A `429` response includes `Retry-After`. Back off instead of retrying in a tight loop.

Errors use JSON with a human-safe `detail` field. Common responses:

| Status | Meaning |
| --- | --- |
| `401` | Missing, malformed, expired, or revoked key. |
| `403` | Key lacks the required permission or beta access ended. |
| `404` | Resource does not exist or belongs to another workspace. |
| `409` | State, idempotency, allowance, or lifecycle conflict. |
| `422` | Invalid settings or request shape. |
| `429` | Rate limit reached; honor `Retry-After`. |
| `503` | Feature or dependency is not enabled/available. |

Every response is `Cache-Control: no-store` and includes `X-SlicePost-Request-ID` for support. Cross-workspace resources deliberately look missing rather than revealing that they exist.

### Troubleshooting a connection

| Symptom | Check |
| --- | --- |
| MCP client lists no SlicePost tools | Confirm the HTTPS URL ends in `/mcp/`, the environment variable is available to the client process, then reconnect or restart the client. |
| `401` on REST or MCP | Check the bearer prefix, the active key, expiry, and whether the client launched after its environment variable was set. Rotate a lost or revoked key. |
| `403` or MCP permission error | Create a replacement key with the required scope, update the client, then revoke the old key. Scopes on an existing key are not edited. |
| `404` for a known ID | Verify the project/source/request ID and the key's workspace. Cross-workspace IDs are intentionally hidden. |
| `409` during upload or processing | Read the current source/request state and reuse the same idempotency key for the same operation. Check the quote and available allowance. |
| `429` | Honor `Retry-After`, then retry with the same idempotency key where applicable. |
| `503` | The developer or processing feature may be disabled for this beta workspace; check Account and try later. |

Do not include keys, signed media URLs, or private source content when sharing a request ID with support.

## Current beta boundaries

- Developer access is available only to approved beta accounts and may be disabled independently.
- API/MCP uses the same monthly allowance and job queue as the dashboard.
- Maximum source is 10 GB and five hours; Clipping additionally requires at least three minutes.
- Media stays private and transfers through short-lived signed capabilities.
- Social publishing and billing remain human-only.
- A successful queue response means accepted, not completed.
- OAuth client authorization is not part of this personal-key beta. Revoke a key from Account if a client or machine is no longer trusted.
