Neurall

YouTube Thumbnail

imageimage/youtube-thumbnail

Paste the video link. We read the video itself and stage a thumbnail about it, starring a real face.

Their photoTheir photoThe thumbnail it staged for the videoThe thumbnail it staged for the video

You give the video and a style; the server reads the page for the title and subject, then composes the layout, the legibility rules and the face-fidelity clauses itself. Your prompt only says how it should look.

Billed per image. $0.15, which covers reading the video as well as the render. Live rate from GET /v3/pricing.

A complete call

A thumbnail for a published video, starring one person.

1Upload the faces

Send every person or product the composition expects in one POST /v3/files/upload. Skip it entirely for no-person.

curl -X POST "https://api.neurall.io/v3/files/upload" \
  -H "Authorization: nl-YOUR_API_KEY" \
  -F "files=@face.jpg"

It answers with the file ids

{
  "files": [
    {
      "id": "f_9c21e0b4",
      "originalName": "face.jpg",
      "size": 690455
    }
  ]
}

2Submit the render

POST /v3/generations with the video link, the style and the ids from step 1.

curl -X POST "https://api.neurall.io/v3/generations" \
  -H "Authorization: nl-YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "feature": "image/youtube-thumbnail",
    "args": {
      "videoUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
      "prompt": "High-contrast tech review look: deep blue background, hard rim light, one bold accent color, generous negative space for a short headline.",
      "composition": "person",
      "images": [
        "f_9c21e0b4"
      ],
      "expressions": [
        "excited"
      ]
    }
  }'

It answers immediately

{
  "generation": {
    "id": "7d31…",
    "feature": "image/youtube-thumbnail",
    "kind": "image",
    "status": "pending"
  }
}

3Poll until it lands

Poll GET /v3/generations/{id}, or pass webhookUrl and skip polling.

# repeat every 2s or so until status is done, error or timeout
curl "https://api.neurall.io/v3/generations/9f2c1d84-6a3b-4f21-9c77-2f0a1b8e5d43" \
  -H "Authorization: nl-YOUR_API_KEY"

Once status is done

{
  "generation": {
    "status": "done",
    "output": {
      "image": "https://cdn.neurall.io/…/image.png",
      "mime": "image/png"
    }
  }
}

output holds the finished asset on a signed CDN URL. Download it rather than hotlinking: API-created outputs expire 24 hours after the request.

Arguments

videoUrlstring
The video the thumbnail is for. We fetch it and read the title and topic. Send this OR videoDescription, never both.
  • A well-formed http(s) URL. Sending both videoUrl and videoDescription is a 400.
videoDescriptionstring
What the video is about, when it is not published yet. The alternative to videoUrl.
  • At most 2000 characters.
promptstringrequired
The creative STYLE only: palette, energy, treatment. Layout, legibility and fidelity clauses are appended server-side.
  • At most 2000 characters.
composition'person' | 'two-people' | 'person-product' | 'product' | 'two-products' | 'no-person'defaults to 'person'
What is in the frame. It decides how many reference images the render expects.
imagesarray
The references, in the order the composition implies. Each entry is a plain file id from POST /v3/files/upload.
  • PNG, JPEG, WebP, GIF, HEIC or AVIF, up to 30 MB and 30 megapixels per file, 10 files per upload request.
  • An uploaded file is deleted 24 hours after it lands, so upload again for a later render rather than caching an id.
  • The count must match the composition: person takes one, two-people takes two, no-person takes none.

How the prompt refers to these

args.images[0]The person, or the first person
Say "the person" if the prompt needs to mention them at all. Do not describe their face; it is preserved from the photo.
args.images[1]The second person, or the product
On two-people this is the second face; on person-product it is the product. Refer to it as "the product" and the render maps that to this slot.
expressionsstring[]
One expression per person in the composition, in the same order as images.
brandobject
Brand kit values, raw: background, text and accent are hex colors, all three required when brand is sent; name and voice (a short tone description) are optional strings; logo is an optional file id from POST /v3/files/upload (upload the logo file first); do not put it in images or count it in the composition, the server adds it after the reference photos and places it small in one corner.

An image you send but never mention still occupies its slot. Send only what the composition expects.

Output

Once status is done, the generation carries an output object with these fields. On any other status, output is absent.

imagestring
The finished thumbnail, as a URL.
  • A signed URL that expires 24 hours after the request (expiresAt on the generation). Download the file rather than hotlinking it.
mimestring
The image's MIME type, e.g. image/png.

Limits and failure

Video source
Exactly one of videoUrl or videoDescription.
Images
As many as the composition implies, 30 MB and 30 megapixels each, deleted 24 hours after upload.
Likeness
A real person in the frame requires their permission; the Terms of Use cover it, there is nothing to send.
Render time
A generation that has not finished in 15 minutes is marked timeout and refunded.
Concurrency
Your plan caps how many generations run at once. Over it the API answers 429 with a Retry-After header; wait that many seconds rather than retrying immediately.
Output lifetime
API-created outputs expire 24 hours after the request (expiresAt on the generation). Download the file rather than hotlinking it.
Deletion
DELETE /v3/generations/{id} removes the generation and its rendered assets immediately, rather than waiting for the 24 hour expiry. It does not refund anything and cannot cancel a render already in flight.
Failure
A failed or timed-out generation is refunded automatically.

Worth knowing

  • Reading the video happens server-side and is part of the price; you do not pass a transcript or a title.
  • The output is 16:9 by design. There is no ratio argument.