Skip to main content
Cadana supports two contract flows: template-based contracts that are sent for electronic signature, and upload-based contracts where you upload an already-signed PDF. This guide covers both.

Prerequisites

1

Contracts enabled

Contracts must be enabled for your account. If you don’t see the Contracts section in the Dashboard, contact your account manager to enable it.
2

API key from Dashboard

Get your API key from the Cadana Dashboard. See Authentication.
3

Contract templates configured (template-based only)

If using template-based contracts, create your templates in the Dashboard under People > Contracts > Browse Templates before using the API. Not needed for uploaded contracts.
4

Onboarded workers

Workers must be onboarded as Persons — you’ll assign contracts using their personId. See Onboard Workers.

Option A: Template-Based Contracts

Use this flow when you want Cadana to handle electronic signatures. You select a contract template, Cadana generates the document, and both parties sign digitally.

List Available Templates

Retrieve the templates available for your business. Each template is scoped to a personType (employee or contractor) and country. Response:
Template variables (e.g., person.firstName) are auto-populated from the Person record when the contract is created.

Create a Contract

Create a contract from a template and assign it to a person. The sender is the business representative who will sign first. Response:
To suppress the default email notification to the signer — for example, if you handle notifications through your own system — pass suppressNotification: true in the request body.
Contract creation is not idempotent — retrying the same request creates a second, identical contract, and there is no API endpoint to revoke a contract. Check for an existing contract with GET /v1/contracts?personId=... before retrying.

Get the Signing URL

Retrieve a URL that the next signer can use to view and sign the contract. The URL is valid for 336 hours (14 days). Response:
The domain in the URL is either app.cadanapay.com or your white-label domain, depending on your platform configuration. The optional redirectUrl query parameter specifies where to send the signer after they complete signing.
If you suppress email notifications (suppressNotification: true), you’re responsible for delivering the signing URL to each signer. Use the signing URL endpoint to generate links on demand.

Track Signature Status

List contracts to check their signature status. Optionally filter by personId. Response:
Each signature includes signedAt (epoch timestamp, 0 if unsigned) and lastViewedAt so you can track engagement.

Contract Status Flow

Contracts can only be revoked before both parties have signed — and not via the API; there is no revocation endpoint. Once completed, the contract is final.

Retrieve a Contract

Fetch the full details of a single contract by its ID. To include a presigned download URL for the contract PDF, pass includeDownloadUrl=true: Response:
The downloadUrl and downloadUrlExpiresAt fields are only present when includeDownloadUrl=true. The download URL expires after 15 minutes.

Option B: Upload a Signed Contract

Use this flow when you already have a signed contract PDF — for example, a contract signed offline or through a third-party e-signature tool.

Step 1: Upload the File

Upload the PDF using the two-step file upload flow. See Working with Files for the full process. Response:
Then upload the file to the putUrl within the expiry window (15 minutes):
Bash

Step 2: Create the Contract Record

Attach the uploaded file to the person’s record using the fileId from step 1. Response:
Uploaded contracts are created with status completed since they’re already signed. They appear alongside template-based contracts when you list contracts for a person, and can be retrieved with GET /v1/contracts/{contractId}.

Webhook Events

Cadana emits contract webhook events so you can track the signing lifecycle in real time. Subscribe via the Dashboard or see Webhooks for setup.

contract.created

Fired when a new contract is created (template-based or uploaded).
JSON

contract.signed

Fired each time a signature is collected. The isComplete field tells you whether all signatures are now in.
JSON

contract.status.updated

Fired on status transitions (e.g., revoked).
JSON
See Events for all event types and payload details.

Troubleshooting


Next Steps

Onboard Workers

Create Person records before issuing contracts

Pay Workers via Payroll

Pay workers after contracts are in place

Working with Files

Upload and download files (contracts, KYC documents, etc.)