Webhooks and Integrations

Connect HeadshotPro to your own systems or third-party tools using webhooks and Zapier.

Webhooks and Integrations

HeadshotPro sends real-time event notifications to a URL of your choice whenever something happens to a model in your organization — a shoot is created, headshots are ready, a favorite is selected, and more. You can also connect to 5,000+ apps via the Zapier integration.

All webhook configuration is on the API Settings page (Admin > API). Only users with the TeamLead role can view or change these settings.

How it works

  1. Go to Admin > API Settings.
  2. Under Webhook Settings, enter a publicly reachable HTTPS URL in the Webhook URL field and click Save.
  3. On first save, HeadshotPro automatically generates a Webhook Secret — a 64-character hex string used to sign every outgoing request. Copy and store it immediately; it is shown only once.
  4. HeadshotPro begins POSTing a JSON payload to your URL whenever a supported event fires.
  5. Your endpoint should return any 2xx status code to acknowledge receipt. If it does not, HeadshotPro retries up to 4 times with escalating delays: immediately, 5 minutes, 15 minutes, then 1 hour.

Verifying signatures

Every request includes two headers:

HeaderValue
X-HeadshotPro-Signaturesha256=<HMAC-SHA256 hex digest>
X-HeadshotPro-TimestampUnix timestamp (seconds)

To verify, reconstruct the signed string as {timestamp}.{raw JSON body} and compute HMAC-SHA256 using your webhook secret. Compare the result to the value in X-HeadshotPro-Signature. Reject requests where the timestamp is more than a few minutes old to prevent replay attacks.

Payload format

Every webhook POST body follows this structure:

{
  "id": "evt_<uuid>",
  "event": "model.photos_ready",
  "createdAt": "2024-01-15T12:00:00.000Z",
  "objectType": "model",
  "object": {
    "_id": "...",
    "uid": "...",
    "title": "...",
    "trigger": "...",
    "status": "...",
    "finishedAt": "...",
    "createdAt": "...",
    "organization": "..."
  }
}

For model.favorite_selected events, a favoritePhoto field is also included:

{
  "favoritePhoto": {
    "id": "...",
    "urls": {
      "preview": "https://...",
      "transparent": "https://...",
      "pfp": "https://..."
    },
    "expiresAt": "2024-02-15T12:00:00.000Z"
  }
}

The download links in favoritePhoto.urls expire after a fixed period — store the photo file on your own infrastructure if you need permanent access.

Event types

EventWhen it fires
model.createdA new model (shoot) is created in your organization
model.status.updatedThe model's status changes (e.g., training started, finished, error)
model.photos_readyHeadshots have been generated and are ready to view
model.favorite_selectedA team member selects their favorite headshot
model.deletedA model is deleted

Managing your webhook secret

  • Rotating the secret: Click Regenerate Secret on the API Settings page. The old secret is immediately invalidated. Update your receiving endpoint before rotating to avoid dropped events.
  • Checking secret status: The API Settings page shows whether a secret exists and when it was created, but never displays the value again after generation. Use Regenerate Secret if you lose it.

Zapier integration

HeadshotPro has a native Zapier app. From the API Settings page, click Connect next to the Zapier card, or go directly to zapier.com/apps/headshotpro/integrations. From there you can build Zaps that trigger on HeadshotPro events and connect to any of Zapier's 5,000+ supported apps — syncing new members from an HRIS, pushing finished headshots to Slack, logging shoots to a spreadsheet, and so on.

Authentication between Zapier and HeadshotPro uses the organization API key available on the same API Settings page.

Good to know

  • There is a short delay (typically a few seconds) between the event and the first delivery attempt.
  • Failed deliveries are logged internally. There is no webhook delivery log visible in the dashboard.
  • Only models belonging to your organization trigger webhooks — events from other organizations are never sent to your URL.
  • Webhook settings require your organization to have the API feature enabled. Contact support if the Webhook Settings section is not visible on your API Settings page.
Was this article helpful?