Skip to main content
A hosted workflow can make signing part of the run. Once you approve a verification on a version that offers contracts, it waits in pending-signature until a contract of each one offered to it is signed, and completes then. Each signer signs with Aadhaar eSign, on Signzy. Your contracts are built for you, one contract workflow per contract: its template, who signs it and in what order, how each signs, and how long its signing links last. A workflow version then offers it, and says which of the template’s values the verification fills in from what it collected and which you set each time you send one. Talk to us to have a contract workflow built and offered.

How a verification moves through signing

The person on the journey is shown it completed once they have submitted; the contracts reach each signer by SMS or email, as the contract workflow says.

Which contracts a verification is offered

Read the workflow, or any version of it, and contracts lists what its verifications can be signed on:
filled are the template’s values the verification fills in from what it collected, and open the ones you set with each send. Every value is required. A verification is sent what the version it runs offers. A contract with a condition is offered only to the verifications that meet it, in the same terms as a step’s condition: an answer the user gave, how a check concluded, or the context you created the verification with. A version can offer one agreement per product, each to the verifications created for that product, or one per legal form, each to the businesses that answer with it. A verification’s offered_contracts names the ones offered to it, and it waits on a signed contract of each of those and no other. Sending one not named there is refused with 409 contract-not-sendable.
Which contracts are offered is settled as the verification is approved, from the run as it stands. A run reopened before any contract is sent is offered again once it is approved again, so correcting an answer can change the contract it is signed on. A verification can be for several things at once, such as its products, in a choice-list context field: a list of one or more of its options. The workflow’s context declares it:
A condition tests such a list with includes or excludes: one agreement per product, each offered where products includes it, or a general agreement for every verification whose products exclude gold-loan. dates are the values in open that take a date. Send each as YYYY-MM-DD, and the contract prints it as the day, the month’s name and the year: 2026-11-01 is printed 1 November 2026, and the contract’s values read it that way too.

Previewing and sending

GET /verifications/{verification_id}/contracts/preview?contract_workflow=dealer-agreement answers what a send would carry now: the values the verification fills in, the ones left to you, everyone it would go to, the contracts of that contract workflow already sent on the run, and every fault that would refuse a send whatever you set. Its open and dates read as they do on the workflow. It sends, spends and records nothing. Send one with every value in open, and a note of your own if you want one:
A send is refused with 422 contract-refused, naming every fault, where a value you set is missing, empty or not yours to set, where a date is not a calendar date given as YYYY-MM-DD (value 'start_date': a date, as YYYY-MM-DD), where the verification does not hold a value the offer fills in, or where a value would print the contract wrongly, such as a name so long that it pushes the signing line onto other text. Nothing goes to the signers and no credit is used. Each send uses one of the workflow’s contract credits, whether or not it is signed. Read contract_credits on the workflow to see where they stand. A workflow with none left refuses a send with 402 contract-credits-exhausted. A send whose answer you did not receive can be asked again, and nothing goes out twice. Where the contract is already out carrying the same values and note, it is answered with 200 rather than 201, and nothing is sent, spent or recorded; a send carrying anything else while one is out is refused with 409 contract-not-sendable.

Following a contract

GET /verifications/{verification_id}/contracts/{contract_id} reads one contract: its status, each signer’s progress and attempts, every message each signer was sent and whether it was delivered, the values it carried and your note. A callback tells you when it reaches its end, so you rarely need to poll. Every status but pending and withdrawing is final. POST .../remind reads the contract afresh and sends the link again to every signer still to sign, or to the one whose turn it is where they sign in order; only a pending contract is reminded. POST .../withdraw takes a contract back. GET /contracts lists every contract across your verifications, filtered by status, contract workflow, workflow, your reference, or verification.

Downloading the contract

POST /verifications/{verification_id}/contracts/{contract_id}/download answers short-lived links to the contract as it went to its signers, held from the moment it goes, and once it is signed, to the signed document and Signzy’s audit certificate. Each link carries the SHA-256 of its file, and sent_document and signed_files on the contract carry the same hashes, so you can check what you downloaded:
Every file is held until the verification expires, and goes with it, so keep what you need before then.

Callbacks

Each contract reaching its end is posted to the workflow’s callback endpoint as contract.signed, contract.expired, contract.failed or contract.withdrawn, and the signature that completes the verification is followed by verification.completed. See Callbacks.

Retention

A contract lives and goes with its verification. Sending a contract, withdrawing one and one reaching its end each restart the verification’s retention window; reminding signers and reading do not. Once the verification expires, or you purge it, its contracts keep what they were and how they ended, and their values, your notes, their signers and every file of theirs are deleted. A contract still out is withdrawn first, and a purge while a signer is part way through signing is refused with 409 contract-withdrawal-pending, to be asked again in a few minutes.