'How can I add custom metadata at runtime to document(s) created from a template

I am using composite templates to create an envelope. Every template will only have one document. I need to individually process every document that comes back signed. In order to do that I need to add metadata to each document that is being sent. How can I do that while also using composite templates before I send the envelope? I know all about envelope metadata and custom fields but what if I need it more specific to documents and I'm not working with the actual documents? Here I'm working with the templates that contain the documents. Here is the c# code I have so far

List<CompositeTemplate> compositeTemplates = new List<CompositeTemplate>();
Recipients recipientsServerTemplate = new Recipients();
List<Signer> signers = new List<Signer>();
        List<CarbonCopy> carbonCopies = new List<CarbonCopy>();

     
        Signer signer1 = new Signer();
        signer1.Email = signerEmail;
        signer1.Name = signerName;
        signer1.RoleName = "signer";
        signer1.RecipientId = "1";
        signer1.Tabs = tabs;
        signers.Add(signer1);

       
        CarbonCopy cc1 = new CarbonCopy();
        cc1.Email = ccEmail;
        cc1.Name = ccName;
        cc1.RoleName = "cc";
        cc1.RecipientId = "2";
        carbonCopies.Add(cc1);

        recipientsServerTemplate.Signers = signers;
        recipientsServerTemplate.CarbonCopies = carbonCopies;


        int i = 1;
        foreach (string templateId in templateIds)
        {
            //add custom fields //this is per envelope. I need it more specific in my case
            TextCustomField textcustomField = new TextCustomField
            {
                Name = "MyCustomField" + i.ToString(),
                Required = "false",
                Show = "false",
                Value =  "653022" 
            };
            CustomFields cf = new CustomFields
            {
                TextCustomFields = new List<TextCustomField> { textcustomField }
            };

            List<ServerTemplate> ServerTemplates = new List<ServerTemplate>();
            List<InlineTemplate> InlineTemplates = new List<InlineTemplate>();
            CompositeTemplate CT = new CompositeTemplate
            {
                CompositeTemplateId = i.ToString()
            };

            ServerTemplate ST = new ServerTemplate
            {
                Sequence = i.ToString(),
                TemplateId = templateId
            };
            

            InlineTemplate IT = new InlineTemplate
            {
                Recipients = recipientsServerTemplate,
                Sequence = (i+1).ToString(),
                CustomFields = cf//this is for the whole envelope
            };
            
            InlineTemplates.Add(IT);
            ServerTemplates.Add(ST);
            CT.ServerTemplates = ServerTemplates;
            CT.InlineTemplates = InlineTemplates;
            compositeTemplates.Add(CT);
            
            i++;
        }


        EnvelopeDefinition env = new EnvelopeDefinition
        {
            Status = "sent",
            CompositeTemplates = compositeTemplates
        };


Solution 1:[1]

Adding metadata on the envelope about my documents was not a robust option as I knew nothing about the document that I could connect my metadata to

What I ended up doing to track individual documents within templates was adding a read-only text tab with "MetaDataId" as the tab label for each of my documents that I had in templates.

Read-only tabs don't replicate data across the envelope.

The JSON request would look like

{
    "compositeTemplates": [
        {
            "compositeTemplateId": "FirstTemplate",
            "serverTemplates": [
                {
                    "sequence": "1",
                    "templateId": "templateId1"
                }
            ],
            "inlineTemplates": [
                {
                    "sequence": "1",
                    "recipients": {
                        "signers": [
                            {
                                "email": "[email protected]",
                                "name": "Blah Blah",
                                "recipientId": "1",
                                "roleName": "Signer",
                                "routingOrder": "1",
                                "tabs": {
                                    "textTabs": [
                                        {
                                            "tabLabel": "MetaDataId",
                                            "value": "121"
                                        }
                                    ]
                                }
                            }
                        ]
                    }
                }
            ]
        },
        {
            "compositeTemplateId": "SecondTemplate",
            "serverTemplates": [
                {
                    "sequence": "2",
                    "templateId": "templateId2"
                }
            ],
            "inlineTemplates": [
                {
                    "sequence": "2",
                    "recipients": {
                        "signers": [
                            {
                                "email": "[email protected]",
                                "name": "Blah Blah",
                                "recipientId": "1",
                                "roleName": "Signer",
                                "routingOrder": "1",
                                "tabs": {
                                    "textTabs": [
                                        {
                                            "tabLabel": "MetaDataId",
                                            "value": "122"
                                        }
                                    ]
                                }
                            }
                        ]
                    }
                }
            ]
        },
        {
            "compositeTemplateId": "ThirdTemplate",
            "serverTemplates": [
                {
                    "sequence": "3",
                    "templateId": "templateId3"
                }
            ],
            "inlineTemplates": [
                {
                    "sequence": "3",
                    "recipients": {
                        "signers": [
                            {
                                "email": "[email protected]",
                                "name": "Blah Blah",
                                "recipientId": "1",
                                "roleName": "Signer",
                                "routingOrder": "1",
                                "tabs": {
                                    "textTabs": [
                                        {
                                            "tabLabel": "MetaDataId",
                                            "value": "123"
                                        }
                                    ]
                                }
                            }
                        ]
                    }
                }
            ]
        }
    ],
    "emailSubject": "Please Sign",
    "emailBlurb": "This is an email Example",
    "status": "sent"
}

Incidentally, if you're using the C# SDK and you're creating the templates with a loop as I am doing in the question for this post then you may have to clone the object that you're setting for the Recipients the in Inline Template so that the value you set for the MetaDataId text tab for the signer doesn't just hold the last one that you assigned, which will happed if you reuse the same Recipients object.

Solution 2:[2]

I suggest adding metadata at the envelope level about the envelope's documents. I don't think you can add document-level metadata when using composite templates.

Added

Templates are usually created via the DocuSign web app. But the web app does not support document-level metadata.

When you use the API to create the envelope, you could create add additional fields to the documents. You could make those additional fields only readable to your company recipients and store document metadata there.

But I would not recommend that. Better to store the document-specific data at the envelope level. For example, include the document-specific metadata as a JSON string in the envelope-level metadata:

...
"compositeTemplates": [
  {
    "serverTemplates": [
      {
        "sequence": "1",
        "templateId": "61973947-7d29-490d-9bac-5432154321"
      }
    ],
    "inlineTemplates": [
      {
        "sequence": "2",
        "customFields": {
          "textCustomFields": [
            {
              "name": "Main document",
              "show": "false",
              "value": "{\"value\":34500, \"office\": \"SF\"}"
            }
          ]
        },

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 NortziHead
Solution 2