Last Frame API
POST /frame/last
About this tool
The Droid Apps FFmpeg `/frame/last` endpoint is purpose-built for teams that automate thumbnails, catalog shots, QA stills, and timeline posters from long-form video without hauling entire files through a browser upload. Instead of multipart forms, your integration sends compact JSON referencing a publicly reachable HTTPS `video_url` that our workers can fetch, decode once, seek near the trim end, and export a deterministic raster snapshot. Jobs are asynchronous: each POST returns task metadata with a stable status URL so you can poll until the image asset is downloadable, mirroring every other FFmpeg route in our catalog.
Because decoding happens on subscribed infrastructure, throughput and fairness are guarded by API keys tied to billing. Silent failures from private buckets are common in first integrations; URLs must resolve without cookies, signed query drift, or regional blocks. When you combine optional `epsilon`, `width`, and `height` hints, FFmpeg can converge faster on acceptable geometry; omit them and sensible defaults still produce a crisp frame, but explicit dimensions help when downstream templates expect exact pixels for social cards or preview grids.
This is not a consumer “free converter.” You are orchestrating cloud FFmpeg with the same discipline as any other microservice: version your payload schema, log task IDs, and retry only when the API reports retriable states. The UI form below mirrors the JSON contract so you can prototype requests before wiring server-side workers. Expect network latency between your storage and ours to dominate short jobs; very long sources may take longer simply because demuxing and seeking scale with container complexity rather than your JSON size.
Operational teams pair last-frame exports with cut, crop, and caption routes to build review pipelines: grab the closing still, auto-caption the same source, and ship both to CMS webhooks. Documents in the API reference spell out edge cases such as variable frame rate footage or HDR color metadata; read them alongside this page when planning compliance-friendly retention, since your subscription governs how long derived artifacts remain hot before you must re-fetch from your own archive.
Try it now
How it works
Authenticate and plan the payload
Attach your `X-API-Key` header from an active Droid Apps subscription. Build JSON with a public HTTPS `video_url` plus any optional geometry hints; no multipart uploads are accepted.
POST to `/frame/last`
Submit the JSON body to the API path. The response includes a task identifier and `status_url` pointing at the async job record our workers update as FFmpeg progresses.
Poll the task until completion
Use GET requests on the returned status URL (also with your API key) until the state transitions to a terminal success. Handle errors verbatim from the JSON body for observability.
Download the generated still
Successful tasks expose HTTPS download links for the rendered frame. Persist the file in your storage; do not treat our CDN copy as long-term archival unless your plan says otherwise.
Frequently asked questions
Why did my job fail with a URL error?
Our servers must download your video without logging in. Private links, expired signed URLs, or HTTP-only hosts fail. Put the file on a public HTTPS bucket and make sure the link stays valid until the job finishes.
Can I send the video file in the request body?
No. Send JSON with a video_url pointing to where the file is hosted. That keeps requests small and works the same way across all Droid Apps endpoints.
How is this different from grabbing a random thumbnail?
Last frame seeks near the end of the file and returns a still from the final moments, useful for end cards, preview images, and QC checks, not a frame from the middle.
What output format do I get?
You receive a JPEG image. Optional width and height resize the output; they do not add letterboxing automatically; crop separately if you need an exact aspect ratio.
My signed S3 URL expired before the job ran: what now?
Generate a new URL with enough lifetime for download plus processing, then submit a fresh job. Poll the status URL every few seconds until the image is ready.
How do I use the Last Frame API?
POST to /frame/last with a JSON body containing video_url and your X-API-Key header. The API returns a task_id; poll GET /task/{task_id} until status is "completed" to retrieve the download_url.
Via the REST API
curl -X POST https://droidapps.one/frame/last \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_KEY" \
-d '{
"video_url": "https://cdn.example.com/clip.mp4"
}'Via the MCP server (droidapps-ffmpeg)
const job = await mcp.callTool("submit_job", {
path: "/frame/last",
body: {
video_url: "https://cdn.example.com/clip.mp4"
}
})
// Returns: { task_id: "abc123", status: "queued" }
const result = await mcp.callTool("wait_for_task", {
task_id: job.task_id
})
// Returns: { status: "completed", download_url: "https://..." }