Output API: Composition guide

Table of Contents

1. Introduction

Starting with version v1 of the Xribe Runtime API it is possible to perform certain post-processing operations on PDF documents, termed composition. These operations are specified in a compose script and can involve inputs provided by the client, outputs generated from a template, or results from another operation in the compose script.

This document describes how compose scripts are used and which compose operations are available.

2. Compose script

In order to perform one or more compose operations you need to provide a script that specifies which operations need to be performed on which documents and in which order. This script must be passed to the message request as a reference to an independent file.

The following message request is a minimalistic example to perform a compose operation on two statically-provided PDF documents. It assumes the presence of two PDF documents and a compose script file in the referenced environment: PDFs/centimeter.pdf and PDFs/inch.pdf for the PDF documents on which the script will operate and Scripts/compose.json containing the script that will be executed.

Tip: the file name or extension given to the compose script does not matter, but using .json or .txt as extension allows for convenient editing in the Resource Browser.

{
   "projectID" : "b8920627-26b0-48f4-bfd1-15c22206edd0",
   "environmentID" : "667dee51-1e15-487c-b7ca-f1516b81ba87",
   "input" : [
      {
          "id"   : "centimeter",
          "type" : "resolve",
          "ref"  : "PDFs/centimeter.pdf"
      },
      {
          "id"   : "inch",
          "type" : "resolve",
          "ref"  : "https://datacenter.example.com/Documents/PDFs/inch.pdf"
      }
   ],
   "compose" : {
      "ref" : "Scripts/compose.json"
   }
}

As you can see, the message request assigns an id to each statically-provided PDF document. Each input that is provided statically must be of type resolve. See the Xribe Runtime API specification for other input types.

Statically provided resources must either reference a resource by path relative to the specified project and environment, or as an absolute HTTPS URL to an accessible resource. This URL may include query parameters (e.g. to pass a security token in case the resource is not publicly accessible).

The compose script in this example performs a pdf_append operation.

{
   "compose" : [
      {
         "operation" : "pdf_append",
         "inputrefs" : [
            "centimeter",
            "inch"
         ],
         "outputref" : "combined"
      }
   ],
   "primaryOutput" : [
      "combined"
   ]
}

The compose script references inputs by ID, regardless of the type of that input: an input may be statically provided and thus of type resolve, but it may also have been generated in a previous phase of the message request; in that case its type would be template. The compose script lists the operation to perform, the inputrefs on which the operation should be performed, and the ID to assign to the result of the operation: outputref. Finally, the script defines its primaryOutput: the outputref of the resource that will be considered the result of the script.

When the message request has finished processing, the Deliverable you can expect is similar to the sample output below.

{
   "id" : "7fe1402a-387a-4126-985a-166b88d9ebed",
   "account" : "account",
   "creator" : "account\\user",
   "created" : "2021-08-10T09:36:05.705Z",
   "modified" : "2021-08-10T09:36:05.705Z",
   "projectID" : "b8920627-26b0-48f4-bfd1-15c22206edd0",
   "environmentID" : "667dee51-1e15-487c-b7ca-f1516b81ba87",
   "messageID" : "040196a0-a8b4-4c0b-95a2-a3f23523af5e",
   "status" : "generated",
   "history" : [
      {
         "severity" : "info",
         "message" : "Changed status to created",
         "created" : "2021-08-10T09:36:05.705Z"
      },
      {
         "severity" : "info",
         "message" : "Changed status to generated",
         "created" : "2021-08-10T09:36:06.429Z"
      }
   ],
   "output": [
      {
         "type": "intermediate",
         "url": "https://resource-app-eu1.scripturaengage.com/resources/v2/data/cloud-resources/account/project/environment/PDFs/centimeter.pdf",
         "id": "centimeter"
      },
      {
         "type": "intermediate",
         "url": "https://resource-app-eu1.scripturaengage.com/resources/v2/data/cloud-resources/account/project/environment/PDFs/inch.pdf",
         "id": "inch"
      },
      {
         "type": "primary",
         "url": "https://inventiveproduction-updc-composition.s3.eu-west-1.amazonaws.com/account/b8920627-26b0-48f4-bfd1-15c22206edd0/667dee51-1e15-487c-b7ca-f1516b81ba87/040196a0-a8b4-4c0b-95a2-a3f23523af5e/output/combined.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIAR7NO35G5X5DAHL3Y%2F20210810%2Feu-west-1%2Fs3%2Faws4_request&X-Amz-Date=20210810T093610Z&X-Amz-Expires=600&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEKH%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCWV1LXdlc3QtMSJHMEUCIQD5GDRLiw7tpfiRkk6goe7yKbNdLg%2BZutgiA11U4LWXVwIgY4G648YS2yWbAGxcIDdJZi78JlEFA5pNp7mBKP2BDA8qrAIIuv%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FARADGgwxMzYxOTUwNzQ0OTEiDKEvl3ZEo0coitMtmyqAAlPHL%2FSyBiXTow8EmF%2BMM4WOGCcw2kpxRJjWjuGOmSOEQsk9OiiqMVkNg4moTuBjoRSLyuPxu%2Bn4XajIYLVheZNfV8yeD5%2Fy%2BfLGXtzHPqtQVJSnOVKlOG%2BAMfnq5I%2BHx%2B1V5%2Faa4uRdf9GeAdd7R5hpR2l%2FS8n7zaknvLNUi0I3hBwxkNg7pQUn%2BdDDmwwrErJQlpQV2T1Z1PIbdnLI%2BD3BeIxNVx8pvrRtVAaEcz9m8HmBJGJC337jwTwFRl04THoqBBaKXPrPlpFrtJbk%2FJBznUfCDTKolJ3yKtQM%2Fe8P0E1IjtBUY5HD9fm5WuHTgzaSqeMf0osIVlQJIjxafvMw7f%2FIiAY6mgEKrp%2F6KChFb19XcKY1l7KSWKRJUJnVksRW3oGCqlnsdsbnwBgoddh7ggfz1CQjTD7eKSfEslu9E7tbja4ncZAAwWSpxP4O8QwD9zlYY9gfHTeXH%2F%2Barc7NuobIhth1DhC1p8bxGIxjFu1nisltldj9%2FaW%2F%2B3IpcBuyelNhfaIAf9SEqQagb6%2BbqRvMOtAKC56bitdFI9ICilxV&X-Amz-Signature=97481e595b2453caf834b28afdf6cee3ff98d0c6d4e9127de6cf720088862a9d&X-Amz-SignedHeaders=host",
         "id": "combined"
      }
   ]
}

The Deliverable contains some general information such as the Deliverable ID (id), the user account that performed the request (account and creator), some timestamps (created and modified), the project, environment and message ID. The Deliverable’s status field evolves from generating to generated or error. When the status ends up in error state, the history items give information about what went wrong in the process. Possible errors can be related to resources that could not be found, problems during generation of output, validation errors in the compose script, or errors that occurred during the execution of the compose script.

Finally, the output field contains an array of all the produced output. The output of type primary is the result of the compose script that was requested via the primaryOutput field in the script. This primary output is located on an accessible location (in this example on AWS S3) using a URL that has a time-limited validity. At the time of writing the output array also includes outputs of type intermediate, which consist of output generated from a template, statically provided inputs, and intermediate PDF documents when the composition script contains multiple operations.

Note: there is no guarantee that intermediate outputs will continue to be provided in the future.

2.1. Formal definition

A compose script must be an object described in valid JSON syntax. It is also allowed to provide a JSONata script. Such a script will be applied to the message request and must also resolve into a valid JSON object.

Tip: use JSONata Exerciser to experiment with JSONata scripts. Place the message request body in the left (JSON) pane, write a JSONata script in the top right (JSONata) pane and check if the result of the script in the bottom right pane resolves in the intended composition script.

The rest of this document will describe the operation of the service as if plain JSON was provided.

The JSON script must have two fields: compose and primaryOutput.

The compose field must be an array with zero or more objects, each defining an operation. Operations are executed in the order in which they are specified.

Each operation object in the compose array has three required fields: operation, inputref(s) and outputref. The operation field contains the name of the operation to apply. Whether or not to use inputref or inputrefs depends on wether the operation takes a single input or multiple inputs. The outputref field assigns an ID to the result of that operation.

Depending on the specific operation, more fields may be required. See Compose operations for more details.

Note: all input and output IDs in the script must be unique. It is not allowed for operations to assign an outputref ID that is already in use by an input defined in the message request to the API or defined as outputref of another operation in the script. Also: at the moment an operation is performed, the input(s) it requires must be available (i.e. they must be provided statically in the API request, they must have been generated from a template, or they must be the result of a previous operation in the script).

Finally, the primaryOutput field in the script is an array in which exactly one ID must be listed.

2.2. Limitations

At the moment of writing there are some technical limitations that may prevent some compose scripts from completing successfully or cause an error before the script is ran.

The number of compose operations in a single compose script is limited to 100. In the unlikely event that you need to perform more than 100 operations, you need to split up the script into multiple scripts and perform them sequentially. When specifying more than 100 operations, the validation will fail before the script is started.

Currently, only one primary output is accepted for a compose script. When specifying more than one primary output, the validation will fail before the script is started.

The amount of storage available to the execution environment that runs the script is limited. Since storage use depends on the number and type of inputs and operations and the size of (intermediate or final) outputs, the amount of storage required cannot be calculated in advance. When too much storage space is used when executing the script, it will fail during its run. As a guideline it is recommended to keep the total sum size of all inputs below 200 MiB.

The script’s running time is limited to 15 minutes. This time includes fetching inputs from remote locations. When providing static input documents from a custom location (e.g. as an HTTPS URL to a document in your own data center), it is recommended to ensure that such location provides fast access.

The amount of memory available to the execution environment that runs the script is limited. Memory usage depends on the size and complexity of the input documents and images and on the resulting (intermediate or final) documents. When more memory is needed than is available, the script will fail during its run, but may not produce a clear error message. Such an out-of-memory situation has not yet been seen to occur with inputs less than 200 MiB in size.

Encrypted or password-protected PDF documents cannot be used in operations. When referencing a password-protected document in an operation, the script will fail during its run.

3. Compose operations

Below are the descriptions of the supported compose operations and their arguments. Required arguments are indicated with an asterisk. Optional arguments all have a default value that will be used when such argument is not specified in the script

3.1. Append

The append operation concatenates all supplied PDF documents in the given order.

3.1.1. Supported fields

operation*

pdf_append

inputrefs*

A nonempty array of IDs denoting PDF documents that need to be concatenated.

outputref*

An ID to assign to the result of the operation.

3.2. Overlay

The overlay operation places an image or a PDF page on specific pages of a base document, which must be a PDF document. You can specify the location and size of the overlay and whether it should be placed on the foreground or in the background. A background overlay could, for example, be used as a watermark on a page. You can also specify on which page(s) the overlay must be applied.

3.2.1. Supported fields

operation*

pdf_overlay

inputref*

The ID of the base document on which to apply the overlay.

overlayref*

The ID of an image in a supported format (JPEG, BMP, PNG, single-page TIFF) or of a single-paged PDF document.

outputref*

An ID to assign to the result of the operation.

x

A coordinate denoting the target location for the top left corner of the overlay. The default value for this field is 0, denoting the left side of the base document.

y

A coordinate denoting the target location for the top left corner of the overlay. The default value for this field is 0, denoting the top side of the base document.

width

A length denoting the desired width of the overlay. When this field is not specified, the overlay will keep its original width.

height

A length denoting the desired height of the overlay. When this field is not specified, the overlay will keep its original height.

fit

An indication of how the overlay should fit inside the rectangle defined by width and height. The default value for this field is fill.

fill

Fill the specified rectangle to the fullest, stretching one dimension of the overlay if it has a different aspect ratio than the rectangle defined by width and height.

clip

Reduce the dimensions of the specified rectangle to those of the provided overlay (if the specified rectangle is larger than the overlay) and then fill this rectangle to the fullest. If the target rectangle is larger than the overlay, the overlay will be added without resizing. If the target rectangle is smaller in both dimensions than the overlay, clip will have the same effect as fill.

aspect-fill

Fill the the specified rectangle to the fullest, keeping the aspect ratio of the overlay constant.

aspect-down

Keep the aspect ratio of the overlay constant and only make the overlay smaller to fit the specified rectangle, not larger.

background

Indicates where to place the overlay. The dault value for this field is true.

true

Watermark mode: the overlay is positioned underneath the content of the base document.

false

Stamping mode: the overlay is positioned on top of the content of the base document, obscuring any base content that might be present at the chosen location.

pages

A page identification. The default value for this field is all, causing the overlay to be applied to all pages in the base document.

3.3. Add QR barcode

The add QR barcode operation places a QR barcode on specific pages of a base document, which must be a PDF document. You can specify the location and size of the QR code. You can also specify on which page(s) the QR code must be placed.

3.3.1. Supported fields

operation*

pdf_add_qr

inputref*

The ID of the base document on which to place the QR code.

data*

The data to be encoded in the QR code. This value must be expressed as a string.

outputref*

An ID to assign to the result of the operation.

x*

A coordinate denoting the target location for the top left corner of the QR code.

y*

A coordinate denoting the target location for the top left corner of the QR code.

size*

A length denoting the desired width and height of the QR code.

eccLevel

A level of error correction to be applied to the QR code. Valid values are L, M, Q or H. The default value for this field is Q.

pages

A page identification. The default value for this field is first, causing the QR code to be placed on only the first page of the base document.

3.4. Rescale

The rescale operation reduces the size of the content of specific pages of a base document, which must be a PDF document. Note that this operation does not reduce the size of pages as a whole: pages keep their original size, but the content is scaled down. This allows for creating blank space in which, for example, an overlay or a QR code may be placed.

3.4.1. Supported fields

operation*

pdf_rescale

inputref*

The ID of the base document that needs its content scaled down.

outputref*

An ID to assign to the result of the operation.

scalex

A decimal value between 0 and 1 denoting the scale factor to be applied to the horizontal dimension. The default value for this field is 1.0, meaning that content will not be scaled at all.

scaley

A decimal value between 0 and 1 denoting the scale factor to be applied to the vertical dimension. The default value for this field is 1.0, meaning that content will not be scaled at all.

pages

A page identification. The default value for this field is all, causing the content of all pages in the base document to be scaled.

anchor

A specifier that determines which part of the scaled content will remain in its original position. The default value for this field is middle-center.

top-left

The top left corner of the content will remain in-place. There will appear empty bands on the right and bottom side of the page.

top-center or top

The top edge of the content will remain in-place. There will appear empty bands on the left, right and bottom side of the page.

top-right

The top right corner of the content will remain in-place. There will appear empty bands on the left and bottom side of the page.

middle-left or left

The left edge of the content will remain in-place. There will appear empty bands on the top, bottom and right side of the page.

middle-center or center

The center of the content will remain in-place. There will appear empty bands all around the content.

middle-right or right

The right edge of the content will remain in-place. There will appear empty bands on the top, bottom and left side of the page.

bottom-left

The bottom left corner of the content will remain in-place. There will appear empty bands on the top and right side of the page.

bottom-center or bottom

The bottom edge of the content will remain in-place. There will appear empty bands on the left, right and top side of the page.

bottom-right

The bottom right corner of the content will remain in-place. There will appear empty bands on the left and top side of the page.

4. Common fields

Some fields are common to more than one operation. These are described here.

4.1. Distances

Distances are used as coordinates or as length specifiers. When used as a coordinate, the distance is relative to the top left corner of a document.

A distance can be expressed as an absolute value or as a contextual value. Absolute values consist of a nonnegative whole or decimal number, optionally followed by a unit. Supported units are mm (millimeter), cm (centimeter), in (inch), pt (point) and px (pixel). When no unit is specified, the value is considered to be expressed in mm. When a value is expressed in pt or px, it is interpreted at 72 dpi; so a value of 100 pt is equal to 1.389 in or 35.278 mm.

A distance can also be expressed as a contextual value: page-width or page-height. The concrete distance this resolves to depends on the page size on which the operation applies.

Example: When specifying page-width and page-height as values for the width and height arguments of the pdf_overlay operation, the overlay will be stretched to the full page size for each page in the base document, even if not all pages in that document have the same size. This can be useful to apply a watermark, for example: a PDF document with the word SPECIMEN could be applied as a background overlay to a variety of base documents without the need to match the page size of the watermark document with the page sizes of those base documents.

4.2. Page identification

A page identification is a comma-separted list of pages, page ranges, or shortcuts on which an operation should apply. If nothing is specified, it depends on the operation what the default behavior will be.

A page is specified as a positive whole number where the first page in a document is treated as page 1.

A page range is either a set of two positive whole numbers separated by a dash, or an open range consisting of a single positive number and a dash. For example 5 - 10 (denoting pages 5, 6, 7, 8, 9 and 10), - 3 (denoting pages 1, 2 and 3), 3 - (denoting all pages in the document, except 1 and 2).

Finally, a page can also be specified as a shortcut: first, last, odd, even and all. Here first denotes page 1, last denotes the last page in the document, however many pages might be in it; odd denotes pages 1, 3, 5, etc; even denotes pages 2, 4, 6, etc; and all denotes all pages in the document.

Examples:

1 - 3, last

The first three pages and the last one of the document.

first, last

The first page and the last page in the document.

even, last

All even pages in the document and also the last page, regardless of whether the document contains an even or an odd number of pages.

1 - 4, odd, last

The first four pages in the document (pages 1, 2, 3 and 4), all odd pages (pages 1, 3, 5, 7, etc) and the last page of the document.

- 10, 5 -

All pages in the document (the ranges of pages from 1 to 10 and from 5 to the end of the document overlap).

Note: a page specifier that includes more pages than are present in a base document (e.g. the range 1 - 10 applied to a base document with only three pages), or a page specifier that includes pages more than once (e.g. 1 - 5, odd, first, last, 3) has no adverse effects.

5. Example scripts

5.1. Applying a watermark

Scenario: You want to generate a sample of a document by placing the words SPECIMEN in the background.

Prerequisites: A template and datasource for the document to generate and a single-page PDF document that contains the word SPECIMEN in a shade of gray. In this sample the template is generated from Templates/invoice.sdt and receives ID basedocument. The specimen document is provided statically as PDFs/specimen.pdf and receives ID specimen.

Sample message request:

{
   "projectID" : "b8920627-26b0-48f4-bfd1-15c22206edd0",
   "environmentID" : "667dee51-1e15-487c-b7ca-f1516b81ba87",
   "input" : [
      {
         "id"   : "specimen",
         "type" : "resolve",
         "ref"  : "PDFs/specimen.pdf"
      },
      {
         "id"   : "basedocument",
         "type" : "template",
         "ref"  : "Templates/invoice.sdt",
         "data" : {},
         "outputParameters" : {
            "type" : "pdf"
         }
      }
   ],
   "compose" : {
      "ref": "Scripts/apply-watermark.json"
   }
}

Compose script:

{
   "compose": [
      {
         "operation"  : "pdf_overlay",
         "inputref"   : "basedocument",
         "overlayref" : "specimen",
         "outputref"  : "watermarked",
         "x"          : 0,
         "y"          : 0,
         "width"      : "page-width",
         "height"     : "page-height",
         "fit"        : "fill",
         "background" : true,
         "pages"      : "all"
      }
   ],
   "primaryOutput" : [
      "watermarked"
   ]
}

Note that numbers and booleans can be specified as a string or as a native value as in the example above.

The result of the request will be available in the Deliverable output object with ID watermarked.

5.2. Concatenating documents (simple)

Scenario: A customer wants to receive his digital invoices by regular mail. To prevent having to create multiple invoice templates (one for delivery as attachment to an e-mail and one with a mail address at the correct position for a windowed envelope), we generate the invoice from the regular digital invoice template and add a cover page that contains the customer’s address at the correct position. We also add a small QR code to the cover page to steer the enveloping machine. Finally, we add a pregenerated 'terms of service' page to the document.

Prerequisites: An invoice template and datasource: Templates/invoice.sdt receives ID invoice. An addressee template and datasource: Templates/addressee-cover-page.sdt receives ID addressee. A static PDF containing the terms of service: PDFs/terms-of-service-v1.3.pdf receives ID terms.

Sample message request:

{
   "projectID" : "b8920627-26b0-48f4-bfd1-15c22206edd0",
   "environmentID" : "667dee51-1e15-487c-b7ca-f1516b81ba87",
   "input" : [
      {
         "id"   : "terms",
         "type" : "resolve",
         "ref"  : "PDFs/terms-of-service-v1.3.pdf"
      },
      {
         "id"   : "addressee",
         "type" : "template",
         "ref"  : "Templates/addressee-cover-page.sdt",
         "data" : {},
         "outputParameters" : {
            "type" : "pdf"
         }
      },
      {
         "id"   : "invoice",
         "type" : "template",
         "ref"  : "Templates/invoice.sdt",
         "data" : {},
         "outputParameters" : {
            "type" : "pdf"
         }
      }
   ],
   "compose" : {
      "ref": "Scripts/concatenate-documents.json"
   }
}

Compose script:

{
   "compose": [
      {
         "operation" : "pdf_add_qr",
         "inputref"  : "addressee",
         "outputref" : "addressee-with-qr",
         "data"      : "a steering code",
         "x"         : "10 mm",
         "y"         : "25 mm",
         "size"      : "15 mm",
         "pages"     : "first"
      },
      {
         "operation" : "pdf_append",
         "inputrefs" : [
            "addressee-with-qr",
            "invoice",
            "terms"
         ],
         "outputref" : "mailable-invoice"
      }
   ],
   "primaryOutput" : [
      "mailable-invoice"
   ]
}

The result of the request will be available in the Deliverable output object with ID mailable-invoice. It will be a single PDF document with the first page containing the customer’s address, the following page(s) containing the invoice information and the last page(s) containing the terms of service.

5.3. Adding a transpromo banner

Scenario: You want to add a narrow information banner to an invoice, notifying customers of a relevant promotion or offer. Since such a promotion or offer is time-bound and may be targeted to specific customer segments, you don’t want to create multiple templates or edit templates frequently. Moreover, the marketing department that creates the promotional collateral may not be in a position to alter invoice templates. In order to add transpromo banners to invoices, we take a regular invoice statement, downscale the content slightly in the vertical dimension and add the promotional banner.

Prerequisites: An invoice template and datasource: Templates/invoice.sdt receives ID invoice. A banner image supplied by the marketing department: Marketing/promo-banner-black-friday.tiff receives ID banner.

Sample message request:

{
   "projectID" : "b8920627-26b0-48f4-bfd1-15c22206edd0",
   "environmentID" : "667dee51-1e15-487c-b7ca-f1516b81ba87",
   "input" : [
      {
         "id"   : "banner",
         "type" : "resolve",
         "ref"  : "Marketing/promo-banner-black-friday.tiff"
      },
      {
         "id"   : "invoice",
         "type" : "template",
         "ref"  : "Templates/invoice.sdt",
         "data" : {},
         "outputParameters" : {
            "type" : "pdf"
         }
      }
   ],
   "compose" : {
      "ref": "Scripts/apply-transpromo.json"
   }
}

Compose script:

{
   "compose": [
      {
         "operation" : "pdf_rescale",
         "inputref"  : "invoice",
         "outputref" : "rescaled-invoice",
         "scalex"    : 1,
         "scaley"    : 0.88,
         "pages"     : "first",
         "anchor"    : "bottom"
      },
      {
         "operation"  : "pdf_overlay",
         "inputref"   : "rescaled-invoice",
         "overlayref" : "banner",
         "outputref"  : "invoice-with-banner",
         "x"          : 0,
         "y"          : "5 mm",
         "width"      : "page-width",
         "height"     : "30 mm",
         "fit"        : "aspect-down",
         "background" : false,
         "pages"      : "first"
      }
   ],
   "primaryOutput" : [
      "invoice-with-banner"
   ]
}

Note: In this sample we expect that the invoice is generated in A4 size (210 x 297 mm). We scale vertically by 0.88 with a bottom anchor, meaning that a space of 35 mm at the top of the page is freed. When placing the banner we leave a blank space of 5mm at the top of the page and make the banner fit in the next 30mm. We use a fit of aspect-down so that the banner keeps its original aspect ratio and is not scaled up (which might cause aliasing artifacts).

The result of the request will be available in the Deliverable output object with ID invoice-with-banner.

5.4. Concatenating documents (dynamic)

As mentioned in Formal definition, it is possible for a compose script to contain JSONata. One example of the advantage of using JSONata is that it can allow you to create reusable compose scripts that are not dependent on predefined input names or a fixed number of inputs.

Below is a compose script that appends all inputs specified in the API request. An example use case could be a request to generate PDF output from one or more templates and adding zero or more statically referenced PDF attachments.

{
   "compose": [
      {
         "operation" : "pdf_append",
         "inputrefs" : [
            $.input.id
         ],
         "outputref" : "merged"
      }
   ],
   "primaryOutput" : [
      "merged"
   ]
}

This JSONata script is applied to the API request. Regardless of how many inputs it defines (generated from a template or provided statically), they will all be appended into a single PDF document that will be available in the Deliverable output object with ID merged.

Note: when using JSONata this way, the order in which inputs are defined in the request becomes important as it defines the order in which the documents will be appended.

Comments or suggestions?
Tell us here.

If you have any suggestions or comments about this guide, please send us an email using this form.