Document signing workflows often start before the signing application is opened. A business system already knows the customer, contract details, line items, dates, and recipient information. In that scenario, the signing process should be started by an integration: Generate the document, create the envelope, and route it to the correct signers. This article shows how a .NET console application can use TX Text Control to merge JSON data into a document template and then submit the resulting document to the SignFabric API. The sample represents the role of your own application: It owns the data, creates the document, and starts the envelope workflow without requiring a manual upload step. Automated Envelope CreationThe integration pattern is simple: Merge the document in your own application, authenticate against SignFabric, and send the generated document plus recipient metadata to the envelope API.https://github.com/TextControl/SignFabric The Integration Flow The sample console application follows a typical server-side integration flow: Load a TX Text Control template from disk. Load JSON data for the mail merge process. Use MailMerge.MergeJsonData to merge the data into the template. Save the merged document in TX internal format. Request an API access token. Post the merged document and signer metadata to the envelope API. This keeps document generation and envelope creation in one automated process. The calling system does not need to ask users to upload the finished document manually after the merge. Template and JSON Data The template contains regular merge fields for business data and TX signature fields for the signers. The JSON file contains the values that are merged into the document. [ { "contract_date": "2020-01-01", "provider": { "name": "Service Provider LLC", "contact": { "name": "John Doe", "title": "CEO" } }, "client": { "name": "Client LLC", "contact": { "name": "Jane Doe", "title": "CFO" } } } ] The following template shows the starting point for the integration: Merge fields are populated from JSON data, while the signature boxes define where SignFabric recipients will sign. The document template can use these values in merge fields and merge blocks. After the merge, the resulting document is saved as .tx, which is one of the supported upload formats configured in SignFabric. Merging the Document The console application uses ServerTextControl as a non-visual document processing component. The template is loaded into ServerTextControl, connected to MailMerge, and merged with JSON data. using var tx = new ServerTextControl(); tx.Create(); var loadSettings = new LoadSettings { ApplicationFieldFormat = ApplicationFieldFormat.MSWordTXFormFields }; tx.Load(templateBytes, BinaryStreamType.InternalUnicodeFormat, loadSettings); using var mailMerge = new TXTextControl.DocumentServer.MailMerge { TextComponent = tx, RemoveEmptyFields = false }; mailMerge.MergeJsonData(jsonData); tx.Save(out byte[] mergedDocument, BinaryStreamType.InternalUnicodeFormat); In a production integration, the template could come from a database, blob storage, a template repository, or another business application. The important part is that the final byte array is posted to SignFabric as a Base64 encoded document. Signer IDs and Signature Fields SignFabric validates that every signer in the API request has a matching signature field in the document. The rule is simple and explicit: signer id "provider" requires signature field "txsign_provider" signer id "client" requires signature field "txsign_client" This relationship is important because it connects the API recipient list to the physical signature boxes in the document. If the request contains a signer with the ID customer, but the document contains only txsign_provider and txsign_client, the API rejects the envelope. The sample therefore validates the merged document before submitting it. It reads the signature field names and compares them with the configured signer IDs. This catches configuration issues locally and prints a useful message before the API call is made. var requiredSignatureNames = signers .Select(signer => "txsign_" + signer.Id) .ToList(); var documentSignatureNames = tx.SignatureFields .Cast<SignatureField>() .Select(field => field.Name) .Where(name => !string.IsNullOrWhiteSpace(name)) .ToHashSet(StringComparer.OrdinalIgnoreCase); var missingSignatureNames = requiredSignatureNames .Where(name => !documentSignatureNames.Contains(name)) .ToList(); if (missingSignatureNames.Count > 0) { throw new InvalidOperationException( "The merged document does not contain matching signature fields for all signers." + Environment.NewLine + "Required signature fields: " + string.Join(", ", requiredSignatureNames) + Environment.NewLine + "Found signature fields: " + string.Join(", ", documentSignatureNames)); } The merged document does not contain enough signature fields for the configured signers. Required signature fields: txsign_customer, txsign_sales Found signature fields: txsign_provider, txsign_client After adjusting the configured signers to provider and client, the same document passes validation and can be submitted to SignFabric. Requesting an Access Token The SignFabric API is protected by bearer authentication. For first-party integrations, SignFabric includes a local OAuth client-credentials endpoint: /api/v1/oauth/token The console application sends a standard client credentials request: grant_type=client_credentials client_id=sf_... client_secret=sfsecret_... scope=envelopes:create envelopes:read The token endpoint accepts form encoded values or JSON. The important parameters are: grant_type: Must be client_credentials. client_id: The API client identifier configured in SignFabric. client_secret: The secret generated for the API client. scope: A space-separated list of requested API scopes, such as envelopes:create envelopes:read. The token is then attached to the envelope API request as a bearer token. using var response = await httpClient.PostAsync( "api/v1/oauth/token", new FormUrlEncodedContent(new Dictionary<string, string> { ["grant_type"] = "client_credentials", ["client_id"] = clientId, ["client_secret"] = clientSecret, ["scope"] = "envelopes:create envelopes:read" })); response.EnsureSuccessStatusCode(); var token = await response.Content.ReadFromJsonAsync<TokenResponse>(); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken); Creating the Envelope The merged document is submitted to the SignFabric envelope endpoint: /api/v1/envelopes The request includes the file name, the Base64 encoded document, the signer list, an optional signing certificate ID, and whether the envelope should be sent immediately. var request = new CreateEnvelopeApiRequest { FileName = "merged-envelope.tx", DocumentBase64 = Convert.ToBase64String(mergedDocument), SendImmediately = true, Signers = new List<CreateEnvelopeSignerApiRequest> { new() { Id = "provider", Name = "John Doe", Email = "john.doe@example.com" }, new() { Id = "client", Name = "Jane Doe", Email = "jane.doe@example.com" } } }; using var response = await httpClient.PostAsJsonAsync("api/v1/envelopes", request); response.EnsureSuccessStatusCode(); var envelope = await response.Content.ReadFromJsonAsync<CreateEnvelopeApiResponse>(); Console.WriteLine($"Envelope created: {envelope.EnvelopeId}"); The envelope endpoint expects a JSON body with the following values: fileName: The document name stored with the envelope. The extension must be allowed by the SignFabric upload policy. documentBase64: The merged document as a Base64 encoded string. signers: The recipient list for the envelope. Each signer requires an id, name, and email. signingCertificateId: Optional certificate ID used for the final signed PDF. sendImmediately: Optional flag that controls whether the envelope is submitted immediately after creation. When sendImmediately is set to true, SignFabric creates the envelope, validates the signature boxes, sends the signing invitations, and returns the resulting envelope status. { "success": true, "envelopeId": "180afbd0-d8f6-47c1-bf0f-d2d62508762f", "name": "merged-envelope.tx", "status": "Sent", "containsSignatureBoxes": true, "signers": [ { "id": "provider", "name": "John Doe", "status": "Sent" }, { "id": "client", "name": "Jane Doe", "status": "Sent" } ] } After the API call succeeds, the generated document appears as a regular SignFabric envelope with the configured recipients and workflow status. Authentication for API Calls Before an application can create envelopes, it needs an access token that is accepted by the SignFabric API. In local or first-party integration scenarios, this can be done with the built-in client credentials endpoint. In production environments, the same envelope call can be protected by the configured bearer authentication setup. From the perspective of the calling application, the token request is a setup step before creating the envelope. The envelope creation itself remains independent of where the document was generated or where the business data came from. Running the Sample The console sample is configured with an appsettings.sample.json file that contains the SignFabric URL, local OAuth client credentials, template path, JSON data path, output path, and signer list. dotnet build dotnet run -- --config appsettings.sample.json The client secret can also be supplied through an environment variable so it does not need to be stored in the sample configuration file: $env:SIGNFABRIC_CLIENT_SECRET = "<client-secret>" dotnet run -- --template .\SampleData\contract.tx The sample writes the merged document to an output folder before submitting it to SignFabric. This makes it easy to inspect the generated document when debugging template data, merge fields, or signature field names. Conclusion Combining TX Text Control mail merge with the SignFabric envelope API creates a clean integration path for document-driven business applications. Data can be merged into a reusable template inside your own application, and the resulting document can be handed directly to SignFabric as an envelope workflow. The most important implementation detail is the mapping between API signer IDs and signature fields in the generated document. With that mapping in place, SignFabric can act as a signing service for generated documents from CRM, ERP, contract management, and document automation systems. Frequently Asked Questions Can SignFabric envelopes be created from generated documents? Yes. A server-side application can generate or merge a document with TX Text Control and submit the resulting document to the SignFabric envelope API as a Base64 encoded file. Which API endpoint creates a SignFabric envelope? The envelope integration API uses POST /api/v1/envelopes. The request includes the file name, Base64 encoded document, signer list, optional signing certificate ID, and whether the envelope should be sent immediately. How does the console app authenticate against SignFabric? The sample uses the local OAuth client-credentials endpoint at /api/v1/oauth/token. It requests a bearer token with scopes such as envelopes:create and envelopes:read, then sends that token with the envelope API request. Why does SignFabric require txsign_ signature field names? SignFabric maps API signer IDs to physical signature fields in the document. A signer with the ID provider requires a signature field named txsign_provider. This makes the recipient-to-field relationship explicit and easy to validate. Can the generated document be inspected before it is sent? Yes. The sample writes the merged document to an output folder before submitting it to the API. This makes it easier to debug merge fields, generated content, and signature field names.