Skip to main content
Webhooks notify your server when a project’s status changes, eliminating the need to poll.

Setup

Set a webhook URL when creating a project or via settings:
{
  "brief": "Your brief here",
  "webhook_url": "https://your-server.com/webhooks/eversince"
}
Or add one to an existing project:
curl -X PATCH https://eversince.ai/api/v1/projects/proj_abc123/settings \
  -H "Authorization: Bearer $EVERSINCE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "webhook_url": "https://your-server.com/webhooks/eversince" }'
The URL must use HTTPS.

Events

Webhooks fire on these status transitions:
EventWhen
runningAgent started working
generatingWaiting for model outputs
idleWork complete. Result ready or awaiting feedback
failedSomething went wrong
renderingFinal video render in progress
Cancelled projects do not fire webhook events.

Payload

Each webhook delivers the full project state (the same data returned by GET /projects/:id) plus an event field indicating the status transition that triggered the webhook.
{
  "id": "proj_abc123",
  "status": "idle",
  "mode": "autonomous",
  "output_type": "assembled",
  "event": "idle",
  "assembled_url": "https://...",
  "assembled_url_expires_at": "2025-03-16T10:30:00Z",
  "project_url": "https://eversince.ai/app/projects/...",
  "agent_message": "Your project is complete...",
  "assets": [
    {
      "ref": "a1b2c3d4",
      "type": "image-to-video",
      "url": "https://...",
      "model": "wan-2.6",
      "prompt": "Opening shot of the product on a clean background",
      "duration": 5.0,
      "aspect_ratio": "16:9",
      "source_image_url": "https://...",
      "source_video_url": null,
      "reference_image_url": null,
      "created_at": "2025-03-15T10:32:00Z"
    }
  ],
  "timeline": {
    "duration_seconds": 15.0,
    "aspect_ratio": "16:9",
    "craft": "cinematic",
    "scenes": [
      {
        "id": "scene_uuid",
        "ref": "a1b2c3d4",
        "position": 1,
        "duration": 5,
        "description": "Opening shot",
        "image_url": "https://...",
        "video_url": "https://...",
        "video_model": "wan-2.6",
        "image_model": "flux-2-max",
        "prompt": "Opening shot of the product on a clean background",
        "volume": 1.0,
        "fade_in": null,
        "fade_out": null
      }
    ],
    "audio": {
      "voiceover": null,
      "music": null,
      "tracks": []
    },
    "overlays": [],
    "captions": null
  },
  "created_at": "2025-03-15T10:30:00Z",
  "updated_at": "2025-03-15T10:35:00Z"
}

Signature verification

Webhook signing is optional. When a signing secret is configured for your account, every webhook includes signature headers for verification:
HeaderDescription
X-Eversince-Signaturesha256=<hmac hex digest>
X-Eversince-TimestampUnix timestamp (seconds)

Verification

The signature is an HMAC-SHA256 of {timestamp}.{raw body} using your signing secret.
import hmac
import hashlib

def verify_webhook(request, signing_secret):
    timestamp = request.headers["X-Eversince-Timestamp"]
    signature = request.headers["X-Eversince-Signature"]
    body = request.body.decode("utf-8")

    signed_content = f"{timestamp}.{body}"
    expected = "sha256=" + hmac.new(
        signing_secret.encode(),
        signed_content.encode(),
        hashlib.sha256
    ).hexdigest()

    return hmac.compare_digest(signature, expected)

Delivery

  • Timeout: 10 seconds. Your endpoint must respond within this window.
  • Method: POST with Content-Type: application/json
  • Webhooks are delivered once. For reliability, confirm state with a GET /projects/:id call after receiving a webhook