StriseWiki
API

Webhooks

AlphaUdgående webhooks er i Alfa. Kontakt Strise, hvis du ønsker adgang.

Strise kan sende hændelser til et HTTPS-endpoint, du kontrollerer. Når der sker noget væsentligt i din portefølje – en vurdering fuldføres, en kundehenvendt formular ændrer status – sender Strise en signeret HTTP-anmodning til din server i næsten realtid, så dine systemer kan reagere uden polling.

Hvor det konfigureres

Administrer abonnementer under Settings → Team → Webhooks. Kun teamledere kan oprette eller redigere dem. Hvert abonnement har en endpoint-URL, de ønskede hændelsestyper og en aktiv-knap.

Webhooks-side i teamindstillinger

Understøttede hændelser

HændelsestypeHvornår den udløses
review.completedEn vurdering er færdigbehandlet, og dens resultat er klar. Payloaden indeholder vurderings-id'et og den entitet, den blev udført på.
form.status.changedEn kundehenvendt formular har ændret status (f.eks. PENDINGIN_PROGRESSSUCCESS). Payloaden indeholder formularinstans-id'et, entiteten samt den gamle og nye status. Statusværdier matcher DocumentStatus-GraphQL-enum'en.
entity.disposition.createdNogen har verificeret et screening-hit på en entitet – bekræftet det som et sandt eller et falsk match. Payloaden indeholder entitets-id'et, id'et på det hit, der blev verificeret (externalId), kind (Pep eller Sanction), status (ConfirmedTrue eller ConfirmedFalse), brugeren, der verificerede det, samt tidspunktet.

Flere hændelser vil blive tilføjet over tid. Kontakt Strise, hvis der er en, du gerne vil se.

newStatusform.status.changed kan også være INCONCLUSIVE – formularen blev udfyldt, men dokumentverifikationstrinnet kunne ikke afklares endeligt.

Send en testhændelse

Når et abonnement er aktivt, kan du udløse en rigtig levering efter behov for at tjekke dit endpoint – uden at skulle vente på, at en live-vurdering afsluttes, eller en formular ændrer status. Under Settings → Team → Webhooks bruger du abonnementets handling Send mock event, vælger en af de hændelsestyper, det abonnerer på, gennemgår JSON-payloaden og sender.

Strise udgiver testhændelsen gennem den samme pipeline som en produktionslevering: den samme signerede kuvert og OIDC-token, sendt til det endpoint, du har registreret. En testhændelse afprøver derfor din signaturverifikation og din handler fra start til slut mod en payload, du kan se på forhånd. Afsendelse er begrænset til teamledere og kun, mens abonnementet er aktivt.

Samme hændelses-id ved hver genafsendelse

Genafsendelse af den samme mock-hændelse genererer en levering med det samme id hver gang. Dette er tilsigtet: Det giver dig mulighed for at bekræfte, at din deduplikering fungerer. En modtager, der deduplikerer på hændelsens id, behandler den første levering og ignorerer identiske genafsendelser – så hvis en gentaget testhændelse ikke længere dukker op downstream, gør din deduplikering sit arbejde.

Hvad du modtager

Et HTTPS POST til det endpoint, du registrerede, med:

  • Headeren Authorization: Bearer <JWT> – det token, du verificerer (nedenfor).
  • Hændelsen som den rå JSON-brødtekst. Kuverten indeholder alt, hvad du behøver for at identificere, dirigere og deduplikere en levering – ingen andre headers er påkrævet til behandlingen.
{
  "id": "4bdf74b2-0d8e-3379-9739-cba7db9b602d",
  "version": "1",
  "eventType": "form.status.changed",
  "teamId": "b07e18b1-45bf-4d5d-877e-ad0374d70111",
  "subscriptionId": "76a48168-145b-495a-8cec-0ee929d8c15c",
  "timestamp": "2026-05-27T12:41:58.985818515",
  "data": {
    "formInstanceId": "…",
    "entityId": "…",
    "entityKind": "Company",
    "oldStatus": "IN_PROGRESS",
    "newStatus": "SUCCESS"
  }
}

Dit endpoint skal være HTTPS – Strise sender ikke til almindelig HTTP, og payloadens integritet under overførslen afhænger af TLS. Se Bekræftelse af leveringen nedenfor for at se, hvordan du svarer.

Verifikation af signaturen

Hver levering indeholder en Authorization: Bearer <JWT>-header med et Google-udstedt OIDC-token, signeret på vegne af Strises servicekonto til levering. Verificering af dette beviser, at anmodningen kom fra Strise og nåede frem til dig uændret. Verificer det, før du stoler på payloaden.

Hvad der skal verificeres mod

ClaimForventet værdi
signatureGoogles offentlige nøgler (JWKS): https://www.googleapis.com/oauth2/v3/certs
isshttps://accounts.google.com
emailwebhook-delivery@strise-prod.iam.gserviceaccount.com
audden nøjagtige endpoint-URL, du registrerede for abonnementet
expskal være i fremtiden

email er en fast Strise-værdi (ovenfor). aud er den endpoint-URL, du indtastede, da du oprettede abonnementet – Strise sætter tokenets audience til dit push-endpoint.

⚠️ Den vigtigste regel

En gyldig Google-signatur alene beviser ikke, at anmodningen er fra Strise. Enhver med en Google Cloud-konto kan hente et Google-signeret OIDC-token (iss: https://accounts.google.com, gyldig signatur). Det, der knytter et token til Strise, er email-claimet (leverings-servicekontoen) sammen med aud-claimet (dit endpoint).

Tjek altid både email og aud efter verificering af signaturen. Hvis du kun verificerer signaturen eller kun udstederen (issuer), er du sårbar over for spoofing.

Verifikationstrin

  1. Udtræk tokenet fra Authorization: Bearer-headeren.
  2. Hent Googles offentlige nøgler (bibliotekerne nedenfor cacher og roterer dem for dig).
  3. Verificer signaturen og standard-claims (iss, exp).
  4. Bekræft, at aud matcher din registrerede endpoint-URL.
  5. Bekræft, at email matcher webhook-delivery@strise-prod.iam.gserviceaccount.com (og email_verified er true).
  6. Først derefter kan du stole på og behandle hændelsens JSON i anmodningens brødtekst.

Kodeeksempler

Hvert eksempel verificerer headeren og returnerer claims ved succes. Erstat EXPECTED_AUDIENCE med den endpoint-URL, du har registreret.

Node.js — google-auth-library

import { OAuth2Client } from 'google-auth-library'

const client = new OAuth2Client()
const EXPECTED_EMAIL = 'webhook-delivery@strise-prod.iam.gserviceaccount.com'
const EXPECTED_AUDIENCE = 'https://your-domain.example.com/strise-webhook'

// Throws if the token is missing, invalid, expired, or not issued by Strise.
export async function verifyStriseWebhook(authorizationHeader) {
  if (!authorizationHeader?.startsWith('Bearer ')) throw new Error('missing bearer token')
  const token = authorizationHeader.slice('Bearer '.length)

  // Verifies the Google signature (JWKS), iss, exp, and aud.
  const ticket = await client.verifyIdToken({ idToken: token, audience: EXPECTED_AUDIENCE })
  const claims = ticket.getPayload()
  if (claims.email !== EXPECTED_EMAIL || claims.email_verified !== true) {
    throw new Error('token not issued by Strise')
  }
  return claims
}

Python — google-auth

from google.oauth2 import id_token
from google.auth.transport import requests as google_requests

EXPECTED_EMAIL = "webhook-delivery@strise-prod.iam.gserviceaccount.com"
EXPECTED_AUDIENCE = "https://your-domain.example.com/strise-webhook"

def verify_strise_webhook(authorization_header: str) -> dict:
    if not authorization_header.startswith("Bearer "):
        raise ValueError("missing bearer token")
    token = authorization_header[len("Bearer "):]

    # Verifies the Google signature (JWKS), iss, exp, and aud.
    claims = id_token.verify_oauth2_token(token, google_requests.Request(), audience=EXPECTED_AUDIENCE)
    if claims.get("email") != EXPECTED_EMAIL or not claims.get("email_verified"):
        raise ValueError("token not issued by Strise")
    return claims

Go — google.golang.org/api/idtoken

import (
	"context"
	"fmt"
	"strings"

	"google.golang.org/api/idtoken"
)

const (
	expectedEmail    = "webhook-delivery@strise-prod.iam.gserviceaccount.com"
	expectedAudience = "https://your-domain.example.com/strise-webhook"
)

// VerifyStriseWebhook returns the verified claims, or an error if the token is
// missing, invalid, expired, or not issued by Strise.
func VerifyStriseWebhook(ctx context.Context, authorizationHeader string) (*idtoken.Payload, error) {
	token := strings.TrimPrefix(authorizationHeader, "Bearer ")
	if token == authorizationHeader {
		return nil, fmt.Errorf("missing bearer token")
	}

	// Validate verifies the Google signature (JWKS), iss, exp, and aud.
	payload, err := idtoken.Validate(ctx, token, expectedAudience)
	if err != nil {
		return nil, err
	}
	if payload.Claims["email"] != expectedEmail || payload.Claims["email_verified"] != true {
		return nil, fmt.Errorf("token not issued by Strise")
	}
	return payload, nil
}

Bekræftelse af leveringen

Svar med enhver 2xx-statuskode for at bekræfte modtagelsen. Et ikke-2xx-svar (eller et timeout) får Strise til at forsøge at sende den samme payload igen.

Bekræft altid, selv hvis din egen behandling mislykkes. Hvis din downstream-handler fejler – en databaseskrivning kaster en fejl, din kø er fuld, eller en undtagelse bobler op – skal du stadig svare 2xx og håndtere fejlen på din egen side (log, alarmér, genprøv fra din egen kø). En ikke-2xx fortæller Strise, at beskeden ikke nåede frem til dig, så vi bliver ved med at forsøge at levere den identiske payload igen. Det løser sjældent en downstream-fejl og forstærker blot støjen i dit system.

Almindelige fejlscenarier

  • Verificering af signaturen, men ikke email/aud – signaturen beviser kun, at Google udstedte tokenet, ikke at Strise gjorde det. Tjek altid begge claims. Dette er den mest almindelige fejl.
  • Afkodning uden verificering – base64-afkodning af JWT-brødteksten for at læse claims, uden at validere signaturen, har tillid til data leveret af en angriber. Brug et bibliotek, der verificerer.
  • Forkert aud – audience skal svare nøjagtigt til den endpoint-URL, du har registreret (den URL, Strise sender til), ikke et servicenavn eller en anden sti.
  • Tidsforskel (clock skew)exp er sat til cirka en time frem i tiden. Hvis dit servers ur driver, bliver gyldige tokens afvist. Hold uret NTP-synkroniseret; ovenstående biblioteker tolererer et par sekunders afvigelse.
  • Fjernet Authorization-header – visse load balancere og API gateways fjerner eller omskriver Authorization. Sørg for, at den når intakt frem til din applikation.
  • Nøglerotation – Google roterer sine signeringsnøgler regelmæssigt. Alle tre biblioteker henter og cacher JWKS og følger rotationen automatisk; fastlås (pin) aldrig en nøgle.
  • Genafspilninger (replays) – et opsnappet token er gyldigt indtil exp (~1 time). Deduplikér på hændelsens id i payloaden (stabil på tværs af genleveringer), så genbehandling er ufarlig.

Sidst opdateret

På denne side