Articles on: Artificial Intelligence (AI)
This article is also available in:

Outgoing webhooks

Webhooks let you connect Fotostudio to external tools such as Make, Zapier, n8n or your own backend. For each important event (new contact, paid invoice, signed contract...), Fotostudio automatically sends the data to the URL of your choice.



Setting up a webhook


Webhooks are a module you activate, available on every plan. Go to Modules > All modules, Advanced category, and activate the Webhooks module. If you had already created a webhook, the module is already activated for you.


Then go to Modules > Outgoing webhooks and click Add a webhook.


Fill in the following fields:


Field

Description

Label (optional)

A name to find your way around (e.g. "Make invoices")

Destination URL

The HTTPS URL provided by your tool (Make, Zapier...)

Events to subscribe to

The events to listen to (you can tick several)


An HMAC secret key is generated automatically when the webhook is created. Copy it right away: it won't be shown this way again. It's used to check that calls really come from Fotostudio.



Available events


Event

Triggered when...

contact.created

A new contact is created

contact.updated

A contact is updated (details, info...)

project.created

A new session is created

project.status_changed

A session's status changes

project.confirmed

A session is confirmed

invoice.created

An invoice is created

invoice.paid

An invoice is marked as paid

payment.created

A payment is recorded

estimate.accepted

A quote is accepted by the client

estimate.refused

A quote is declined by the client

contract.signed

A contract is signed



Format of the data sent


Each call is a JSON POST with the following structure:


{
  "event": "invoice.paid",
  "timestamp": "2026-06-12T10:30:00Z",
  "data": {
    ...
  }
}


HTTP headers


Header

Value

Content-Type

application/json

X-FS-Event

Event name (e.g. invoice.paid)

X-FS-Signature

sha256=<hmac> (HMAC-SHA256 signature of the body)

X-FS-Delivery-Id

Unique delivery identifier


Verifying the signature


The signature in X-FS-Signature is calculated like this:


HMAC-SHA256(secret, body_json)


For example in Node.js:


const crypto = require('crypto')
const sig = 'sha256=' + crypto.createHmac('sha256', SECRET).update(rawBody).digest('hex')
if (sig !== req.headers['x-fs-signature']) throw new Error('Invalid signature')



Data details by event


contact.created / contact.updated


{
  "id": 123,
  "firstname": "Mary",
  "lastname": "Smith",
  "email": "mary@example.com",
  "phone": "+1 555 123 4567",
  "company": "Photo Studio",
  "street": "12 Main Street",
  "zipcode": "10001",
  "city": "New York",
  "country": "United States",
  "created_at": "2026-01-15T09:00:00Z",
  "url": "https://www.fotostudio.io/app/contacts/123"
}


project.created / project.status_changed / project.confirmed


{
  "id": 456,
  "name": "Smith Wedding",
  "start_time": "2026-07-20T14:00:00Z",
  "end_time": "2026-07-20T18:00:00Z",
  "project_type": "Wedding",
  "status": "Confirmed",
  "validated": true,
  "location": "Central Park",
  "contact_id": 123,
  "created_at": "2026-01-15T09:00:00Z",
  "url": "https://www.fotostudio.io/app/projects/456"
}


invoice.created / invoice.paid


{
  "id": 789,
  "numero": "F2026-042",
  "title": "Smith Wedding",
  "invoice_date": "2026-06-01",
  "total_price": 1500.00,
  "amount_to_pay": 750.00,
  "paid": false,
  "draft": false,
  "contact_id": 123,
  "project_id": 456,
  "created_at": "2026-06-01T10:00:00Z",
  "url": "https://www.fotostudio.io/app/invoices/789"
}


amount_to_pay is the remaining balance (total minus payments already received).


payment.created


{
  "id": 101,
  "amount": 750.00,
  "payment_date": "2026-06-10",
  "payment_type": "Bank transfer",
  "invoice_id": 789,
  "contact_id": 123,
  "created_at": "2026-06-10T14:00:00Z"
}


estimate.accepted / estimate.refused


{
  "id": 202,
  "numero": "D2026-018",
  "title": "Smith Wedding",
  "total_price": 1500.00,
  "accepted": true,
  "refused": false,
  "accepted_at": "2026-06-05T16:00:00Z",
  "contact_id": 123,
  "project_id": 456,
  "created_at": "2026-05-20T09:00:00Z",
  "url": "https://www.fotostudio.io/app/estimates/202"
}


contract.signed


{
  "id": 303,
  "title": "Smith Wedding Contract",
  "signed_at": "2026-06-08T11:30:00Z",
  "project_id": 456,
  "contact_id": 123,
  "created_at": "2026-05-25T10:00:00Z",
  "url": "https://www.fotostudio.io/app/contracts/303"
}



Delivery history


In the list of webhooks, open a webhook's Actions menu, then Last deliveries (50). You'll see the history of calls with:


  • the date and time
  • the event triggered
  • the status (Delivered, Failed or Pending)
  • the number of attempts
  • the HTTP response code
  • the error message if it failed


If a call fails, Fotostudio automatically retries up to 3 times with an exponential delay. You can also resend a call manually with the Retry button.



Using with Make


  1. In Make, create a new scenario and add a Webhooks → Custom webhook module
  2. Copy the URL generated by Make
  3. In Fotostudio, create a webhook with this URL and select the events you want
  4. Trigger a test event from Fotostudio (create a contact, for example)
  5. Make receives the data. You can then build your automation



Using with Zapier


  1. In Zapier, create a new Zap and choose Webhooks by Zapier → Catch Hook as the trigger
  2. Copy the URL provided by Zapier
  3. In Fotostudio, create a webhook with this URL
  4. Trigger a test event. Zapier automatically detects the data structure
  5. Set up your action (Google Sheets, Notion, Slack...)



FAQ


What happens if my server is unavailable?
Fotostudio retries 3 times with an increasing delay. After 3 attempts, the delivery is marked as failed but stays in the history. You can resend it manually.


How fast must my webhook respond?
Your endpoint must respond within 10 seconds. Beyond that, the request is considered failed.


Can I have several webhooks?
Yes, you can create as many webhooks as you like, each with its own events and URL.


How do I temporarily disable a webhook?
In the list, open the webhook's Actions menu and choose Inactive (or Active to turn it back on): it is paused without being deleted.


What happens if I deactivate the Webhooks module?
Your webhooks are kept, but no more calls are sent and the Outgoing webhooks entry disappears from the menu. Activate the module again to resume sending.

Updated on: 23/10/2026

Was this article helpful?

Share your feedback

Cancel

Thank you!