When to use this
An image prompt is a question that shows the candidate an image while they record their video answer. Use it when you want candidates to react to something visual: a system architecture diagram, a chart, a design mockup, or a product photo. See Image Prompt Questions for how it looks in the dashboard. Through the API, an image prompt is a regularQA step with questionFormat.image set. The candidate still answers on video, so answerFormat.video is required as usual.
Before you start
Don’t forget to send your Hireflix API Key in theX-API-KEY header to https://api.hireflix.com/me.
Check the image first:
- File type – any
image/*MIME type: JPEG, PNG, GIF, WebP, or SVG. Anything else is rejected withMediaFileUploadMimeTypeNotSupportedError. - File size – 10 MB max per image, which is exactly 10,000,000 bytes. Note this is a decimal megabyte, unlike the 150 MB video limit (157,286,400 bytes). Larger files are rejected with
MediaFileUploadTooBigError. - Dimensions – no width or height limit.
How image uploads differ from video uploads
Videos and images are uploaded in completely different ways, so don’t reuse the video flow from Creating a Position.How a multipart upload works
A normal GraphQL request is a JSON body. JSON can’t carry a binary file, so the API follows the GraphQL multipart request spec: instead of JSON, you send amultipart/form-data request (the same format a browser uses for an HTML form with a file input) made of three parts.
1
operations: the mutation, with a placeholder for the file
A form field named
operations that holds the JSON you’d normally send as the request body: query plus variables. Declare the file as a variable of type Upload! and set its value to null. The null is a placeholder that the server replaces with the uploaded file.2
map: which file goes where
A form field named This reads as: “put the file from form field
map that tells the server which file part fills which variable. The key is the name of the file part ("0"), and the value is a list of paths into operations.0 into variables.image”. The path matches the variable name you declared in step 1. The mutation wraps that variable in a list itself (upload: [$image]), so the path doesn’t need a list index.3
The file itself
A file part whose name matches the key in
map (here 0), containing the raw image bytes and an image/* content type.Create a position with an image prompt
This is the full mutation used in every example below. It creates a position with one image prompt question:- questionFormat.image.upload – the image file, passed as an
Upload!variable. Always exactly one. - answerFormat.video – required, because video is currently the only answer format.
{}uses the position defaults; see Creating a Position for the available settings. - title / description – same as any other question. The image is shown alongside them.
- curl
- Node.js
- Python
Save the Then send the three parts, in order:
operations JSON to a file, since the query is awkward to escape inline:operations.json
operations=<operations.jsonreads the file’s contents into a text field. Don’t use@here.0=@diagram.pngattaches the image as a file part named0, matching the key inmap.;type=image/pngsets the file’s content type. Change it to match your image (image/jpeg,image/webp, …).-Fmakes curl sendmultipart/form-dataand set theContent-Typeheader with the boundary, so don’t add one yourself.
Reuse an image with mediaIds
Every uploaded image gets a media ID. To use the same image in another question or position, pass that ID inmediaIds instead of uploading the file again. No upload means no multipart request: this is a normal JSON request.
Fetch the media ID of an image that’s already on a position. Replace <position-id> with the ID of the position that has the image, for example the data.id returned when you created it:
AdminQAImageContent, and images[].id is the media ID. Video questions come back as AdminQAVideoContent, and text-only questions have questionFormat: null.
Then reference it in mediaIds:
- Use either
uploadormediaIdsin one question, with one image in total. - The ID must belong to an image. A video’s media ID returns
MediaMimeTypeMismatchError. - The 10 MB limit applies to existing media as well.
Image questions in updatePosition
updatePosition accepts the same questionFormat.image input, with both upload and mediaIds. To add a new image question to an existing position, send the same multipart request as above, but with updatePosition and a $image: Upload! variable.
This example keeps an existing image question and adds a new one with a freshly uploaded image, in a single multipart request (map stays {"0": ["variables.image"]}):
Handling the response
createPosition and updatePosition return a union type. For image questions, these are the cases to handle:
MutationCreatePositionSuccess/MutationUpdatePositionSuccess– the position was saved; read it fromdata.ValidationError– one or more fields failed validation; inspectfieldErrorsfor the offendingpathandmessage.MediaFileUploadTooBigError– the uploaded image is over 10,000,000 bytes. For example:File "big.png" exceeds maximum allowed size of 10000000 bytes.MediaFileUploadMimeTypeNotSupportedError– the file part’s content type isn’timage/*. For example:File "diagram.webp" has unsupported mime type "application/octet-stream". Supported types are: image/*. If the file really is an image, set its content type explicitly (see How a multipart upload works).MediaNotFoundError– a media ID inmediaIdsdoesn’t exist or doesn’t belong to your company.MediaMimeTypeMismatchError– a media ID inmediaIdsisn’t an image.
operations sent as a file) fails before GraphQL runs, and returns a plain JSON object with a message such as Misordered multipart fields; files should follow 'map' instead of a data object.
Key reminders
- One image per question. The schema accepts up to 10, but candidates only see the first one. Use one image prompt question per image.
- Images are uploaded inside the mutation request as
multipart/form-data, not through a reserve/presigned-URL flow like videos. - Part order:
operations,map, then the file.operationsandmapare text fields. - Set the file’s content type explicitly to an
image/*type. Don’t set the request’sContent-Typeheader yourself. - Max 10 MB (10,000,000 bytes) per image, any
image/*type, no dimension limit. answerFormat.videois required on every image question.- Reuse images with
mediaIds, and always resendquestionFormatfor existing image questions inupdatePosition, or the image is dropped. - Verify the result by opening admin.hireflix.com/jobs, finding the position by name, and previewing the interview.
Learn next?
Need to create many positions at once? Let’s learn how to bulk-create positions with a script.

