Articles sur : Intelligence artificielle (IA)

Webhooks sortants

Les webhooks te permettent de connecter Fotostudio à des outils externes comme Make, Zapier, n8n ou ton propre backend. À chaque événement important (nouveau contact, facture payée, contrat signé...), Fotostudio envoie automatiquement les données vers l'URL de ton choix.



Configurer un webhook


Rends-toi dans Modules → Webhooks sortants et clique sur Nouveau webhook.


Remplis les champs suivants :


Champ

Description

Label

Un nom pour t'y retrouver (ex : "Make – factures")

URL de destination

L'URL HTTPS fournie par ton outil (Make, Zapier...)

Événements

Les événements à écouter (tu peux en cocher plusieurs)


Un secret est généré automatiquement à la création. Copie-le immédiatement : il ne sera plus affiché ensuite. Il sert à vérifier que les appels viennent bien de Fotostudio.



Événements disponibles


Événement

Déclenché quand...

contact.created

Un nouveau contact est créé

contact.updated

Un contact est modifié (coordonnées, infos...)

project.created

Une nouvelle séance est créée

project.status_changed

Le statut d'une séance change

project.confirmed

Une séance est confirmée

invoice.created

Une facture est créée

invoice.paid

Une facture est marquée comme payée

payment.created

Un paiement est enregistré

estimate.accepted

Un devis est accepté par le client

estimate.refused

Un devis est refusé par le client

contract.signed

Un contrat est signé



Format des données envoyées


Chaque appel est un POST en JSON avec la structure suivante :


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


En-têtes HTTP


Header

Valeur

Content-Type

application/json

X-FS-Event

Nom de l'événement (ex : invoice.paid)

X-FS-Signature

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

X-FS-Delivery-Id

Identifiant unique de la livraison


Vérifier la signature


La signature dans X-FS-Signature est calculée ainsi :


HMAC-SHA256(secret, body_json)


En Node.js par exemple :


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('Signature invalide')



Détail des données par événement


contact.created / contact.updated


{
  "id": 123,
  "firstname": "Marie",
  "lastname": "Dupont",
  "email": "marie@example.com",
  "phone": "+33 6 12 34 56 78",
  "company": "Studio Photo",
  "street": "12 rue de la Paix",
  "zipcode": "75001",
  "city": "Paris",
  "country": "France",
  "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": "Mariage Dupont",
  "start_time": "2026-07-20T14:00:00Z",
  "end_time": "2026-07-20T18:00:00Z",
  "project_type": "Mariage",
  "status": "Confirmé",
  "validated": true,
  "location": "Château de Versailles",
  "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": "Mariage Dupont",
  "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 est le solde restant à payer (total - paiements déjà reçus).


payment.created


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


estimate.accepted / estimate.refused


{
  "id": 202,
  "numero": "D2026-018",
  "title": "Mariage Dupont",
  "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": "Contrat Mariage Dupont",
  "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"
}



Historique des livraisons


Dans la fiche de chaque webhook, l'onglet Logs affiche l'historique des appels avec :


  • la date et l'heure
  • l'événement déclenché
  • le statut (succès / échec)
  • le code HTTP de réponse
  • le message d'erreur en cas d'échec


En cas d'échec, Fotostudio réessaie automatiquement jusqu'à 3 fois avec un délai exponentiel. Tu peux aussi relancer manuellement un appel depuis les logs.



Utiliser avec Make


  1. Dans Make, crée un nouveau scénario et ajoute un module Webhooks → Custom webhook
  2. Copie l'URL générée par Make
  3. Dans Fotostudio, crée un webhook avec cette URL et sélectionne les événements souhaités
  4. Déclenche un événement test depuis Fotostudio (crée un contact, par exemple)
  5. Make reçoit les données. Tu peux ensuite construire ton automatisation



Utiliser avec Zapier


  1. Dans Zapier, crée un nouveau Zap et choisis Webhooks by Zapier → Catch Hook comme déclencheur
  2. Copie l'URL fournie par Zapier
  3. Dans Fotostudio, crée un webhook avec cette URL
  4. Déclenche un événement test. Zapier détecte automatiquement la structure des données
  5. Configure ton action (Google Sheets, Notion, Slack...)



FAQ


Que se passe-t-il si mon serveur est indisponible ?

Fotostudio réessaie 3 fois avec un délai croissant. Après 3 tentatives, la livraison est marquée en échec mais reste dans les logs. Tu peux la relancer manuellement.


Mon webhook doit-il répondre en moins de combien de temps ?

Ton endpoint doit répondre dans les 10 secondes. Au-delà, la requête est considérée comme en échec.


Puis-je avoir plusieurs webhooks ?

Oui, tu peux créer autant de webhooks que tu veux, chacun avec ses propres événements et son URL.


Comment désactiver temporairement un webhook ?

Dans la liste, utilise le bouton de bascule pour activer ou désactiver un webhook sans le supprimer.


Mis à jour le : 12/06/2026

Cet article a-t-il répondu à vos questions ?

Partagez vos commentaires

Annuler

Merci !