NEW: Simple case file creation

The simple case file creation method is designed to provide maximum simplicity and efficiency by allowing you to submit an entire case file in one single request.

On this page you will receive basic information and use case examples on how to leverage the simple case file creation endpoint. Let's send a Case file with Penneo!

📘

To use the simple Case file creation endpoint, you must obtain a JWT using OAuth as described here.

Request structure

To use the simple case file creation endpoint it's essential to understand the two logical form elements.

Try the endpoint here: API reference

  • Files : In the files form element the files that needs to be signed/attached are provided.
  • Data: In the data form element the case file structure is configured using JSON.

Your request structure will be the following:

// Request structure for simple case file creation

curl --location --request POST 'https://app.penneo.com/send/api/v1/casefiles/20251022/create' \
--header 'X-Auth-Token: [YOUR_AUTH_TOKEN]' \
--header 'accept: JWT' \
--header 'Content-Type: multipart/form-data' \
--form 'files=@"[PATH_TO_FILE_1]"' \
--form 'files=@"[PATH_TO_FILE_2]"' \
--form 'data="<JSON caseFile structure>"'

Files form element

Files must be uploaded as separate files in the multipart/form-data request. One files fields containing the actual binary files. Unlike some older API methods, this endpoint does not accept Base64-encoded PDFs in the JSON body.

The multipart/form-data encoding type is used to send files and data to Penneo's server.

Data form element

The data form element shall contain your full case file structure. This includes signers, document properties, and various other functionalities from Penneo that you, as an integrator, wish to leverage.

📘

The name value in the documents array must match the name of the files uploaded in the Files form element.

Let's have a look at the different components in the data form element. The structure of the JSON is based on a caseFile object including an array for signers and an array for documents. Giving you flexibility to design the case file as your users desire.

Scenario 1: Configuring a case file with a single document and a single signer.

// Scenario: single document, single signer 
{
  "caseFile": {
    "title": "<insert casefile name>",
    "signers": [
      {
        "name": "<enter signer name>",
        "email": "<enter signer email>"
      }
    ],
    "documents": [
      {
        "name": "<name of the file>", // Must match the name of files provided
        "title": "<enter a document title>"
      }
    ]
  }
}

Scenario 1 creates a case file with one signer and one document.

As an integrator you can easily extend the amount of signers and documents, which is exemplified in scenario 2.

Scenario 2: Configuring a case file with more signers and more documents.

{
  "caseFile": {
    "title": "<insert casefile name>",
    "signers": [
      {
        "name": "<signer name 1>",
        "email": "<signer email>"
      },
      {
        "name": "<signer name 2>",
        "email": "<signer email>"
      },
      {
        "name": "<signer name 3>",
        "email": "<signer email>"
      }
    ],
    "documents": [
      {
        "name": "<name of the file>",
        "title": "<enter a document title>"
      },
      {
        "name": "<name of the file>",
        "title": "<enter a document title>"
      },
      {
        "name": "<name of the file>",
        "title": "<enter a document title>"
      }
    ]
  }
}

Scenario 2 creates a case file with 3 signers and 3 documents. Visualised below you see the case file object containing 3 signers and 3 documents. For this given case all signers will sign all documents.


Roles

When configuring the data form element you can leverage the role value on the signer in combination with the roles value on the document to specify whether signers shall sign all or some of the documents. This might be valuable in certain signing scenarios where not all signers shall sign all documents.

📘

If there are no roles defined in the document array, the document will, by default, be signed by all signers. It is important that the roles on the document matches the role given to the signers.

Let's look at an example!

Scenario 3: Configuring a case file with two signers and two documents where;

  • Signer 1 signs both documents
  • Signer 2 signs one document
{
  "caseFile": {
    "title": "<insert casefile name>",
    "signers": [
      { 
        "name": "<signer name 1>",
        "email": "<signer email>",
        "role": "role1"
      },
      { 
        "name": "<signer name 2>", 
        "email": "<signer email>",
        "role": "role2"
      }
    ],
    "documents": [
      { 
        "name": "<name of the file>", 
        "title": "<enter a document title>",
        "roles": ["role1"]
      },
      { 
        "name": "<name of the file>", 
        "title": "<enter a document title>",
        "roles" ["role1", "role2"]
      }
    ]
  }
}

When there are no roles defined in the document array, the document will be signed by all signers. Hence, the same scenario could be achieved by leaving roles on document two blank.

{
  "caseFile": {
    "title": "<insert casefile name>",
    "signers": [
      { 
        "name": "<signer name 1>",
        "email": "<signer email>",
        "role": "role1"
      },
      { 
        "name": "<signer name 2>", 
        "email": "<signer email>",
        "role": "role2"
      }
    ],
    "documents": [
      { 
        "name": "<name of the file>", 
        "title": "<enter a document title>",
        "roles": ["role1"]
      },
      { 
        "name": "<name of the file>", 
        "title": "<enter a document title>"
      }
    ]
  }
}

Essentially as an integrator you will be able to leverage the signer role combined with the document roles to appoint signers to documents.

In the visualisation above you see a case file with 2 documents and 2 signers (role1 & role2) and solelydocument[0] is signed by role1.

Signing order

A common use case with Penneo is to have signer(s) sign before other signer(s). This can be achieved by configuring the data form element using signOrder in the signer array.

Scenario 4: Configuring a case file with three signers and one document where;

  • Signer 1 signs first
  • Signer 2 signs second
  • Signer 3 signs third
{
  "caseFile": {
    "title": "<insert casefile name>",
    "signers": [
      { 
        "name": "<signer name 1>",
        "email": "<signer email>",
        "signorder": 0
      },
      { 
        "name": "<signer name 2>", 
        "email": "<signer email>",
        "signorder": 1
      },
      { 
        "name": "<signer name 3>", 
        "email": "<signer email>",
        "signorder": 2
      }
    ],
    "documents": [
      { 
        "name": "<name of the file>", 
        "title": "<enter a document title>"
      }
    ]
  }
}

As per the visualisation below this structure creates a case file with 3 signers and 1 document, where the signers sign in sequence.

Attachments

For certain scenarios you might wish to distinguish between files that must be signed and attachments. This can be achieved by configuring the data form element using the signable boolean in the document array.

📘

If the signable value is not present, the system defaults to true.

Scenario 5: Configuring a case file with two signers and two documents where;

  • One document must be signed
  • One document is an attachment
{
  "caseFile": {
    "title": "<insert casefile name>",
    "signers": [
      { 
        "name": "<signer name 1>",
        "email": "<signer email>"
      },
      { 
        "name": "<signer name 2>", 
        "email": "<signer email>"
      }
    ],
    "documents": [
      { 
        "name": "<name of the file>", 
        "title": "<enter a document title>"
      },
      { 
        "name": "<name of the file>", 
        "title": "<enter a document title>",
        "signable": false
      }
    ]
  }
}

As per the visualisation below, the data structure creates a case file with 2 signers and 2 documents but solely one of the documents has signable: true .


Delivering the signing request

By default Penneo delivers the signing request to signers via email. The email texts are defined in the signer array. As an integrator you can change the email texts. This can be achieved by configuring the data form element.

Let's look at how you, as an integrator, can change the email texts for a case file.

Scenario 6: Configuring a case file with two signers and one documents where;

  • Email texts are modified for each signer
  • Reminder interval is specified
{
  "caseFile": {
    "title": "<insert casefile name>",
    "signers": [
      { 
        "name": "<signer name 1>",
        "email": "<signer email>",
        "emailSubject": "string",
        "emailText": "string",
        "reminderEmailSubject": "string",
        "reminderEmailText": "string",
        "completedEmailSubject": "string",
        "completedEmailText": "string",
        "reminderInterval": 1 //the signer is reminded every day
      },
      { 
        "name": "<signer name 2>",
        "email": "<signer email>",
        "emailSubject": "string",
        "emailText": "string",
        "reminderEmailSubject": "string",
        "reminderEmailText": "string",
        "completedEmailSubject": "string",
        "completedEmailText": "string",
        "reminderInterval": 2 //the signer is reminded every second day
      }
    ],
    "documents": [
      { 
        "name": "<name of the file>", 
        "title": "<enter a document title>"
      }
    ]
  }
}

The simple case file creation endpoint does also support scenarios, where, you as an integrator, wish to deliver the signing request through other means than Penneo's email service.

This use case can be achieved by configuring the data form element without populating the email in the signer array. Followed by obtaining the signing links by checking queue status check endpoint.

Scenario 7: Configuring a case file with two signers and one documents where;

  • The integrator delivers the signing requests by other means
{
  "caseFile": {
    "title": "<insert casefile name>",
    "signers": [
      { 
        "name": "<signer name 1>",
      },
      { 
        "name": "<signer name 2>",
      }
    ],
    "documents": [
      { 
        "name": "<name of the file>", 
        "title": "<enter a document title>"
      }
    ]
  }
}

Thereafter, to obtain the signingLinks. You must use the response UUID and payloadHash from the response body on the queue status check endpoint.

{
  "uuid": "123e4567-e89b-12d3-a456-426614174000",
  "payloadHash": "3a7bd3e2360a3d485f2a5f4d8e6f1e8b9c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f"
}

Once the job has been executed you will be able to obtain both the casefileId and the signingLinks.


Final remarks

  • API reference
  • Feel free to provide any feedback through our support channel