Webhooks
A webhook is Papers telling your system that something happened, instead of your system asking. Set one up and you stop polling for "is the batch done" and "have they signed it yet".
You need somewhere for Papers to post to, so this one is for whoever runs your systems.
Add an endpoint
Settings, then Webhooks, then New endpoint.
Give it a Name, pick the Environment, and give the URL Papers should post to. The URL
has to be https://, and Papers refuses anything else rather than sending your document events
over plain HTTP.
An endpoint belongs to one environment, the same way a key does, so a test system and a live one each get their own.
Copy the signing secret now
Creating the endpoint shows a signing secret, once. Copy it before you close the dialog: it is not shown again, and without it your receiver cannot tell a real delivery from anybody who has guessed your URL.
If you lose it, use Rotate on the endpoint and update your receiver with the new one.
An endpoint created by your AI assistant through the connector never shows you a secret, in the chat or anywhere else. Open Settings in the web app and use Rotate on that endpoint to get one before you point a receiver at it.
Check the signature on every delivery
Papers posts JSON and signs it. The X-Papers-Signature-256 header is the HMAC-SHA256 of the exact
request body, keyed with your signing secret, as lowercase hex.
Your receiver computes the same thing over the raw body it received and compares. If they do not match, throw the request away: the URL is public, so the signature is the only thing that makes a delivery trustworthy.
Compute it over the raw bytes, before any JSON parsing and re-serialising. Reformatted JSON gives a different signature and nothing will ever match.
Signing deliveries also carry X-Papers-Event with the event name and X-Papers-Delivery-Id,
which is handy in your logs. Generation deliveries carry only the signature, so read the event name
from the body.
What Papers sends
Two families of event.
Generation events are generation.completed and generation.failed, and they come from batches.
Each item that renders sends generation.completed with its own job id. When the whole batch has
finished, one more event arrives with the batch's job id, as generation.completed or
generation.failed. Either way, read the batch's items to see which documents worked.
The body names the event in event and carries the job id, the template id and the status, so a
completed job is your cue to fetch the file from /v1/generation-jobs/{id}/download.
A single document from POST /v1/generate sends no webhook. The response to that request already
tells you how it went.
Signing events follow a request through its life: signing_request.sent,
signing_request.completed, signing_request.declined, signing_request.voided,
signing_request.expired, and per person signatory.viewed, signatory.signed,
signatory.declined and signatory.reminder_sent. The body names the event in eventType and
carries the event id, the signing request id, the signatory id where there is one, and when it
happened.
Every active endpoint in the environment gets every event. There is no per-event subscription, so your receiver should look at the event name and ignore what it does not care about.
Answer with a 2xx quickly
Papers treats any 2xx as delivered. Anything else is a failure.
A generation delivery is tried up to three times: straight away, again after two seconds, and again after six. Papers waits ten seconds for each answer. A 4xx is not retried at all, because a bad request will not fix itself. A redirect is not followed and counts as a failure, so give Papers the final URL rather than one that bounces.
A signing delivery is tried once. If your receiver is down when a signature lands, that event is gone, so treat the signing events as a prompt to refresh rather than as your only record. The request's own state and audit trail are always there to read back.
Do the work after you answer. Acknowledge the delivery, put the event on your own queue, and process it there. A receiver that generates a report before replying will time out and be sent the same event again.
Expect the same event twice
Retries mean a delivery can arrive more than once, and a batch's own event can arrive twice when its last two items finish together. Make your handler idempotent: key on the job id or the signing request id and ignore what you have already dealt with.
Switch one off without deleting it
Edit on an endpoint has an Active tick box. Clear it and the endpoint stops receiving events while keeping its URL and its secret, which is what you want while the receiving system is down for maintenance.
Delete removes it for good.
Testing one
Point an endpoint at a request-capturing service, generate a small batch or send a test document for signature, and read what arrives. That is the quickest way to see the real payload shape, and the reference at View API documentation in the API Keys section has the field lists.