Your id or ours: linking a signature request to the record it signs
Your product has a new flow that ends with a signature: a contract attached to a deal, a mandate attached to an account, a consent attached to an onboarding. On your side, that document belongs to a record in your database. On the IgniSign side, it belongs to a signature request. Every webhook that reaches your backend names the signature request, so before your handler can do anything useful it has to answer one question: which of my records is this about? You can answer it with the IgniSign id or with your own.
Where the two ids come from
When you build a request step by step, IgniSign returns a signatureRequestId as soon as you initialise it. You then attach documents, and an update call sets the signers, the documents, the title, the default signature method and an optional externalId. Publishing the request sends it to the signers.
externalId is a free-form reference that IgniSign does not interpret. Whatever you put there comes back to you: the webhook events for that request carry it as signatureRequestExternalId, next to the signatureRequestId, the appId and the appEnv.
Option 1: store the IgniSign id on your record
Save signatureRequestId on your record right after you initialise the request, and look the record up by that id when an event arrives.
This works, and it is often the first version. It has one weak spot: ordering. Your record and the IgniSign request are created in two systems, and if your code saves the id after a step that can fail, you can end up with a request your database does not know about. When its events arrive, your handler has nothing to match them to.
It also ties your queries to an id you did not choose. Support, finance or an auditor will ask about "contract 4812", not about an IgniSign id, and someone has to translate.
Option 2: put your id on the request
Create your record first, then set its id as externalId when you update the signature request, before you publish it.
From then on, every event for that request tells you which record it is about, in your own terms. The handler for the launched request, the one for each signer's finalized signature and the one for the generated proof all start the same way: read signatureRequestExternalId, load the record, act. No lookup table and no translation.
The public Node example in ignisign-examples follows this pattern: it inserts the contract, then passes the contract id as externalId in the update call, and its webhook handlers receive the contract id back.
Store both anyway
The two options are not exclusive, and a robust integration stores both ids in your database:
- your id goes to IgniSign as
externalId, so events find the record without a lookup; - the IgniSign
signatureRequestIdstays on your record, so your code can call the API about that request, for example to read its context, without searching.
Add the appId and appEnv from the event to your lookup. Your development and production environments are separate, and a record created with development keys should never be matched by a production event that happens to carry the same reference.
If you also map your users to persistent IgniSign signers, the same idea applies one level down: the signer's externalId comes back as signerExternalId in signer-level events, so a per-signer update finds the right user directly.
What to watch for
externalId is a reference, not a secret. Use your record's id, not an email address or a customer name, and keep anything sensitive out of it.
Make your handlers safe to run twice. An event you resend from the webhook event log arrives with the same ids, so key the work on your record id and the event type and skip it when it is already done.
The decision
Let your own id travel with the request. Create the record, set its id as externalId before you publish, and keep the IgniSign signatureRequestId beside it for API calls. Your webhook handlers then start from the record they are about, and anyone reading your logs can follow a signature from your product to IgniSign and back.
Try it in your development environment first: publish one request with an externalId, sign it, and check that the same value arrives with each event in the event log.