SDK in abbonamento
OAuth per utente · limiti del piano condivisi tra le app · modello gestito da Pura.
Cerchi le API a consumo?Webhook di lifecycle
Firma HMAC, retry, identità e applicazione atomica degli eventi.
Configura il ricevitore
Il proprietario dell’app configura un endpoint HTTPS pubblico nella console o con PUT /v1/integrations/apps/{client_id}/webhook. Salva il signing_secret restituito sul tuo server per verificare le richieste ricevute. I webhook sono opzionali: usali per aggiornare lo stato dei collegamenti e dell’abbonamento nella tua app.
Il ricevitore deve essere raggiungibile pubblicamente e rispondere direttamente, senza redirect. Gli indirizzi locali o privati non sono ammessi. Un test restituisce 202 e stato queued: verifica delivered nella console per confermare la consegna.
Eventi e payload
Eventi: integration.connected, integration.revoked, subscription.updated, subscription.ended, integration.test. L’envelope contiene api_version, event_id, event, integration_id, sequence, created, user e data. Correlalo al client_id registrato e al pura_user_id già verificato durante OAuth.
Gli eventi subscription sono snapshot di lifecycle e non un feed di addebiti per richiesta. paid_period contiene percentuali e servizi disponibili, senza identificativi di modello. Usa usage() per il consumo corrente. Il server Pura resta autorevole e verifica i limiti a ogni richiesta.
Verifica i byte originali
Header X-Pura-Signature: t=<unix-seconds>,v1=<hex-HMAC-SHA256>. La firma copre timestamp UTF-8, un punto e i byte originali del body. La tolleranza predefinita è ±300 secondi. Parsing e successiva serializzazione JSON cambiano i byte e non devono precedere la verifica.
import {verifyWebhook} from '@pura-ai/sdk';
const rawBody = new Uint8Array(await request.arrayBuffer());
const event = await verifyWebhook(rawBody, request.headers, {
signingSecret: serverSigningSecret,
integrationId: registeredClientId,
});Idempotenza transazionale
processOnce(eventId, handler) deve verificare l’ID, applicare handler e salvare l’ID nella stessa transazione condivisa da tutti i worker. Restituisce false per un evento già committato. Un errore deve fare rollback anche del marker; restituisci 2xx soltanto dopo il commit.
Per email o altri effetti esterni usa un tuo outbox transazionale. Il marker nel database non rende atomica una chiamata a un servizio esterno. process_once è l’interfaccia equivalente Python.
Handler del ricevitore
Il callback onEvent deve usare lo stesso contesto transazionale di processOnce. L’helper verifica firma e app prima di invocare lo store, poi restituisce event_id e duplicate. Restituisci questa risposta con HTTP 200 soltanto quando la Promise termina.
import {createWebhookHandler} from '@pura-ai/sdk';
const receive = createWebhookHandler({
signingSecret: serverSigningSecret,
integrationId: registeredClientId,
store: persistentEventStore,
onEvent: async event => applyEventInTheSameTransaction(event),
});
const result = await receive(rawBody, request.headers);
// Return HTTP 200 after processOnce committed.
// A verification error must not be acknowledged as a valid event.Ordine, retry e rotazione
sequence è monotona per app. Il ricevitore deve scartare snapshot vecchi e rilevare gap; l’SDK non applica automaticamente l’ordine. Nei retry event_id, created e sequence restano uguali, mentre il timestamp firmato cambia. Pura usa fino a otto tentativi con backoff.
La configurazione restituisce una nuova generazione e un nuovo signing secret. Coordina la sostituzione con il ricevitore e controlla gli eventi nella console. Retry e skip sono azioni manuali di recupero: skip va usato soltanto quando puoi accettare l’evento mancante.