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
- Go to Admin > API Settings.
- Under Webhook Settings, enter a publicly reachable HTTPS URL in the Webhook URL field and click Save.
- 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.
- HeadshotPro begins POSTing a JSON payload to your URL whenever a supported event fires.
- Your endpoint should return any
2xxstatus 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:
| Header | Value |
|---|---|
X-HeadshotPro-Signature | sha256=<HMAC-SHA256 hex digest> |
X-HeadshotPro-Timestamp | Unix 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
| Event | When it fires |
|---|---|
model.created | A new model (shoot) is created in your organization |
model.status.updated | The model's status changes (e.g., training started, finished, error) |
model.photos_ready | Headshots have been generated and are ready to view |
model.favorite_selected | A team member selects their favorite headshot |
model.deleted | A 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.