Skip to main content

Authentication

All webhooks are sent with a signature in the X-Mosaic-Signature header when you have a webhook secret configured. The signature is your webhook secret sent as a plaintext string for simple validation. Important: This is NOT encryption or hashing - it’s a direct plaintext string comparison for authentication.

Signature Validation Example

# Simple plaintext validation
webhook_signature = request.headers.get('X-Mosaic-Signature')
expected_secret = os.environ.get('MOSAIC_WEBHOOK_SECRET')

if expected_secret and webhook_signature != expected_secret:
    return {"error": "Invalid webhook signature"}, 401

Webhook Types

Mosaic sends two types of webhooks:
  1. RUN_STARTED - Sent when an agent run begins processing
  2. RUN_FINISHED - Sent when an agent run completes (successfully or with failures)

RUN_STARTED

Sent immediately when an agent run begins processing. This webhook includes information about all input videos being processed.

Payload Structure

{
  "flag": "RUN_STARTED",
  "agent_id": "123e4567-e89b-12d3-a456-789012345678",
  "run_id": "7f8d9c2b-4a6e-8b3f-1d5c-9e2f3a4b5c6d",
  "status": "running",
  "inputs": [
    {
      "video_url": "https://storage.googleapis.com/.../input.mp4",
      "thumbnail_url": "https://storage.googleapis.com/.../input-thumb.jpg"
    }
  ],
  "node_status_counts": {
    "completed": 1,
    "in_progress": 5,
    "failed": 0
  },
  "triggered_by": {
    "type": "youtube",
    "channel_id": "UCxxxxxxxxxxxxxx",
    "video_id": "dQw4w9WgXcQ",
    "video_title": "Never Gonna Give You Up",
    "video_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "triggered_at": "2024-01-15T10:30:00Z",
    "trigger_id": "8f7d6c5b-4a3e-2b1f-9d8c-1a2b3c4d5e6f"
  }
}

Field Descriptions

FieldTypeDescription
flag"RUN_STARTED"Webhook type identifier
agent_idstringUUID of the agent being executed
run_idstringUUID of the agent run (same as agent_state_id)
status"running"Current status of the run
inputsVideoInput[]Array of input videos being processed
node_status_countsNodeStatusCountsCounts of nodes in different statuses
triggered_byTriggerInfoOptional information about what triggered this run

RUN_FINISHED

Sent when an agent run completes processing (successfully or with failures). This webhook includes all final outputs produced by the run.

Payload Structure

{
  "flag": "RUN_FINISHED",
  "agent_id": "123e4567-e89b-12d3-a456-789012345678",
  "run_id": "7f8d9c2b-4a6e-8b3f-1d5c-9e2f3a4b5c6d",
  "status": "completed",
  "inputs": [
    {
      "video_url": "https://storage.googleapis.com/.../input.mp4",
      "thumbnail_url": "https://storage.googleapis.com/.../input-thumb.jpg"
    }
  ],
  "outputs": [
    {
      "video_url": "https://storage.googleapis.com/.../output.mp4",
      "thumbnail_url": "https://storage.googleapis.com/.../thumb.jpg",
      "completed_at": "2024-01-15T10:35:00Z"
    }
  ],
  "node_status_counts": {
    "completed": 10,
    "in_progress": 0,
    "failed": 0
  },
  "triggered_by": {
    "type": "youtube",
    "channel_id": "UCxxxxxxxxxxxxxx",
    "video_id": "dQw4w9WgXcQ",
    "video_title": "Never Gonna Give You Up",
    "video_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "triggered_at": "2024-01-15T10:30:00Z",
    "trigger_id": "8f7d6c5b-4a3e-2b1f-9d8c-1a2b3c4d5e6f"
  }
}

Field Descriptions

FieldTypeDescription
flag"RUN_FINISHED"Webhook type identifier
agent_idstringUUID of the agent that was executed
run_idstringUUID of the agent run (same as agent_state_id)
status"completed" | "partial_complete" | "failed"Final status of the run
inputsVideoInput[]Array of input videos that were processed
outputsVideoOutput[]Array of final output videos produced by the run
node_status_countsNodeStatusCountsCounts of nodes in different statuses
triggered_byTriggerInfoOptional information about what triggered this run

NodeStatusCounts Structure

FieldTypeDescription
completedintegerNumber of nodes that finished successfully (status: "completed", "partial_complete")
in_progressintegerNumber of nodes currently processing or waiting (status: "running", "queued")
failedintegerNumber of nodes that failed or are blocked (status: "failed", "blocked")
Triggered_by in RUN_STARTED and RUN_FINISHED is identical.
If a run is initiated manually via POST /agent/[agent_id]/run using a YouTube URL, triggered_by.type will still be "youtube", but trigger_id will be null because there is no saved channel-trigger configuration associated with the run.
In rare cases, triggered_by.channel_id may be null for manual YouTube runs if channel metadata is unavailable at run creation time. The webhook will still include video_id, video_title, and video_url.

Status Values

The status field can have the following values:
  • "completed" - All videos processed successfully with outputs generated
  • "partial_complete" - Some videos processed successfully, but others failed
  • "failed" - The entire run failed, no outputs generated