# Add poster and preview images to video uploads [View original](https://ittybit.com/guides/add-poster-preview-images) ## The Workflow ### Overview I've been making videos for the internet for a realllly long time (like, way before YouTube was a thing). And pretty much every video in that time has needed a poster image (to show in the player before the video loads) and a preview image (a smaller thumbnail to show when listing videos). This workflow will generate both for you. *** ### Build Workflow Our workflow will: 1. Checks the input file is a video 2. Generate a 1280x720 poster image 3. Generate a 320x180 preview image 4. Send the output file data to a webhook URL on your server

A [workflow](/docs/workflows) is an array of task definitions that describe what should happen and in what order.

Tasks in the array run in parallel. You can also chain tasks together in sequences using the `next` property.

*** ### Create Task We create a new task with the `kind: "workflow"`. The `workflow` property contains our workflow steps as defined above. ```ts const task = await ittybit.tasks.create({ url: "https://example.com/your-video.mp4", kind: "workflow", workflow: workflow }) ``` ```python task = ittybit.tasks.create({ url="https://example.com/your-video.mp4", kind="workflow", workflow=workflow }) ``` ```ruby task = ittybit.tasks.create({ url: "https://example.com/your-video.mp4", kind: "workflow", workflow: workflow }) ``` ```php $task = $ittybit->tasks->create([ 'url' => "https://example.com/your-video.mp4", 'kind' => "workflow", 'workflow' => workflow ]); ``` ```go task, err := ittybit.Tasks.Create( context.TODO(), &ittybit.TaskCreateParams{ Kind: "workflow", URL: "https://example.com/your-video.mp4", Workflow: workflow }, ) ``` ```js const task = await fetch('https://api.ittybit.com/tasks', { method: 'POST', headers: { 'Authorization': `Bearer ${ITTYBIT_API_KEY}` }, body: JSON.stringify({ url: "https://example.com/your-video.mp4", kind: "workflow", workflow: workflow }) }) ``` *** ### Handle Webhook Your webhook handler should parse the [File Object](/docs/files) payload and save the data in your database. Optionally, you might want to pull the file itself into your object storage. *** ### Use the Output Your database should now have 3x files associated with the input video: * The original video file * The poster image file * The preview image file You can use them in your frontend to give a nicer user experience. ```html ``` *** ## Responsive Workflow The current workflow assumes input videos are landscape. It'll still work with portrait or square videos, but the output images will be too big. We can update our workflow to work with portrait and square videos responsively. We do this by updating our conditions to check the `orientation` property of the input file, and adding a second branch for portrait and square videos. *** ## Next Steps You can extend these workflow examples with your own task ideas and build something unique for your app. Check out the [Tasks](/docs/tasks) documentation for more information on what you can do.