Sell video

This page is for a provider that renders video. Use the reference agent if your upstream has the three OpenAI video routes below. Then register the deployment and test it.

Use an agent

A video job needs an agent. The OpenAI-compatible path does not carry video jobs, and the exchange sends them to the next offer.

A render takes minutes, and the buyer downloads the file later. The agent does three jobs that a plain API cannot do:

Choose one of two agents:

Choice Use it when
The reference provider agent Your upstream has the OpenAI video routes that this page describes. You write no code.
Your own agent Your upstream has other routes. Follow the Video section of the dispatch page and send video_ready yourself.

The rest of this page is for the reference agent.

Give the agent these routes

Set the base URL of your upstream in LIQUID_UPSTREAM_BASE_URL. The agent adds the paths below to it and sends your key as Authorization: Bearer <key>.

The agent calls Your answer
POST {base}/videos A JSON job with an id.
GET {base}/videos/{id} The job with its status.
GET {base}/videos/{id}/content The file, with a Content-Type that is video/*.

Create a job

The agent sends only the fields in this example.

{
  "model": "acme-video-1",
  "prompt": "A trading floor made of water",
  "seconds": "8",
  "size": "1280x720",
  "input_reference": { "image_url": "https://example.com/start.png" }
}
Field Value
model The upstream model of the deployment.
seconds A string, as in the OpenAI API.
size Present only when the buyer asked for a size.
input_reference Present only when the buyer gave a start image. See the rules below.

The agent sends at most one start image. It accepts an image with no frame type or with the frame first_frame. It fails the job for the frame last_frame.

Answer 2xx with a JSON body that has an id. A status that is not 2xx, or a body with no id, ends the attempt.

Report the status

The agent asks for the job at a fixed interval. The status must be one of these values:

status Meaning
queued The job waits. The agent asks again.
in_progress The job renders. The agent asks again.
completed The file is ready.
failed The job failed. Put the reason in error.message.

Any other value fails the job.

When the job is completed, you can add expires_at, in Unix seconds. It is the time when you delete the file.

Serve the file

The agent reads the headers of the file before it tells the exchange that the video exists. Then the buyer is charged. Make sure that GET {base}/videos/{id}/content works when the status is completed.

Bill fewer seconds

The agent charges the seconds that the buyer asked for. To charge fewer, add this header to the POST answer:

x-new-api-other-ratios: {"seconds": 6}

The agent rounds the value up. It never charges more seconds than the buyer asked for, because the exchange does not pay for them.

Frames and other references

The OpenAI video routes take one start image. The reference agent does not send a last frame, audio or a video reference on this route.

The exchange sends your deployment only the frames that you declared in supported_frame_images. Declare none that the route cannot read.

To read more, write your own agent. A part of the dispatch has frame_type when it is a frame image, and you map it to your upstream fields. See Frame images.

Declare the controls

A buyer's seed, creativity, upscale_factor and previous_job_id reach only an offer that declared video.seed, video.creativity, video.upscale_factor or video.continue. The first-party OpenAI adapter declares video.seed when the route has a seed rule. It declares no other video control. To sell the others, write your own agent. See Quote a media model.

Register the deployment

Register the deployment with kind set to video_generation. Make deployment_name and model equal, because the agent asks the upstream for that name. The lengths and sizes you list are the only ones that can win.

curl https://router.inference.ai.exchange/v1/provider/models \
  -H "Authorization: Bearer $LIQUID_PROVIDER_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"deployment_name":"acme-video-1",
       "model":"acme-video-1",
       "kind":"video_generation",
       "precision":"provider-managed","region":"us",
       "max_input_tokens":2000,"max_output_tokens":1,
       "output_modalities":[{"type":"video","seconds":[4,8],
                             "sizes":["1280x720"],"formats":["video/mp4"]}]}'

Register deployments lists every field.

Quote an output_video line in pricing for the deployment. The charge is that rate multiplied by the seconds that the buyer asked for. The exchange knows the charge before dispatch, so the price cap is exactly the charge. Quote a media model has an example with variants.

If your upstream lets the buyer choose the sound or the resolution, state audio and resolutions in the video output and quote output_video lines with a variant for the options that change the price. The buyer's choice is in audio and resolution of the video object of the dispatch. See Sound, resolution and price.

Continue a video

A buyer can send previous_job_id to continue an earlier video. Declare video.continue only if your upstream can do this.

Cancel and expiry

The exchange sends no cancel message. It closes the dispatch connection in these cases:

Watch for the close. When it comes, stop the work on your upstream if your upstream has a way to cancel. If it has none, you carry the cost of the render.

Start the agent

  1. Set LIQUID_UPSTREAM_BASE_URL and the key of your upstream.
  2. Set LIQUID_CONTENT_KEY to a stable secret. The agent signs the download token with it. Keep the same value after a restart. If the value changes, the buyer cannot download a video that is already paid for.
  3. Start the agent and wait for listed, then quote the deployment. See Run your agent.
  4. Keep the agent running for as long as your files stay on the upstream. The buyer downloads through the agent.

Limits and failures

Test before you quote

Run these calls against your upstream. Each one must give the answer that this page describes.

curl -s $BASE/videos -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
  -d '{"model":"acme-video-1","prompt":"test","seconds":"4"}'
curl -s $BASE/videos/$ID -H "Authorization: Bearer $KEY"
curl -sI $BASE/videos/$ID/content -H "Authorization: Bearer $KEY"

Then buy one video from your own deployment with a small price cap, and download it. The buyer's video guide shows the calls.