Skip to main content
Everything runs on one Tomorro webhook and two REST endpoints. How you write to the storage depends on your storage (SharePoint, Google Drive, Box, S3…).

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 key
3

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

Response 200:
  • Up to 50 contracts per page: while pagination.has_next is true, call again with after=<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).
  • Keep data.contract.id, and name, signatureDate, typeId, externalCompany.name for the file name and the metadata.
  • Only some contract types: skip the event when data.contract.typeId is 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

Response 200:
  • One entry per signed document: the main document, then the annexes signed in the same bundle, in order.
  • downloadUrl is a pre-signed URL valid 30 seconds, see expiresAt. Download straight away (no auth header) and do not store the URL. Re-call the endpoint for a fresh one.
  • 409 when the contract has no signed file yet; 404 for 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, then NDA - Acme - 7d12db6f - Annex 1.pdf.
Storage unreachable: retry with backoff (Make, n8n and Zapier have a retry-on-error setting), and log the failed uploads to a channel someone reads (email, Slack). Answering 2xx to the webhook first means Tomorro does not retry for you.
Advanced: mirror the Tomorro folder tree. Same flow, the folder is computed in step 2 instead of being fixed.
Tomorro does not return the folder path of a contract. GET /v2/contracts/{id} gives a folderId, but no public endpoint turns it into a folder name or path. The folder comes from the storage rules of the contract type: the integration has to apply the same rules itself, and be updated every time a rule changes in Tomorro. Start with the simple backup unless you have a strong reason not to.
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-version header, defaults to the latest version.
  • Rate limit: a 429 means 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 data object (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…) and data.signatories. No folder.
  • Delivery: 2xx within 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-Signature header). Verify it before calling the API.

3.4 - Error handling

Every endpoint follows the standard error format of the REST API. Error envelope
  • error.statusCode is a string, not a number.
  • meta.requestId is 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.