Back to API Reference
POST/api/v1/images/generate-headshots

Generate Headshots

Submit a set of portrait photos to generate 60 professional AI headshots. The job runs asynchronously and delivers results to your callback URL when complete.

This is an async endpoint. You will receive an immediate response with a headshots_id, and your callback URL will be called with the 60 generated images once processing is complete (estimated 1–2 hours).

Prompt for Vibe Coder

Skip the docs — paste this prompt into your AI agent and let it handle the integration.

Base URL

https://api.runflow.io

Authentication

Include your API key in the request header:

HeaderTypeRequiredDescription
x-api-keystringYesYour Runflow API key

Request Body

You can send input images in one of two ways. callback_url is required in both cases.

Option 1File Uploadmultipart/form-data
FieldTypeRequiredDescription
callback_urlstringYesURL that receives the completed headshots webhook
imagesFile[]YesOne or more image files (JPEG, PNG, WebP). Send as repeated form fields.
Option 2JSON Bodyapplication/json
FieldTypeRequiredDescription
callback_urlstringYesURL that receives the completed headshots webhook
input_imagesstring[]YesArray of publicly accessible image URLs

Examples

bash
curl -X POST https://api.runflow.io/api/v1/images/generate-headshots \
  -H "x-api-key: YOUR_API_KEY" \
  -F "callback_url=https://yourapp.com/webhook/headshots" \
  -F "images=@/path/to/photo1.jpg" \
  -F "images=@/path/to/photo2.jpg" \
  -F "images=@/path/to/photo3.jpg"

Response

Returns immediately with a headshots_id to track the job. Processing runs in the background.

json
{
  "success": true,
  "data": {
    "headshots_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }
}
FieldTypeDescription
successbooleantrue when the job was accepted successfully
data.headshots_idstring (UUID)Unique identifier for this headshot generation job

Webhook Callback

When all 60 headshots are ready (estimated 1–2 hours), Runflow will send a POST request to your callback_url with the following payload:

json
{
  "event": "headshots.completed",
  "headshots_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "image_urls": [
    "https://cdn.runflow.io/headshots/out_001.jpg",
    "https://cdn.runflow.io/headshots/out_002.jpg",
    "..."
  ]
}

The image_urls expire after 24 hours. Make sure your webhook handler saves the URLs to your own storage immediately upon receipt.

FieldTypeDescription
eventstringAlways headshots.completed
headshots_idstring (UUID)Matches the ID from the initial API response
image_urlsstring[]60 generated headshot URLs. Expire after 24 hours — store immediately.

Webhook handler example

javascript
// Example Express.js webhook handler
app.post("/webhook/headshots", async (req, res) => {
  const { event, headshots_id, image_urls } = req.body;

  if (event === "headshots.completed") {
    // Store image_urls immediately — they expire in 24 hours
    await db.saveHeadshots({ headshots_id, image_urls });
  }

  res.sendStatus(200);
});