- Dokumentasjon
- Grunnlag
Webhooks
Motta hendelser fra alle produktene som signerte HTTP-kall, med gjenforsøk i 72 timer, leveringslogg og mulighet for å sende på nytt.
Webhooks er hvordan Spire forteller deg at noe har skjedd: en faktura er betalt, et dokument er signert, et selskap har byttet daglig leder. Du registrerer en URL, og vi sender hendelser dit som POST-kall.
Registrere en webhook
curl -X POST https://api.spireapi.com/v1/webhooks \
-H "Authorization: Bearer sk_live_…" \
-H "Content-Type: application/json" \
-d '{
"url": "https://din.app/spire-webhook",
"hendelser": ["faktura.*", "signering.fullfort"],
"beskrivelse": "Fakturasystemet"
}'
Ved opprettelse sender vi en testhendelse (test.ping) og krever et 2xx-svar innen 10 sekunder. Svaret inneholder hemmelighet (whsec_…) som vises bare denne ene gangen. Du kan ha opptil 20 webhooks per miljø, med forskjellige hendelser og URL-er.
Jokertegn støttes: * for alt, faktura.* for alle fakturahendelser. Alle hendelsestyper står i referansen.
Konvolutten
Alle hendelser har samme form:
{
"id": "evt_01JBXB7Q2M",
"type": "faktura.betalt",
"opprettet": "2026-11-03T10:11:02Z",
"api_versjon": "2026-09-01",
"konto": "kto_01HZ…",
"data": { "id": "fak_01JBX4R8Q2M7", "status": "betalt", "…": "…" },
"forsok": 1
}
data er objektet slik GET ville returnert det da hendelsen skjedde, i API-versjonen webhooken ble opprettet med. Hvis du trenger gjeldende tilstand (objektet kan ha endret seg siden), gjør et GET-kall.
Verifisere signaturen
Hvert kall har hodet Spire-Signature:
Spire-Signature: t=1762164662,v1=5f8a3c…
t er Unix-tid for sendingen, v1 er HMAC-SHA256 av t + "." + kropp med hemmeligheten som nøkkel. Verifiser alltid, og avvis hendelser der t er mer enn 5 minutter gammel, for å stoppe gjentakelsesangrep.
import { createHmac, timingSafeEqual } from 'node:crypto';
export function verifiser(kropp, hode, hemmelighet) {
const { t, v1 } = Object.fromEntries(hode.split(',').map((d) => d.split('=')));
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) throw new Error('For gammel');
const forventet = createHmac('sha256', hemmelighet).update(`${t}.${kropp}`).digest('hex');
if (!timingSafeEqual(Buffer.from(forventet), Buffer.from(v1))) throw new Error('Ugyldig signatur');
return JSON.parse(kropp);
}
import hmac, hashlib, json, time
def verifiser(kropp: bytes, hode: str, hemmelighet: str) -> dict:
deler = dict(d.split("=") for d in hode.split(","))
if abs(time.time() - int(deler["t"])) > 300:
raise ValueError("For gammel")
forventet = hmac.new(hemmelighet.encode(), f"{deler['t']}.".encode() + kropp, hashlib.sha256).hexdigest()
if not hmac.compare_digest(forventet, deler["v1"]):
raise ValueError("Ugyldig signatur")
return json.loads(kropp)
Bruk den rå kroppen, ikke en som er parset og serialisert på nytt. SDK-ene har webhooks.verifiser() som gjør alt dette.
Svar raskt, behandle senere
Svar 2xx innen 10 sekunder. Alt annet regnes som feil. Den tryggeste modellen er: verifiser signaturen, legg hendelsen i en kø, svar 200, og behandle fra køen. Da påvirker ikke en treg database leveringen.
Gjenforsøk
Får vi ikke 2xx, prøver vi igjen med økende mellomrom: 1 min, 5 min, 30 min, 2 t, 6 t, 12 t, deretter hver 12. time til 72 timer er gått. Etter det markeres hendelsen som feilet, og du får e-post. Feilede hendelser kan sendes på nytt fra dashbordet eller via POST /v1/webhooks/{id}/leveranser/{hendelse_id}/send.
Hvis en webhook feiler for over 500 hendelser på rad, settes den på pause og du får e-post. Hendelser samles opp, og alle sendes når du aktiverer den igjen.
Duplikater
Vi leverer minst én gang. I sjeldne tilfeller (for eksempel når du svarte 200 men svaret gikk tapt) kommer samme hendelse to ganger. Lagre id for behandlede hendelser i minst 72 timer, og hopp over dem du har sett.
Rekkefølge
Hendelser for samme objekt leveres normalt i rekkefølge, men det er ikke garantert, særlig under gjenforsøk. Bruk opprettet eller objektets tilstand, ikke rekkefølgen hendelsene kommer i. faktura.betalt som kommer før faktura.sendt betyr at fakturaen er betalt.
Forsinkelse
Normalt leveres hendelser innen 2 sekunder. Statussiden viser gjeldende forsinkelse. Ved kø over 60 sekunder leverer vi uten rekkefølgegaranti for å ta igjen, som beskrevet i postmortem fra 12. september. Bygg aldri logikk som antar at en hendelse kommer innen n sekunder.
Leveringslogg
Alle leveringsforsøk med statuskode, svartid og kroppen vi sendte ligger i dashbordet og under GET /v1/webhooks/{id}/leveranser. Oppbevaring: 7 dager på Start, 30 på Vekst, 90 på Skala, 13 måneder på Enterprise.
Testing lokalt
Sandkassen sender ekte webhooks, også til localhost hvis du bruker en tunnel. Dashbordet har en «Send testhendelse»-knapp for hver hendelsestype med realistisk innhold. I CI kan du opprette en webhook mot en testserver, utløse et scenario, og vente på hendelsen.