PropertyPixel Docs

Webhooks

Get notified when jobs finish and uploads arrive.

Add an endpoint in Settings → Developers → Webhooks (workspace owners only). Choose the events you want and copy the signing secret. It's shown once; you can rotate it later.

Events

EventWhen
job.completedA photo edit (enhancement or staging) finished.
job.failedA job failed. Its credits were refunded.
video.completedA Photo to Video or Listing Tour video finished.
upload.completedPhotos arrived through an upload link and the user tapped Done.

Payload

Every delivery is a POST with a JSON body:

{
  "type": "job.completed",
  "timestamp": "2026-10-05T10:15:00.000Z",
  "data": {
    "id": "9b1c…",
    "kind": "enhancement",
    "status": "completed",
    "project_id": "2f4e…",
    "photo_ids": ["a81d…"],
    "enhancement_types": ["improve_lighting"],
    "result": { "url": "https://…", "expires_at": "2026-10-06T10:15:00.000Z" }
  }
}

data for job events follows the Job shape, and its result URL lasts 24 hours. Events sent with Send test event include "test": true.

Verifying signatures

Deliveries are signed with the Standard Webhooks scheme, using the webhook-id, webhook-timestamp and webhook-signature headers. Verify against the raw request body.

Node
import { Webhook } from "standardwebhooks";

const wh = new Webhook(process.env.PROPERTYPIXEL_WEBHOOK_SECRET!); // "whsec_…"

export async function POST(request: Request) {
  const body = await request.text();
  const event = wh.verify(body, Object.fromEntries(request.headers)); // throws if invalid
  // handle event.type …
  return new Response(null, { status: 204 });
}
Python
from standardwebhooks import Webhook

wh = Webhook(os.environ["PROPERTYPIXEL_WEBHOOK_SECRET"])
event = wh.verify(request.body, dict(request.headers))  # raises if invalid

Use webhook-id to deduplicate: retries reuse the same ID.

Retries and disabling

  • Respond with any 2xx within 10 seconds to acknowledge.
  • Failed deliveries are retried after 30 seconds, 2 minutes, 10 minutes, 30 minutes, 2 hours, 6 hours and 12 hours (8 attempts over about 21 hours).
  • After 8 deliveries in a row exhaust their retries, or after 3 days of failures, the endpoint is disabled and the workspace owner is emailed. Re-enable it in Settings once it's fixed.
  • The delivery log keeps 30 days of attempts, and you can resend any delivery.