0
votes

we are developing, with Java library from REST API, a procedure to sign multiple documents where the signature position is set using anchorString in signHereTabs for each signer (anchorString is a string inserted into the document to be signed); since we have documents with size greater than 25MB, we are using what has been reported in https://developers.docusign.com/esign-rest-api/guides/resource-limits , that is we create a draft envelope (status=created) and then we updates the envelope with the documents; the problem is that when we set the envelope with status = sent, the signer receives the email, open the link to DocuSign, but only the first document allow to access the anchorString. Is there any particular way to update the list of documents in the draft envelope ?

Thanks

...

// add a recipient to sign the document, identified by name and email we used above
int recipientId = 0;
List<Signer> signerList = new ArrayList<Signer>();

/* to fix the position where the signature has to be inserted */
int buyerIdx = 0;
int supplierIdx = 0;
for(DSSignerInfo signerInfo : signers) {
  Tabs tabs = new Tabs();

  Signer signer = new Signer();
  signer.setEmail(signerInfo.getEmail());
  signer.setName(signerInfo.getName());
  signer.setRecipientId(String.valueOf(++recipientId));
  signer.setRoutingOrder(String.valueOf(recipientId)); // sequential
  signer.setRoleName("role unknown");

  RecipientEmailNotification emailNotification = new RecipientEmailNotification();
  emailNotification.setEmailBody("emailBody - "+signerInfo.getName());
  emailNotification.setEmailSubject("emailSubject - "+signerInfo.getName());
  emailNotification.setSupportedLanguage(signerInfo.getLanguage());
  signer.setEmailNotification(emailNotification);

  // create a signHere tab somewhere on the document for the signer to sign
  // default unit of measurement is pixels, can be mms, cms, inches also
  for(int documentId = 1; documentId <= documentFiles.size(); documentId++) {
    SignHere signHere = new SignHere();
    signHere.setDocumentId("" + documentId);
    signHere.setPageNumber("1");
    signHere.setRecipientId(String.valueOf(recipientId));

    if(signerInfo.getRole().equalsIgnoreCase("buyer")) {
      signHere.setAnchorString("BUYER_"+buyerIdx);
    } else {
      signHere.setAnchorString("SUPPLIER_"+supplierIdx);
    }
    signHere.setAnchorXOffset("10");
    signHere.setAnchorYOffset("10");
    tabs.addSignHereTabsItem(signHere);
  }
  signer.setTabs(tabs);
  signerList.add(signer);
  if(signerInfo.getRole().equalsIgnoreCase("buyer")) {
    buyerIdx++;
  } else {
    supplierIdx++;
  }
}
Recipients recipients = new Recipients();
recipients.setSigners(signerList);
envDef.setRecipients(recipients);

try {
  String envelopeId = null;
  EnvelopesApi envelopesApi = null;

  // create a byte array that will hold our document bytes
  int documentId = 1;
  for(String documentFile : documentFiles) {
    byte[] fileBytes = null;
    try {
      // read file
      Path path = Paths.get(documentFile);
      fileBytes = Files.readAllBytes(path);
    } catch (IOException ioExcp) {
      // handle error
      System.out.println("Exception: " + ioExcp);
      return null;
    }

    // add a document to the envelope
    Document doc = new Document();
    String base64Doc = Base64.getEncoder().encodeToString(fileBytes);
    doc.setDocumentBase64(base64Doc);
    String fileName = new File(documentFile).getName();
    doc.setName(documentId+"_"+fileName);
    doc.setFileExtension(fileName.lastIndexOf('.') > 0 ? fileName.substring(fileName.lastIndexOf('.') + 1) : "");
    doc.setDocumentId("" + documentId++);

    envDef.addDocumentsItem(doc);

    if(envelopeId == null || envelopesApi == null) {
      // To save as a draft set to "created" (for test purpose I create and envelope with only one file)
      envDef.setStatus("created");
      envelopesApi = new EnvelopesApi();
      EnvelopeSummary envelopeSummary = envelopesApi.createEnvelope(accountId, envDef);
      envelopeId = envelopeSummary.getEnvelopeId();
    } else {
      // the files after the 1st are updated in the draft envelope
      envDef.setRecipients(recipients);
      List<Document> tmpDocumentList = new ArrayList<Document>();
      doc.setApplyAnchorTabs("true");
      tmpDocumentList.add(doc);
      envDef.setDocuments(tmpDocumentList);
      EnvelopeDocumentsResult envelopeDocumentsResult = envelopesApi.updateDocuments(accountId, envelopeId, envDef);
    }
  }
  Envelope envelope = envelopesApi.getEnvelope(accountId, envelopeId);
  envelope.setStatus("sent");
  envelope.setPurgeState(null);
  EnvelopesApi.UpdateOptions uo = envelopesApi. new UpdateOptions();
  uo.setAdvancedUpdate("true");
  EnvelopeUpdateSummary envelopeUpdateSummary = envelopesApi.update(accountId, envelopeId, envelope, uo);

  documentId = 1;
  for(String documentFile : documentFiles) {
    Tabs tabs = envelopesApi.getDocumentTabs(accountId, envelopeId, ""+documentId++);
    System.out.println("CARLO Tabs 3, documentId "+(documentId - 1)+": "+tabs);
  }

Thanks for your answer. More details: in the envelope we have more than one document; the size of each document is less than 25MB; the sum of the sizes of all the documents is more than 25MB. We can upload documents in envelope with status "created", but when the status is changed to "sent" and the signer goes into the signature page then it is not required to sign these documents; it seem that the signHereTabs is not set in the documents added while envelope status is "created".

If after having set envelope status = "sent" we execute the following code

documentId = 1;
for(String documentFile : documentFiles) {
    Tabs tabs = envelopesApi.getDocumentTabs(accountId, envelopeId, ""+documentId++);
    System.out.println("Tabs: documentId "+(documentId - 1)+": "+tabs);
}

we obtain

Tabs: documentId 1: class Tabs { ... signHereTabs: [class SignHere { anchorCaseSensitive: null anchorHorizontalAlignment: null anchorIgnoreIfNotPresent: null anchorMatchWholeWord: null anchorString: BUYER_0 anchorUnits: pixels anchorXOffset: 10 anchorYOffset: -10 conditionalParentLabel: null conditionalParentValue: null customTabId: null documentId: 1 errorDetails: null mergeField: null name: SignHere optional: false pageNumber: 1 recipientId: edb96dfd-9700-4328-ba45-825a1284b030 scaleValue: 1.0 stampType: signature stampTypeMetadata: null status: null tabId: e484087c-70c2-431c-9825-47605e1f44c2 tabLabel: Sign Here tabOrder: null templateLocked: null templateRequired: null tooltip: null xPosition: 123 yPosition: 297 }] ... } Tabs: documentId 2: class Tabs { ... signHereTabs: [] ... }

where documentId 1 has been uploaded when the envelope has been created (status="created"), and documentId 2 has been uploaded in a second step (both documentId 1 and 2 contain the anchorString: BUYER_0).

3
Welcome to StackOverflow and thank you for using DocuSign! Please upvote all useful answers, including those to others' questions. And PLEASE check (accept) the best answer to your own questions. Thank you.Larry K
Please see my updated answer.Larry K

3 Answers

1
votes

If your document size is greater than 25MB then also putting document in the draft mode will not help, instead you have to use ChunkedUploads to add any document less than 50MB. Adding multiple documents via draft is useful if your JSON Request Payload is greater than 25 MB, but it will not be useful if any document in the envelope is greater than 25 MB.

0
votes

To add on to Amit's answer, every individual API request to DocuSign must be less than 25MB.

Since the default technique is to send Base64 encoded documents within a JSON object, the effective max total size for all of the documents sent in a single request is around 18MB.

You can avoid the Base64 overhead by sending the API request as a multi-part MIME message. This technique enable you to send the documents as binary objects. See the code example for scenario 10 in C# (also available for PHP, Java, Node.js, Python, and Ruby)

Additional

If each of your documents is less than 18 MB, then you can use the "regular" JSON object and Base64 encode one document at a time. If the sum of the document sizes is greater than 18MB then you must upload them one at a time:

  1. Create the envelope, include one of the documents. The document status should be created so the envelope is not sent at this time.
  2. Add more documents to the envelope, one at a time. You can use EnvelopeDocuments::updateList API method. You'd probably want query parameter apply_document_fields on.
  3. Update the envelope status to sent using Envelopes::update

For adding tabs to the documents, you could define them at the beginning if you use anchor tab positioning. Or you could add the tabs to the envelope definition after you finish adding the documents to the envelope.

0
votes

Thanks all for the answers. I've solved the problem in this way: - step 2: set on the parameter apply_document_fields on each added file, - step 3: set again the recipients in the envelope before set it as 'sent'. From my point of view this question is solved.