StriseWiki
API

Webhooks

AlphaUtgående webhooks er i Alfa. Kontakt Strise hvis du ønsker tilgang.

Strise kan sende hendelser til et HTTPS-endepunkt du kontrollerer. Når noe vesentlig skjer i porteføljen din – en vurdering fullføres, et kundevendt skjema endrer status – sender Strise en signert HTTP-forespørsel til serveren din i nær sanntid, slik at systemene dine kan reagere uten polling.

Hvor det konfigureres

Administrer abonnementer under Innstillinger → Team → Webhooks. Bare teamledere kan opprette eller redigere dem. Hvert abonnement har en endepunkt-URL, settet med hendelsestyper du ønsker, og en aktiveringsbryter.

Webhooks-siden i teaminnstillinger

Støttede hendelser

HendelsestypeNår den utløses
review.completedEn vurdering er ferdig behandlet og resultatet er klart. Nyttelasten inkluderer vurderings-ID-en og entiteten den ble kjørt på.
form.status.changedEt kundevendt skjema har endret status (f.eks. PENDINGIN_PROGRESSSUCCESS). Nyttelasten inkluderer skjemainstansens ID, entiteten, samt gammel og ny status. Statusverdiene samsvarer med GraphQL-enumen DocumentStatus.
entity.disposition.createdNoen verifiserte et screening-treff på en entitet – bekreftet det som et reelt treff eller avkreftet det som falskt treff. Nyttelasten inkluderer entitets-ID-en, ID-en til treffet som ble verifisert (externalId), kind (Pep eller Sanction), status (ConfirmedTrue eller ConfirmedFalse), brukeren som verifiserte det, og tidspunkt.

Flere hendelser vil bli lagt til over tid. Kontakt Strise hvis det er noen du gjerne skulle sett.

newStatusform.status.changed kan også være INCONCLUSIVE – skjemaet ble fullført, men dokumentverifiseringstrinnet kunne ikke avgjøres entydig.

Send en testhendelse

Når et abonnement er aktivt, kan du utløse en reell levering ved behov for å sjekke endepunktet ditt – du trenger ikke vente på at en ekte vurdering blir ferdig eller at et skjema endrer status. Under Innstillinger → Team → Webhooks, bruk abonnementets handling Send mock event, velg en av hendelsestypene det abonneres på, se over JSON-nyttelasten og send.

Strise publiserer testhendelsen gjennom den samme pipelinen som en produksjonslevering: den samme signerte konvolutten og OIDC-tokenet, sendt til endepunktet du registrerte. En testhendelse tester derfor signaturverifiseringen og håndtereren din ende-til-ende, mot en nyttelast du kan se på forhånd. Sending er begrenset til teamledere, og kun mens abonnementet er aktivt.

Samme hendelses-ID ved hver gjenutsending

Å sende den samme mock-hendelsen på nytt produserer en levering med samme id hver gang. Dette er tilsiktet: det lar deg bekrefte at dedupliseringen fungerer. En mottaker som dedupliserer på hendelsens id behandler den første leveringen og ignorerer identiske resendinger – så hvis en gjentatt testhendelse slutter å dukke opp nedstrøms, gjør dedupliseringen jobben sin.

Hva du mottar

En HTTPS POST til endepunktet du registrerte, med:

  • Headeren Authorization: Bearer <JWT> – tokenet du verifiserer (nedenfor).
  • Hendelsen som rå JSON-body. Konvolutten inneholder alt du trenger for å identifisere, rute og deduplisere en levering – ingen andre headere kreves for 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"
  }
}

Endepunktet ditt må være HTTPS – Strise vil ikke sende til vanlig HTTP, og nyttelastens integritet under overføring avhenger av TLS. Se Bekrefte leveringen nedenfor for hvordan du svarer.

Verifisere signaturen

Hver levering har en Authorization: Bearer <JWT>-header som inneholder et Google-utstedt OIDC-token, signert på vegne av Strises tjenestekonto for levering. Verifisering beviser at forespørselen kom fra Strise og nådde deg uendret. Verifiser det før du stoler på nyttelasten.

Hva du skal verifisere mot

ClaimForventet verdi
signatureGoogles offentlige nøkler (JWKS): https://www.googleapis.com/oauth2/v3/certs
isshttps://accounts.google.com
emailwebhook-delivery@strise-prod.iam.gserviceaccount.com
audden nøyaktige endepunkt-URL-en du registrerte for abonnementet
expmå være i fremtiden

email er en fast Strise-verdi (ovenfor). aud er den endepunkt-URL-en du oppga da du opprettet abonnementet – Strise setter tokenets audience til ditt push-endepunkt.

⚠️ Regelen som betyr mest

En gyldig Google-signatur alene beviser ikke at forespørselen er fra Strise. Hvem som helst med en Google Cloud-konto kan hente et Google-signert OIDC-token (iss: https://accounts.google.com, gyldig signatur). Det som knytter et token til Strise er email-claimet (tjenestekontoen for levering) sammen med aud-claimet (endepunktet ditt).

Sjekk alltid både email og aud etter at signaturen er verifisert. Å bare verifisere signaturen eller bare utstederen gjør deg sårbar for spoofing.

Verifiseringstrinn

  1. Ekstraher tokenet fra Authorization: Bearer-headeren.
  2. Hent Googles offentlige nøkler (bibliotekene nedenfor cacher og roterer dem for deg).
  3. Verifiser signaturen og standard claims (iss, exp).
  4. Kontroller at aud er lik din registrerte endepunkt-URL.
  5. Kontroller at email er lik webhook-delivery@strise-prod.iam.gserviceaccount.com (og at email_verified er true).
  6. Først da kan du stole på og behandle hendelsens JSON i forespørselskroppen.

Kodeeksempler

Hvert eksempel verifiserer headeren og returnerer claims ved suksess. Erstatt EXPECTED_AUDIENCE med endepunkt-URL-en du registrerte.

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
}

Bekrefte leveringen

Svar med en vilkårlig 2xx-statuskode for å bekrefte mottak. Et svar som ikke er 2xx (eller et tidsavbrudd) fører til at Strise prøver å sende den samme nyttelasten på nytt.

Bekreft alltid mottak, selv om din egen behandling feiler. Hvis din nedstrømshåndterer feiler – en databaseskriving kaster en feil, køen din er full, et unntak bobler opp – svar likevel 2xx og håndter feilen på din side (loggfør, varsle, prøv igjen fra din egen kø). En respons som ikke er 2xx forteller Strise at meldingen ikke nådde frem til deg, så vi fortsetter å prøve den identiske nyttelasten på nytt. Det løser sjelden en nedstrømsfeil og forsterker bare støyen på din side.

Vanlige feilsituasjoner

  • Verifisere signaturen, men ikke email/aud – signaturen beviser bare at Google utstedte tokenet, ikke at Strise gjorde det. Sjekk alltid begge claims. Dette er den vanligste feilen.
  • Dekoding uten verifisering – base64-dekoding av JWT-bodyen for å lese claims, uten å validere signaturen, stoler på data fra en angriper. Bruk et bibliotek som verifiserer.
  • Feil aud – audience må være nøyaktig lik endepunkt-URL-en du registrerte (URL-en Strise sender til), ikke et tjenestenavn eller en annen sti.
  • Klokkeavvik (clock skew)exp er omtrent én time frem i tid. Hvis serverens klokke avviker, blir gyldige tokens avvist. Hold den NTP-synkronisert; bibliotekene ovenfor tolererer noen sekunders avvik.
  • Fjernet Authorization-header – enkelte lastbalanserer og API-gatewayer fjerner eller omskriver Authorization. Sørg for at den når applikasjonen din intakt.
  • Nøkkelrotasjon – Google roterer signeringsnøklene sine periodisk. Alle de tre bibliotekene henter og cacher JWKS og følger rotasjonen automatisk; lås aldri en nøkkel.
  • Replay-angrep (replays) – et fanget token er gyldig frem til exp (~1 time). Dedupliser på hendelsens id i nyttelasten (stabil på tvers av gjentatte leveringer), slik at reprosessering er ufarlig.

Sist oppdatert

På denne siden