Reference webhook payloadu a podpisu

Každá webhook integrace ve FluoTestu odešle při odeslání kvízu HTTP POST požadavek s JSON tělem. Tato stránka popisuje formát požadavku, výchozí pole payloadu, alternativní tvar payloadu používaný s mapováním polí a systém podpisu.

Naposledy aktualizováno

Jak vypadá payload webhooku ve FluoTestu?

Ve výchozím stavu jde o plochý JSON objekt s identifikátory odpovědi, kontaktními údaji, skóre, úrovní nebo výsledkem, celým objektem odpovědí a časem odeslání. Pokud je nastaven podpisový klíč, požadavky obsahují hlavičku X-FluoTest-Signature (HMAC-SHA256 z těla požadavku).

Konfigurace

Webhook integrace se konfiguruje cílovou URL adresou a volitelným podpisovým klíčem. Není potřeba žádné OAuth ani propojení účtu třetí strany.

Formát požadavku

Každý webhook požadavek se odesílá s touto metodou a hlavičkami:

HlavičkaHodnotaPoznámky
MethodPOSTVždy POST požadavek.
Content-Typeapplication/jsonTělo je kódováno jako JSON.
User-AgentFluoTest-Webhook/1.0Identifikuje požadavek jako pocházející z FluoTestu.
X-FluoTest-Eventsubmission.createdJediný v současnosti odesílaný typ události.
X-FluoTest-Signaturesha256=<hex>Přítomna pouze pokud je pro webhook nastaven podpisový klíč.

Výchozí pole payloadu

Bez nastaveného mapování polí je tělo požadavku plochý JSON objekt:

{
  "submission_id": "8f2b1c3a-...",
  "test_id": "3a9d7e10-...",
  "test_name": "Lead Fit Quiz",
  "email": "[email protected]",
  "first_name": "Jane",
  "last_name": "Doe",
  "company": "Acme Inc",
  "contact_type": "email",
  "respondent_name": "Jane Doe",
  "total_score": 82,
  "max_score": 100,
  "score_percent": 82,
  "tier": "High fit",
  "scores": null,
  "outcome": null,
  "outcomes": null,
  "disqualified": false,
  "answers": {
    "sections": [
      {
        "section_title": "Section 1",
        "questions": [
          {
            "question_id": "q1",
            "question_text": "What's your role?",
            "question_type": "multiple_choice",
            "answer": "Founder"
          }
        ]
      }
    ]
  },
  "submitted_at": "2026-07-10T14:32:00.000Z"
}
PoleTypPopis
submission_idstringUnikátní ID odpovědi.
test_idstringID kvízu.
test_namestringNázev kvízu.
emailstring | nullE-mail respondenta, pokud byl sesbírán.
first_namestring | nullKřestní jméno respondenta, pokud bylo sesbíráno.
last_namestring | nullPříjmení respondenta, pokud bylo sesbíráno.
companystring | nullNázev společnosti, pokud byl sesbírán.
contact_typestring | nullJaký kontaktní způsob byl sesbírán: „email“, „phone“, nebo null.
respondent_namestring | nullCelé jméno, pokud byla zodpovězena otázka na jméno.
total_scorenumberCelkové skóre respondenta.
max_scorenumberMaximální možné skóre.
score_percentnumberSkóre vyjádřené v procentech.
tierstring | nullPopisek odpovídající bodovací úrovně (kvízy s jedním skóre).
scoresobject | nullSkóre po kategoriích u kvízů s více skóre; jinak null.
outcomestring | nullKlíč odpovídajícího primárního výsledku (pouze Pro systém výsledků).
outcomesstring[] | nullKlíče všech odpovídajících výsledků.
disqualifiedbooleanZda byl respondent diskvalifikován.
answersobjectVnořené sekce/otázky/odpovědi — viz níže.
submitted_atstringČasové razítko odeslání ve formátu ISO 8601.

Odeslání jen některých polí

Webhook lze nastavit tak, aby odesílal jen vybranou podmnožinu výše uvedených polí. submission_id a test_id jsou vždy zahrnuty bez ohledu na tento výběr, takže každý payload lze dohledat ke zdroji.

Režim mapovaného payloadu

Pokud je pro webhook nastaveno mapování polí (viz Mapování polí a opakování synchronizací), tvar payloadu se změní: mapovaná pole vytvořená pravidly mapování nahradí plochou strukturu, spolu s případnými štítky, a celý výchozí payload je beze změny zahrnut pod klíčem raw.

{
  "mapped": { "email": "[email protected]", "score": 82 },
  "tags": ["High fit"],
  "raw": { "submission_id": "8f2b1c3a-...", "...": "..." }
}

Ověření podpisu

Pokud je nastaven podpisový klíč, každý požadavek obsahuje hlavičku X-FluoTest-Signature: hexadecimální HMAC-SHA256 otisk přesného těla požadavku, vypočtený se sdíleným klíčem a s prefixem sha256=. Na přijímací straně spočítejte stejný otisk z nezměněného těla požadavku a porovnejte ho s hlavičkou, abyste ověřili, že požadavek pochází z FluoTestu a nebyl cestou pozměněn.

const crypto = require("crypto");

function isValidSignature(rawBody, header, secret) {
  const expected = "sha256=" + crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex");
  return header === expected;
}

Doručení, opakování a selhání

Webhook požadavek má časový limit 10 sekund. Odpověď mimo rozsah 2xx je považována za neúspěšné doručení. Neúspěšná doručení se automaticky opakují — viz Mapování polí a opakování synchronizací pro harmonogram opakování a způsob zaznamenávání selhání.

Často kladené otázky

Co spouští webhook ve FluoTestu?

Webhook se spustí jednou při každém odeslání kvízu, s typem události submission.created. V současnosti neexistuje žádný jiný typ události.

Jak ověřím hlavičku X-FluoTest-Signature?

Spočítejte HMAC-SHA256 otisk nezměněného těla požadavku pomocí podpisového klíče nastaveného pro webhook, zakódujte ho hexadecimálně, přidejte prefix sha256= a porovnejte ho s hodnotou hlavičky pomocí porovnání v konstantním čase.

Co se stane, když je můj endpoint nedostupný nebo vrátí chybu?

Doručení se označí jako neúspěšné a automaticky se opakuje s prodlevou, až 3 další pokusy, pokud selhání není považováno za trvalé.

Můžu si vybrat, která pole se v payloadu odešlou?

Ano. Webhook lze nastavit s konkrétním seznamem polí; do každého požadavku se zahrnou jen tato pole plus submission_id a test_id.