1. Technical prerequisites
1
1.1 - Create Tomorro superadmin account
An existing admin creates a dedicated superadmin account from Settings > Members (e.g.
automation@customer.com), not a personal account.- The API key and the webhook are bound to a member, not to the organization: they only see the contracts that member can see.
- A superadmin sees every contract of the workspace, in every folder. Its webhook fires for every signed contract and its API key can download every signed file, without the account being added as a participant.
- With an admin account, the webhook only fires for the contracts it takes part in (or that sit in no folder), and the backup misses the others. Use a superadmin.
- Recommended: no personal mailbox behind it, and exclude it from Tomorro notification settings.
2
1.2 - API key
Generate the API key from that superadmin account. It does not expire. It is sent on every REST call in the
x-api-key header: Step 1: Get your API key3
1.3 - contractSigned webhook
Logged in as the superadmin account, create a webhook with the trigger
contractSigned and the URL of your integration: Webhooks. Keep its signing secret to verify every delivery (Technical documentation).4
1.4 - Storage
Out of scope (depends on the storage). Create the destination folder (and the metadata columns, see Non-Technical scoping), and give the integration write access to it.
2. Flows
Flow 0 - [Tomorro → Storage] Initialisation
1
Step 0 - Triggered by hand
Run once, when the integration goes live: the webhook of Flow 1 only fires for contracts signed after it is created. Re-running it is safe: contracts already in the storage are skipped.
2
Step 1 - List the signed contracts
200:Notes
Notes
- Up to 50 contracts per page: while
pagination.has_nextistrue, call again withafter=<pagination.next_cursor>. - Only some contract types: add
contractTypeId=<id>(one type per call). - Skip a contract whose file is already in the storage (file name contains the contract id, see step 3).
3
Steps 2 and 3 - Same as Flow 1
For each contract: get the signed files, upload them (Flow 1, steps 1 and 3).
Flow 1 - [Tomorro → Storage] Contract signed
Simple backup (recommended): every signed contract lands in one folder.1
Step 0 - Receive the contractSigned webhook
Verify the
Leeway-Signature header, answer 2xx within 3 seconds, then do the work asynchronously (Technical documentation).Notes
Notes
- Keep
data.contract.id, andname,signatureDate,typeId,externalCompany.namefor the file name and the metadata. - Only some contract types: skip the event when
data.contract.typeIdis not one of them. - Deduplicate on
eventId: a delivery that fails is retried (up to 10 times, 5 minutes apart), so the same event can arrive more than once.
2
Step 1 - Get the signed files
200:Notes
Notes
- One entry per signed document: the main document, then the annexes signed in the same bundle, in order.
downloadUrlis a pre-signed URL valid 30 seconds, seeexpiresAt. Download straight away (no auth header) and do not store the URL. Re-call the endpoint for a fresh one.409when the contract has no signed file yet;404for an unknown contract.
3
Step 2 - Read the contract metadata (optional)
Only needed for metadata the webhook does not carry (contract type name, smart fields), or for the advanced folder tree below.Returns
contractType (id, name), counterparty, fields (smart field values) and contractUrl.4
Step 3 - Upload to the storage
Out of scope (depends on the storage). Upload each file to the destination folder.
- File name: include the contract id (e.g.
NDA - Acme - 7d12db6f.pdf): two contracts can share a name, and a re-run overwrites instead of duplicating. - Metadata: contract type, counterparty, signature date,
contractUrl… as columns, if the storage supports them. - Several files: keep the order of step 1, e.g.
NDA - Acme - 7d12db6f.pdf, thenNDA - Acme - 7d12db6f - Annex 1.pdf.
1
Step 2.1 - List your storage rules
Once, from the storage settings of each contract type in Tomorro (Configure contract storage), write each rule as a condition on the contract’s data and a target path. For example:
2
Step 2.2 - Compute the folder
Read the contract (step 2) and evaluate the rules of its
contractType.id against counterparty and fields (smart field values) to get the target path. No rule matches: fall back to a single “To sort” folder rather than dropping the file.3
Step 2.3 - Create the folder if needed
Out of scope (depends on the storage). Create each missing level of the path, then upload as in step 3.
3. Technical references
Reference material: conventions, the endpoints, the webhook and error handling. Read it once, then come back to it while implementing the flows above.3.1 - API conventions
- REST only. The whole integration runs on the public REST API and one webhook.
- Base URL:
https://api.tomorro.com/v2 - Authentication:
x-api-key: <your api key>on every call. A missing or unknown key returns 401. - Versioning: optional
tomorro-versionheader, defaults to the latest version. - Rate limit: a
429means too many calls in a short time. Retry with backoff, especially during Flow 0. - Sandbox: available on request. It is an empty sandbox, not a copy of your production workspace.
- Response envelope: every successful JSON response is wrapped in a
dataobject (errors come as{ error, meta }, see 3.4). - Full reference: Tomorro API
3.2 - Endpoints
3.3 - The contractSigned webhook
- When it fires: when a contract becomes
signed, whatever the signature tool: Tomorro signature, DocuSign, or a signed version pushed by a third-party signature tool. - When it does not: contracts signed before the webhook was created, and contracts imported directly as signed (bulk import, store a signed document). Flow 0 covers both: re-run it after a bulk import.
- Payload:
data.contract(id,name,status,signatureDate,typeId,externalCompany,attributes…) anddata.signatories. No folder. - Delivery:
2xxwithin 3 seconds, otherwise retried up to 10 times, 5 minutes apart; after the 10th failure the webhook is disabled and has to be re-enabled in the settings. See Delivery & retries. - Security: every delivery is signed (
Leeway-Signatureheader). Verify it before calling the API.
3.4 - Error handling
Every endpoint follows the standard error format of the REST API. Error envelopeerror.statusCodeis a string, not a number.meta.requestIdis the value to quote to Tomorro support when reporting a failing call. Log it.
3.5 - Edge cases
- Duplicates: name each file with the contract id and deduplicate webhook deliveries on
eventId: a retried event or a re-run of Flow 0 overwrites instead of adding a copy. - Webhook disabled after 10 failed deliveries: events fired meanwhile are not replayed. Re-enable it, then re-run Flow 0 to catch up (already saved contracts are skipped).
- Contract deleted or canceled in Tomorro after signature: the backup keeps its copy. Nothing is removed from the storage.
- Amendment: a new contract in Tomorro, so a new file with its own id.
- Unsigned contracts (draft, negotiating): out of scope, their document is not a final PDF yet.
- Signature certificate: not part of
signed-files. Download it from the contract in Tomorro if your backup needs it.