Salta ai contenuti

Buste e destinatari

Una busta è un contratto in procinto di essere firmato: una versione di un modello composta con le Sue variabili, i destinatari che intervengono su di essa e le prove di tutto ciò che accade. La crei con POST /v1/envelopes.

Campo Tipo Note
template tpl_… Obbligatorio
version numero o "latest" Predefinito latest; risolto e fissato alla creazione. Deve essere pubblicata
variables oggetto Convalidato rispetto al JSON Schema della versione
recipients array Uno per ruolo (role, name, email; facoltativi externalUserId, verification, fields per precompilare in base all’id del campo, order per cambiare l’ordine di firma)
subject, message stringa Usati nelle e-mail di firma e mostrati nella pagina di firma
delivery email · embedded · none Predefinito email
expiresAt RFC 3339 Deve essere nel futuro; a quella data la busta scade e i link di firma e degli osservatori smettono di funzionare
cc array Destinatari in CC aggiuntivi (name, email) oltre ai ruoli in CC del modello; fino a 50
viewers array Persone che seguono la busta senza firmare (name, email, facoltativo notifyOnSignature); numero limitato per busta in base al piano
viewerDocumentAccess booleano Consente agli osservatori di aprire il documento nella loro pagina di stato. Predefinito false (solo stato); dal piano Team in su
reminders oggetto { "enabled": false } disattiva i promemoria; { "enabled": true, "intervalHours": 24 } cambia l’intervallo (da 1 a 720)
externalId stringa Un Suo id, fino a 200 caratteri
dedupeOn "external_id" Restituisce la busta esistente con questo externalId invece di crearne un’altra
metadata oggetto di stringhe Fino a 500 caratteri per valore; restituito nella busta e nei webhook

Ogni destinatario deve avere un ruolo della versione; ogni ruolo non CC deve avere esattamente un destinatario. Gli errori vengono segnalati tutti insieme, con puntatori come /recipients/1/role o /recipients/0/fields/start_date.

Risposte: 201 con la busta e un header Location; 200 con la busta esistente e x-deduplicated: true quando dedupeOn trova una corrispondenza; 200 con un riepilogo della simulazione per ?dry_run=true; 402 quando un workspace Free ha esaurito le buste incluse; 403 plan-upgrade-required quando gli osservatori superano quanto previsto dal piano o viewerDocumentAccess non è incluso nel piano (Piani e limiti). Anche le simulazioni controllano i limiti del piano.

Ogni campo aggiunto dopo la prima release è facoltativo: una richiesta senza di essi si comporta esattamente come prima.

Il modello definisce chi firma e in quale ordine. Per una singola busta può cambiarlo senza modificare il modello:

{
"template": "tpl_9fK2mQ7xLp",
"variables": { "client": { "name": "Jane Doe" } },
"recipients": [
{ "role": "client", "name": "Jane Doe", "email": "jane@acme.dev", "order": 2 },
{ "role": "company", "name": "Sam Lee", "email": "sam@bonafide.dev", "order": 1 },
{ "role": "witness", "name": "Kim Park", "email": "kim@acme.dev", "order": 1 }
],
"cc": [{ "name": "Legal", "email": "legal@acme.dev" }],
"viewers": [{ "name": "Alex Chen", "email": "alex@acme.dev", "notifyOnSignature": true }],
"reminders": { "enabled": true, "intervalHours": 48 },
"expiresAt": "2026-11-30T23:59:59Z"
}
  • Ordine: recipients[].order è il passaggio in cui il destinatario firma; i destinatari con lo stesso numero firmano contemporaneamente. Se manca, si applica l’order del ruolo definito nel modello. Gli ordini sono interi positivi; i ruoli in CC non possono essere ordinati; ogni ruolo ha comunque bisogno del suo destinatario (così i campi del modello mantengono il loro firmatario); almeno un destinatario deve firmare. L’evento envelope.created registra routingOverridden: true.
  • CC: i destinatari in CC aggiuntivi ricevono l’e-mail con il documento completato e non firmano mai. Compaiono in recipients con kind: "cc" e il ruolo _cc.
  • Promemoria: chi è di turno riceve un promemoria ogni intervalHours (predefinito: il valore REMINDER_INTERVAL_HOURS dell’installazione, 72), al massimo tre volte; con enabled: false non ne viene inviato nessuno. I promemoria si applicano alla consegna email.
  • L’autenticazione del firmatario è per destinatario: verification sostituisce il metodo del ruolo. Sono disponibili oggi none (solo il link di firma univoco, il valore predefinito per i ruoli che non ne impostano uno) ed email_otp (il link più un codice inviato via e-mail); passkey e id_check vengono rifiutati perché non ancora disponibili. Veda verifica del firmatario.
  • Lingua: locale su un destinatario, un CC o un osservatore (o sulla busta, per tutti quelli che non ne hanno una propria) imposta la lingua della pagina di firma e delle e-mail, scelta tra le 50 lingue di firma. Se manca, la pagina di firma segue il browser e le e-mail sono in inglese.

La schermata di invio della dashboard offre le stesse opzioni: spostare i passaggi prima o dopo, selezionare Firma contemporanea, aggiungere CC e osservatori, scegliere l’autenticazione di ciascun firmatario (Solo link via e-mail o Link via e-mail + codice) e la lingua, e impostare una data di scadenza e una pianificazione dei promemoria.

  • email: ogni destinatario riceve via e-mail un link alla pagina di firma ospitata quando è il suo turno. I destinatari che non hanno firmato ricevono un promemoria ogni pochi giorni (fino a tre) e tutti ricevono un’e-mail quando la busta viene completata.
  • embedded: nessuna e-mail ai firmatari. Crei una sessione di firma quando il firmatario si trova nel Suo prodotto. Gli osservatori ricevono comunque via e-mail il loro link di stato.
  • none: nessuna e-mail (osservatori compresi); da usare quando i link li consegna Lei (sessioni ospitate).

POST /v1/envelopes/{id}/recipients/{recipient}/resend invia via e-mail un nuovo link a un destinatario di turno (al massimo una volta al minuto).

┌──────────── declined (a signer declined)
│
sent ─────┼──────────── voided (POST /v1/envelopes/{id}/void)
│
├──────────── expired (expiresAt passed)
│
└──────────── completed ──► seal: pending ──► sealed
status Significato
rendering In preparazione
sent In corso: i destinatari stanno firmando nell’ordine di instradamento
completed Tutti i destinatari hanno terminato. Inizia la sigillatura
declined Un destinatario ha rifiutato; la busta si chiude
voided L’ha annullata Lei ({ "reason": "…" }); le sessioni di firma aperte smettono di funzionare
expired expiresAt è trascorso prima del completamento

seal segue lo stato del PDF sigillato: not_started, pending (completata, in fase di sigillatura), sealed o failed. La sigillatura non blocca mai il completamento: la busta viene prima completata e subito dopo sigillata.

{
"id": "rcp_5Jw0pLs9Xe",
"role": "client",
"name": "Jane Doe",
"email": "jane@acme.dev",
"order": 1,
"status": "viewed",
"verification": "email_otp",
"completedAt": null
}

Lo status del destinatario è pending (non è ancora il suo turno), sent, viewed, completed o declined, e kind è quello del ruolo: signer, approver, form_filler o cc. L’instradamento segue order (quello del ruolo o la sostituzione all’invio): tutti i destinatari dell’ordine più basso non ancora concluso agiscono in parallelo e il gruppo successivo inizia quando hanno terminato. I destinatari in CC non bloccano mai l’instradamento.

Un osservatore segue una busta senza firmare: un responsabile, un assistente legale, il referente dell’account dal lato del cliente. Gli osservatori non sono destinatari. Non hanno un ruolo né un turno, non bloccano né completano mai nulla e non compaiono mai nell’elenco dei firmatari del certificato.

  • Quando la busta viene inviata (o quando li aggiunge in seguito con POST /v1/envelopes/{id}/viewers), ogni osservatore riceve un’e-mail con il marchio della Sua organizzazione e un link a una pagina di stato in sola lettura: il titolo della busta, il mittente, ogni passaggio con nomi, ruoli, stato e orari dei destinatari, aggiornata in tempo reale man mano che le persone firmano. Gli indirizzi e-mail dei destinatari non vengono mostrati.
  • Gli osservatori ricevono di nuovo un’e-mail quando la busta viene completata, rifiutata o annullata, e dopo ogni firma se notifyOnSignature è true (disattivato per impostazione predefinita).
  • Il documento compare nella pagina solo se imposta viewerDocumentAccess: true (dal piano Team in su): l’originale mentre è in corso, il PDF sigillato una volta sigillato. Altrimenti gli osservatori vedono solo lo stato.
  • DELETE /v1/envelopes/{id}/viewers/{viewer} revoca un osservatore: tutti i link che gli sono stati inviati smettono subito di funzionare.
  • I link sono URL di accesso personali. Di ogni token di link viene memorizzato solo uno SHA-256. Un link funziona fino alla scadenza della busta (al massimo 90 giorni), per 30 giorni dopo la conclusione della busta, e mai più una volta revocato l’osservatore.
  • L’aggiunta, l’apertura (prima visualizzazione della pagina e del documento) e la revoca vengono registrate nell’audit trail come viewer.added, viewer.viewed, viewer.document_viewed e viewer.revoked, e quindi nel certificato.

Le risposte relative a una singola busta (creazione, lettura, annullamento) li elencano:

{
"viewers": [
{
"id": "vwr_2Hc8sQ1nVt",
"name": "Alex Chen",
"email": "alex@acme.dev",
"notifyOnSignature": true,
"status": "active",
"invitedAt": "2026-10-13T13:58:04.512Z",
"firstViewedAt": "2026-10-13T14:05:41.090Z",
"lastViewedAt": "2026-10-13T15:12:09.337Z",
"revokedAt": null,
"createdAt": "2026-10-13T13:58:04.512Z"
}
],
"viewerDocumentAccess": false
}

Il numero di osservatori per busta dipende dal piano (Free 1, Pay-as-you-go 2, Team 5, Business 20, Platform illimitati); i destinatari in CC non vengono conteggiati. Gli osservatori revocati liberano il loro posto.

GET /v1/envelopes/{id}/document?version=… scarica un PDF, con il relativo SHA-256 in x-document-sha256:

version File
original (predefinito) Il documento composto così come è stato inviato per la firma
sealed Il PDF finale: valori appiattiti, certificato di completamento in coda, marca temporale. Dopo envelope.sealed
certificate Il solo certificato di completamento

Il documentHash della busta è lo SHA-256 dell’originale e sealedDocumentHash quello del file sigillato; sono questi i valori che la verifica cerca.

Ogni azione è un evento in una catena di hash propria della busta: hash = SHA-256(prevHash ‖ canonical JSON of the event), dove il primo prevHash è composto da 64 zeri. GET /v1/envelopes/{id}/events restituisce gli eventi e controlla la catena:

{
"data": [
{
"id": "evt_…",
"envelope": "env_8Gm2kQ4rT1",
"seq": 1,
"type": "envelope.created",
"createdAt": "2026-10-13T13:58:04.512Z",
"recipient": null,
"actor": { "kind": "api_key", "id": "…", "name": null, "email": null },
"ip": "203.0.113.7",
"userAgent": null,
"data": { "template": "tpl_…", "templateVersion": 3, "documentHash": "9f2c…" },
"hash": "4b1d…",
"prevHash": "0000000000000000000000000000000000000000000000000000000000000000"
}
],
"chain": { "valid": true, "brokenAt": null }
}

Oltre ai tipi di evento webhook, l’audit trail contiene voci solo di audit come session.created, recipient.verified, recipient.reminded e gli eventi degli osservatori (tipo di attore viewer quando un osservatore apre la sua pagina).

Per uno stato in tempo reale in un’interfaccia, GET /v1/envelopes/{id}/events/stream è un flusso di server-sent event: il nome dell’evento di ogni frame è il type dell’evento e il suo id è il seq; per riprendere, si riconnetta con Last-Event-ID.

GET /v1/envelopes filtra per status, seal, template e q (testo libero su nomi ed e-mail dei destinatari, externalId e id della busta). Come ogni elenco, è paginato con cursore:

{ "data": [ … ], "hasMore": true, "nextCursor": "…" }

Ripassi nextCursor come cursor; limit va da 1 a 100 (predefinito 20).