> ## Documentation Index
> Fetch the complete documentation index at: https://docs.poof.bg/llms.txt
> Use this file to discover all available pages before exploring further.

# Video background removal API

> Remove the background from MP4, MOV, WebM and animated GIF with one API call, up to 4K. Get transparent WebM, ProRes 4444, GIF or green screen MP4.

Poof removes the background from video with the same endpoint, the same API key and the same parameters as images. Send a clip to [`POST /remove`](/api-reference/remove-background#video) and Poof detects that it is a video, accepts it as a job and processes every frame in the background. Poll the job, then download the finished file from its `result_url`.

The matting model is the one used for images, with a motion-aware temporal stabiliser so the edges do not flicker from frame to frame. It works best on a clearly separated subject: people, products, pets, talking heads and social clips.

<Tip>
  **No code needed.** Upload a clip in **Studio** at [dash.poof.bg](https://dash.poof.bg), or ask Claude, ChatGPT or Cursor through the [MCP server](/integrations/mcp) (`remove_video_background`). Both use your Poof credits.
</Tip>

## How it works

1. **Submit** the video with `file` (upload, up to 100 MB) or `url` (public `https` link, up to 500 MB). The response is `202 Accepted` with a [job](/api-reference/jobs) that already tells you the clip's duration and the credits charged.
2. **Poll** `GET /jobs/{id}` every 2 to 5 seconds until `status` is `completed` or `failed`. Polling is free and not rate limited.
3. **Download** `result_url`. It is a direct CDN link that needs no API key and stays valid for 24 hours (`expires_at`).

<CodeGroup>
  ```bash cURL theme={null}
  # 1. Submit (the response is the job as JSON; note the "id")
  curl -X POST https://api.poof.bg/v1/remove \
    -H "x-api-key: YOUR_API_KEY" \
    -F "file=@clip.mp4" \
    -F "format=webm"

  # 2. Poll until "status" is "completed"
  curl https://api.poof.bg/v1/jobs/job_8f3a1c2e9b7d4a10 \
    -H "x-api-key: YOUR_API_KEY"

  # 3. Download "result_url" (no API key needed)
  curl -o clip-no-bg.webm \
    https://cdn.poof.bg/1d/jobs/job_8f3a1c2e9b7d4a10/result.webm
  ```

  ```python Python theme={null}
  from poof import Poof

  client = Poof(api_key="YOUR_API_KEY")

  job = client.remove_background("clip.mp4", format="webm")  # returns a Job
  job = client.wait_for_job(job, on_progress=lambda j: print(f"{j.progress:.0%}"))
  client.download(job, "clip-no-bg.webm")
  ```

  ```typescript TypeScript theme={null}
  import { Poof, isJob } from '@poof-bg/js';
  import fs from 'node:fs/promises';

  const poof = new Poof({ apiKey: 'YOUR_API_KEY' });

  const submitted = await poof.removeBackground('clip.mp4', { format: 'webm' });
  if (isJob(submitted)) {
    const job = await poof.waitForJob(submitted);
    const video = await fetch(job.resultUrl!);
    await fs.writeFile('clip-no-bg.webm', Buffer.from(await video.arrayBuffer()));
  }
  ```
</CodeGroup>

The SDK examples need `poofbg` 0.3.0 or later and `@poof-bg/js` 1.2.0 or later. The [API reference](/api-reference/remove-background#video-examples) has the same flow with plain `requests` and `fetch`.

## Pick an output

| You need | Request | Guide |
| - | - | - |
| A transparent video for a website or app | `format=webm` (default) | [Transparent video](/guides/transparent-video) |
| A transparent clip for Premiere, Final Cut, DaVinci Resolve or After Effects | `format=mov` (ProRes 4444) | [Transparent video](/guides/transparent-video#prores-4444-for-video-editors) |
| A green screen, or the subject on any solid colour | `format=mp4` + `bg_color=#00ff00` | [Green screen video](/guides/green-screen-video) |
| A looping transparent GIF for stickers, chat or email | `format=gif` | [Transparent GIF](/guides/transparent-video#transparent-gif) |
| Only the matte, for your own compositing | `channels=alpha` (add `format=mp4` for the smallest file) | [Alpha matte video](/api-reference/remove-background#alpha-matte-video) |

The [output formats table](/api-reference/remove-background#output-formats) lists the codec, alpha and audio for every `format` and `channels` combination.

## Limits

| | |
| - | - |
| Input formats | MP4, MOV, WebM, M4V, MKV, animated GIF |
| Duration | Up to 5 minutes |
| File size | 100 MB via `file`, 500 MB via `url` |
| Output resolution | Source resolution up to 4K (4096 px on the longest side); GIF output up to 720p (1280 px) |
| Frame rate | Kept from the source (GIF output: up to 50 fps) |
| Audio | Kept, except for an alpha matte (`channels=alpha`) and GIF output |

Use `size` to make the output smaller. For video it caps the longest side: `preview` 640 px, `medium` 1280 px, `hd` 1920 px (1080p), and `full` (the default) keeps the source resolution up to 4096 px. The aspect ratio is kept and nothing is upscaled. 4K jobs take about 1.5 times as long as 1080p, so pass `size=hd` when you do not need 4K. 4K files are large: send them by `url` (up to 500 MB) rather than as an upload. `crop`, `padding`, `width`, `height` and `fit` are image-only and are rejected for video.

## Credits

| Source frame rate | Cost |
| - | - |
| Up to 30 fps | 5 credits per second of video |
| Above 30 fps | 10 credits per second of video |

The duration is rounded up to the next whole second, so the minimum is 5 credits. A 12.4 second clip at 29.97 fps costs 65 credits. The charge does not depend on `format`, `channels`, `size` or resolution: 4K costs the same as 1080p. The free plan's 100 monthly credits cover 20 seconds of video.

Credits are charged when the job is accepted, and the `202` response shows the exact amount. A failed job is refunded automatically, and rejected requests (`4xx`) are never billed.

## Processing time and queueing

Jobs run on a shared GPU pool and you can submit several at once. When the pool is busy a job waits in `queued` with `progress` at `0` before it starts, so allow for that in your timeouts: the SDK helpers wait up to 10 minutes by default. See [Queueing](/api-reference/jobs#queueing).

## Errors

| Code | When |
| - | - |
| [`video_too_large`](/errors/video-too-large) | The upload is over 100 MB (or the URL over 500 MB) |
| [`video_too_long`](/errors/video-too-long) | The clip is longer than 5 minutes |
| [`invalid_video`](/errors/invalid-video) | The file could not be decoded as a video |
| [`validation_error`](/errors/validation-error) | An image format such as `png`, or an image-only parameter, was sent with a video |
| [`job_not_found`](/errors/job-not-found) | The job id is wrong, or the job expired 24 hours after it finished |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.