Skip to Content

Automatisations

Ce que reçoit votre système depuis une automatisation, la requête API en tant qu'utilisateur Workflow et la structure d'un flux

Dernière mise à jour le

Les automatisations permettent à Tillor d'exécuter lui-même des actions, comme créer des tâches ou appeler votre système. Le mode d'emploi pour les utilisateurs se trouve dans Automatisations. Cette page décrit ce que voit un intégrateur : le message de l'étape Envoyer un webhook, la Requête API vers une URL personnalisée ou vers l'API Tillor, et la structure d'un flux lorsque vous le gérez via l'API.

Envoyer un webhook

L'étape Envoyer un webhook livre un message personnalisé à l'un des webhooks de l'organisation. C'est la même livraison que pour les événements de webhook ordinaires, avec la même signature.

Le message

L'étape effectue un POST avec Content-Type: application/json et ces en-têtes :

En-têteContenu
X-Webhook-Event-IDUn identifiant unique pour cette livraison. En cas de nouvelles tentatives, la valeur reste identique, vous pouvez donc dédoublonner dessus
X-Webhook-Signaturesha256=<hex>, le HMAC-SHA256 du corps avec le secret de signature du webhook

Le corps a la même enveloppe que la charge utile d'un webhook :

{
  "event": "automation.invoice_unpaid",
  "data": {
    "invoice": "2026-0042",
    "amountOutstanding": 125.5
  },
  "timestamp": 1735689600000,
  "traceId": "0b0f7c0e-5d3c-4c1e-9b8a-7f1e2a3b4c5d",
  "triggeredBy": null
}
ChampDescription
eventLe Nom de l'événement que vous avez saisi dans l'étape. N'importe quel texte est autorisé, le nom n'a pas besoin de figurer dans la liste des clés d'événement
dataLa Charge utile de l'étape, une fois les variables remplacées, au format JSON
timestampHeure Unix en millisecondes de la livraison
traceIdUn UUID aléatoire par livraison. Contrairement aux événements du système, ce n'est pas l'identifiant de trace d'une action Tillor
triggeredByToujours null

Il n'y a pas de spanId. Le webhook n'a pas besoin d'être abonné à une clé d'événement : un message issu d'une automatisation est toujours livré au endpoint choisi, tant qu'il existe et qu'il est activé.

La vérification de la signature est décrite dans Vérifier la signature.

Tentatives et résultat

Tillor effectue jusqu'à 5 tentatives dans l'étape, avec 1, 2, 4 et 8 secondes d'attente entre elles. Une tentative est réussie avec un statut 2xx. Une cible bloquée, par exemple une adresse interne, compte aussi comme tentative échouée.

  • Si l'une des tentatives réussit, le flux continue par la sortie Réussi
  • Si les cinq échouent, le flux continue par Échec. Le message est ensuite encore réessayé en arrière-plan selon le calendrier décrit dans Comportement de livraison et nouvelles tentatives. Si une tentative ultérieure réussit, cela ne se reflète plus dans l'exécution, car celle-ci a déjà continué

Si le webhook n'existe plus ou est désactivé, l'étape ne passe pas par Échec. L'exécution s'arrête alors avec le statut Échec.

Requête API vers une URL personnalisée

Avec Requête API et Envoyer à sur URL personnalisée, une automatisation envoie une requête HTTP vers votre serveur.

ÉlémentComportement
MéthodeGET, POST, PUT, PATCH ou DELETE
URLDoit commencer par https://. Les variables sont insérées encodées
CorpsJSON. Non envoyé pour GET et DELETE. Avec un corps, Tillor définit Content-Type: application/json
En-têtesLibres. Les valeurs peuvent contenir des variables. Host, Content-Length, Transfer-Encoding et Connection sont ignorés
CibleLes adresses privées et internes sont refusées, même si un nom de domaine ordinaire y renvoie
RedirectionsNon suivies. Une réponse 3xx compte comme un échec
Délai d'expiration15 secondes

Pas de signature

Contrairement à Envoyer un webhook, Tillor ne signe pas cette requête. Si vous voulez vérifier qu'une requête provient de votre automatisation, placez un secret dans un en-tête et contrôlez-le de votre côté. Les en-têtes sont stockés chiffrés, une clé ou un jeton qui s'y trouve est donc en sécurité.

Une réponse avec un statut 2xx continue par Réussi, tout autre statut par Échec. Si le serveur est injoignable ou dépasse le délai d'expiration, l'exécution s'arrête avec le statut Échec.

Requête API vers l'API Tillor

Avec Envoyer à sur Tillor API, l'automatisation appelle l'API de sa propre organisation. Vous indiquez seulement un chemin, par exemple /tasks, et Tillor le place derrière /api/orgs/{orgId}. Votre référence d'API se trouve sur OpenAPI.

  • Identité : la requête est exécutée en tant qu'utilisateur Workflow de l'organisation. Celui-ci a toutes les permissions au sein de cette organisation et nulle part ailleurs. Les modifications sont donc enregistrées au nom de Flux de travail
  • Pas de clé nécessaire : Tillor effectue l'appel lui-même, sans clé API et sans passer par Internet
  • Chemin : doit commencer par un seul /. //, .. et \ ne sont pas autorisés. Une chaîne de requête est permise, par exemple /tasks?terrainId=…&limit=1. Les variables dans le chemin sont insérées encodées
  • Bloqué : les chemins /automations et /automation-runs sont refusés, même avec une chaîne de requête, des majuscules, un / final ou un codage en pourcentage. Une automatisation ne peut pas gérer des automatisations
  • Corps : JSON, pour POST, PUT et PATCH. Pour GET et DELETE, il n'est pas envoyé
  • Menu de choix : dans l'éditeur figure Choisissez un endpoint API avec les opérations de la spécification OpenAPI. Les opérations internes n'y figurent pas. Si vous en choisissez une, Tillor remplit la méthode, le chemin et un exemple de corps
  • Échec : une réponse 2xx continue par Réussi. Un statut d'erreur, y compris un 404 pour un chemin inexistant, passe par Échec

La réponse dans les étapes suivantes

Après la requête, ces variables sont disponibles :

VariableContenu
{response.status}Le code de statut HTTP
{response.body}Les 4000 premiers caractères de la réponse sous forme de texte
{response.data}La réponse au format JSON. null si ce n'est pas du JSON, ou si elle dépasse 100 000 caractères. Vous adressez les listes par un index, par exemple {response.data.items.0.id}

Une deuxième requête API dans le même flux remplace response. Les variables fonctionnent comme dans Variables et modèles.

La structure d'un flux

Vous pouvez aussi créer et modifier des automatisations via l'API. Les opérations figurent dans OpenAPI sous le tag automations. La lecture requiert la permission automations:read, la création et la modification automations:write (ou toutes les permissions). L'utilisateur Workflow lui-même ne peut jamais les appeler. Il peut être plus pratique de construire un flux dans l'éditeur et de le lire comme exemple.

Une nouvelle automatisation est toujours désactivée. L'activer via enabled échoue tant que le flux a des problèmes ouverts, et vous ne pouvez pas enregistrer un flux activé qui a des problèmes.

La definition se compose d'étapes (nodes), de liens (edges) et, en option, de remarques (notes). Maximum 100 étapes, 200 liens et 50 remarques.

{
  "nodes": [
    {
      "id": "trigger",
      "type": "trigger",
      "label": "",
      "position": { "x": 0, "y": 0 },
      "config": { "source": "event", "eventKey": "occupation:ended" }
    },
    {
      "id": "task",
      "type": "taskCreate",
      "label": "",
      "position": { "x": 0, "y": 190 },
      "config": { "title": "Controleer {occupation.terrain.name}", "priority": "HIGH" }
    }
  ],
  "edges": [
    { "id": "trigger:out:task", "source": "trigger", "target": "task", "sourceHandle": "out" }
  ],
  "notes": [
    {
      "id": "note_1",
      "text": "Maakt na elk vertrek een controletaak.",
      "position": { "x": 340, "y": 0 },
      "width": 240,
      "height": 140
    }
  ]
}

Une remarque (notes) est une explication sur le canevas. Elle n'est jamais exécutée et n'a pas de liens. text fait 2000 caractères maximum, width et height sont en pixels.

Un lien a un sourceHandle : la sortie de l'étape dont il part.

Étape (type)Sorties (sourceHandle)
trigger, delay, waitUntilOpen, waitUntilClosed, taskCreate, taskSetStatus, taskSetPriority, taskUpdate, invoiceReminderSend, invoiceSend, invoicePrint, occupationExtendInvoice, staffNotify, commentCreate, inboxReply, inboxTag, customerUpdate, accessMethodCreate, accessMethodUpdate, accessMethodSendQr, accessPointControl, meterSwitch, nfcTagUpdate, deviceCommand, deviceDisplay, deviceSlideshow, controllerRelay, controllerCommandout
customerMessageSend, reservationSetStatus, invoiceBook, paymentLinkCreate, mandateRequest, mandateCollect, consumptionInvoiceout, skipped
conditionyes, no
switchL'id de chaque branche, plus default
openingHoursopen, closed
throttlepass, blocked
taskFind, documentFind, recordLookupfound, notFound
forEacheach, done
waitUntilmet, timeout
waitForEventreceived, timeout
approvalapproved, rejected, timeout
webhookSend, httpRequestsuccess, failed

Toute action sauf webhookSend et httpRequest reçoit une sortie supplémentaire error dès que continueOnError est à true dans la config. Sans ce réglage, une action échouée arrête l'exécution. Avec ce réglage, le flux continue par error, avec {error.message} et {error.step} comme variables pour les étapes suivantes. La sortie skipped est utilisée lorsqu'une étape n'avait rien à faire, et out est alors la sortie ordinaire.

Pour forEach, la sortie each démarre une exécution propre par élément pour les étapes suivantes, et la sortie done est la suite ordinaire du flux lui-même.

Une sortie peut mener à plusieurs étapes. L'exécution continue elle-même avec le premier lien et démarre pour chaque autre lien une exécution propre avec les mêmes données, qui tourne en parallèle (comme la sortie each de forEach). Les liens qui forment une boucle sont refusés dans l'éditeur. Un flux a exactement un trigger.

Réglages par étape

Les champs sous config sont les champs de l'éditeur. Les champs de texte acceptent des variables entre accolades.

ÉtapeChamps dans config
triggersource (event, webhook, invoiceOverdue, dateReached, daily ou cron), webhookVersion (pour webhook : texte, à incrémenter pour remplacer l'adresse), eventKey, date (pour dateReached : un chemin record.veld vers une colonne DateTime d'un modèle dont un événement envoie l'intégralité, comme reservation.checkIn ou contact.birthday, ou vers une clé de date déclarée dans une colonne JSON, comme document.userMetadata.insuranceExpiryDate ; les anciens noms comme reservationCheckIn continuent de fonctionner), dateOffset ({ "amount", "unit" }), dateDirection (before ou after), dateTime (exact : l'heure dans la date, ou fixed : le jour calendaire de la date dans le fuseau horaire de l'organisation, avec dateHour et dateMinute, du texte comme "9" et "0" ; le décalage compte sur l'horloge, donc à travers l'heure d'été et d'hiver), repeatYearly (booléen : seuls le jour et le mois comptent, chaque année), hour et minute (texte, par exemple "8" et "0", minute de 0 à 59), cron (cinq champs ; le jour de la semaine peut être 1#2 ou 1L, un sixième champ W2:2026-10-05 répète toutes les deux semaines), conditions, oncePerRecord (booléen)
conditionconditions
switchfield (un chemin de variable sans accolades), cases : une liste de { "id", "key", "value" } avec key comme nom de la branche et value comme valeur à laquelle le champ doit être égal. 8 branches maximum
delaymode (duration ou untilDate), duration et offset sous la forme { "amount", "unit" } avec unit valant seconds, minutes, hours, days ou weeks, dateField (chemin de variable), direction (before ou after)
taskCreatetitle, description, assigneeIds, labelIds, assignActor, priority (LOW, MEDIUM, HIGH ou URGENT), viewId, laneId, subtasks (une par ligne), dueIn ({ "amount", "unit" }), linkRecords
taskSetStatustaskId, status (PENDING, IN_PROGRESS, WAITING ou COMPLETED)
taskFindtitle (titre exact), linkedToRecords, onlyOpen, onlyTopLevel (booléens)
documentFindcustomerId (modèle), documentType (INSURANCE_POLICY, INSURANCE_PAYMENT_PROOF, IDENTITY_CARD, SEPA_MANDATE, OTHER ou vide), onlyActive, onlyValid (booléens). Résultat sous foundDocument
documentUpdatedocumentId (modèle), documentType (vide conserve le type), status (ACTIVE, ARCHIVED ou vide)
taskSetPrioritytaskId, mode (raise, lower ou set), priority (pour set), maxPriority (pour raise)
taskUpdatetaskId, title, assigneeIds, assignActor, assigneeMode (add ou replace), labelIds, dueIn ({ "amount", "unit" } avec unit valant minutes, hours, days ou weeks)
invoiceReminderSend, invoiceSend, invoiceBookinvoiceId
invoicePrintinvoiceId, printer (a4, pos ou tablet)
paymentLinkCreateinvoiceId, method (any, BANCONTACT, IDEAL, CREDITCARD ou PAYCONIQ)
mandateRequestcustomerId, mode (request ou reminder)
mandateCollectinvoiceId, delayDays (texte, "0" par défaut, 7 au plus)
consumptionInvoicecustomerId, sendEmail, sendSms
occupationExtendInvoiceoccupationId, includeConsumption
customerMessageSendcustomerId, subject, body, sendEmail, sendSms, sendWhatsApp
staffNotifyuserIds, notifyActor, title, body, sendPush, sendEmail
commentCreatecontent, target (event ou task), taskId (pour task)
inboxReplythreadId, body, keepAssistant
inboxTagthreadId, tagIds, archive
customerUpdatecustomerId, status (keep, DEFAULT, PREFERRED, VIP, WARNING ou BLACKLISTED), notes
reservationSetStatusreservationId, action (checkIn, checkOut ou cancel)
accessMethodCreatecustomerId, type (QR_CODE, LPR, PIN_CODE ou NFC), value, periodFrom, periodTo (variables contenant une date, vide signifie aucune limite)
accessMethodUpdatescope (one ou customer), accessMethodId (pour one), customerId (pour customer), status (keep, ACTIVE, SOFT_BLOCKED, BLOCKED ou INACTIVE), periodTo
accessMethodSendQraccessMethodId, sendEmail, sendSms, sendWhatsApp, print (none, label ou thermal)
accessPointControlaccessPointId, action (open ou close)
meterSwitchtarget (terrain ou meter), terrainId (pour terrain), meterId (pour meter), state (on ou off)
nfcTagUpdatecustomerId, action (block, unblock, topUp ou lowBalance), amount (pour topUp, en euros par badge)
deviceCommanddeviceId, command (wake, sleep, reload, identify, testSound ou playSound), url (pour playSound : le chemin d'un son téléversé, tel que l'éditeur le remplit, ou un lien https vers un fichier mp3, wav ou m4a)
deviceDisplaykind (pdf ou image), url (lien https). Apparaît sur chaque tablette configurée comme écran d'affichage, comme un PDF de facture
controllerRelaytarget (controller ou event : le contrôleur de l'événement controller:input:changed qui a démarré le flux), controllerId (pour controller), relay (texte "1" à "6"), action (pulse, on ou off), durationSeconds (pour pulse, texte, de 0.001 à 3600 avec des décimales comme "0.5" ; le relais retombe de lui-même)
controllerCommandtarget et controllerId comme pour controllerRelay, command (reboot, rebootExtension, otaUpdate, forceOtaUpdate, extensionOtaUpdate ou refreshSettings)
deviceSlideshowscope (displays ou device), mode (screensaver ou background), source (feed ou urls). Pour feed : itemsPath, imageField, champs de filtre et de tri facultatifs
openingHours, waitUntilOpen, waitUntilClosedAucun champ
throttlewindow ({ "amount", "unit" } avec unit valant minutes, hours, days ou weeks), key (vide signifie par enregistrement qui a démarré le flux)
recordLookupmodel (Customer, Reservation, Occupation, Invoice, Payment, Terrain, Task, Document, AccessMethod, NfcTag, Meter, InboxThread ou InboxMessage), recordId. Le résultat se trouve sous found plus le modèle, comme foundCustomer
forEachsource (customerAccessMethods, customerNfcTags, customerOpenInvoices, customerUpcomingReservations, customerOccupations, customerDocuments (uniquement ACTIVE) ou terrainMeters), parentId (identifiant du client ou du terrain). 100 éléments au plus, l'élément se trouve sous item
waitUntilconditions, interval et timeout ({ "amount", "unit" } avec unit valant minutes, hours, days ou weeks ; l'intervalle est d'au moins 5 minutes)
waitForEventeventKey, sameRecord (booléen), timeout ({ "amount", "unit" })
approvaltitle, description, assigneeIds, timeout ({ "amount", "unit" }). La tâche se trouve sous approvalTask.id
Toute action sauf webhookSend et httpRequestcontinueOnError (booléen)
webhookSendwebhookId, event, payload (JSON sous forme de texte)
httpRequesttarget (tillor ou custom), method, path (pour tillor), url (pour custom), headers (liste de { "id", "key", "value" }), body (JSON sous forme de texte)

conditions a la forme { "match": "all" ou "any", "rules": [...] }. Chaque règle est { "id", "field", "operator", "value", "values" }. operator vaut is, isNot, contains, greaterThan, lessThan, isOneOf, isEmpty ou isNotEmpty. Vous n'utilisez values que pour isOneOf. Une liste de règles vide laisse tout passer.

Démarrer une automatisation avec un webhook

Une automatisation avec le déclencheur webhook démarre à la suite d'un POST vers sa propre adresse :

curl -X POST "https://tillor.eu/api/orgs/org_abc123/automation-hooks/aut_xxx/<token>?bron=website" \
  -H "Content-Type: application/json" \
  -d '{"email":"jan@voorbeeld.nl","aankomst":"2026-07-14"}'
  • L'adresse complète figure dans l'éditeur, au niveau du déclencheur, ou via GET /automations/{id}/webhook-url (avec automations:read). Le jeton est le secret ; un en-tête d'authentification n'est pas nécessaire
  • Le corps JSON devient la variable body, la chaîne de requête query, et l'heure receivedAt
  • Réponse 200 avec { "accepted": true } dès que l'exécution a démarré. Une adresse erronée, remplacée ou désactivée renvoie 404, un corps de plus de 100 Ko renvoie 400
  • De nombreux appels rapprochés ne sont pas refusés : chaque appel valide démarre une exécution. Utilisez Ignorer les répétitions sur le déclencheur si le même appel peut arriver deux fois, voir Ignorer les répétitions

Une automatisation ne peut pas appeler son propre webhook via une Requête API vers l'API Tillor.

Choisir une décision via l'API

La tâche d'une étape Demander une décision a une action par option que vous avez définie dans l'étape. Récupérez la tâche pour voir les actions avec leur id, et choisissez-en une avec POST /tasks/{id}/actions/{actionId}/choose. Si l'option demande une note, envoyez-la avec { "note": "..." }. Le choix est définitif : il clôt la tâche et poursuit l'automatisation par la sortie de cette option. Les collègues assignés (y compris via un groupe) et les administrateurs peuvent choisir. Voir OpenAPI pour les détails.

Pour en savoir plus

  • Webhooks pour la signature, les nouvelles tentatives et la liste des événements
  • API HTTP pour l'authentification et le contexte d'organisation
  • Variables et modèles pour le mode d'emploi utilisateur
Cette page t'a-t-elle été utile ?

Sur cette page