ReportingCloud

Web API

Topic

Your first ReportingCloud document is an invoice: the demo template sample_invoice.tx from your template storage, filled with JSON data and returned as a PDF file. The steps below create it with curl in a bash shell, without an SDK and without code of your own. The SDKs send the same request to the Web API, so the commands also show what any HTTP client in any language has to send.

Prerequisites

  • A ReportingCloud account. A trial account is enough; Creating an Account shows how to sign up. Every new trial account has the demo template sample_invoice.tx in its template storage.
  • An API key. Create one on the Manage Account page of the ReportingCloud portal, as API Keys describes.
  • A bash shell with curl, jq and GNU base64, as on Linux or in the Windows Subsystem for Linux. jq reads the JSON responses, and base64 decodes the document.

Store the API Key

Open a terminal and store your API key in an environment variable:

export REPORTINGCLOUD_API_KEY="<API key>"

Replace <API key> with the key from the portal. The commands below read the key from this variable, and so do the ASP.NET Core and PHP tutorials. Treat the key like a password: whoever has it creates documents on your quota.

Check the Template Storage

Every request to the Web API carries the API key in the Authorization header: the word ReportingCloud-APIKey, a space and the key. A request that lists the templates of your storage shows that the key works:

curl -s -H "Authorization: ReportingCloud-APIKey $REPORTINGCLOUD_API_KEY" \
  "https://api.reporting.cloud/v1/templates/list" | jq -r '.[].templateName'

The endpoint GET /v1/templates/list returns a JSON array with one object per template, each with the properties templateName, modified and size. jq prints the names, and sample_invoice.tx is among them.

If jq reports an error instead, the Web API has answered with an error message rather than a list. Send the command again without | jq -r '.[].templateName' to see it, and look it up under Troubleshooting.

Merge the Template

The endpoint POST /v1/document/merge takes the name of a stored template and the format of the result as query parameters, and the data as JSON in the request body. It answers with the merged document.

  1. Save the following JSON as invoice.json in the current directory. It is the request body, a MergeBody object whose mergeData property holds the data:

    {
      "mergeData": [
        {
          "yourcompany_companyname": "Text Control, LLC",
          "yourcompany_zip": "28226",
          "yourcompany_city": "Charlotte",
          "yourcompany_street": "6926 Shannon Willow Rd, Suite 400",
          "yourcompany_phone": "704 544 7445",
          "yourcompany_fax": "704-542-0936",
          "yourcompany_url": "www.textcontrol.com",
          "yourcompany_email": "sales@textcontrol.com",
          "invoice_no": "778723",
          "billto_name": "Joey Montana",
          "billto_companyname": "Montana, LLC",
          "billto_customerid": "123",
          "billto_zip": "27878",
          "billto_city": "Charlotte",
          "billto_street": "1 Washington Dr",
          "billto_phone": "887 267 3356",
          "payment_due": "20/1/2016",
          "payment_terms": "NET 30",
          "salesperson_name": "Mark Frontier",
          "delivery_date": "20/1/2016",
          "delivery_method": "Ground",
          "delivery_method_terms": "NET 30",
          "recipient_name": "Joey Montana",
          "recipient_companyname": "Montana, LLC",
          "recipient_zip": "27878",
          "recipient_city": "Charlotte",
          "recipient_street": "1 Washington Dr",
          "recipient_phone": "887 267 3356",
          "item": [
            {
              "qty": "1",
              "item_no": "1",
              "item_description": "Item description 1",
              "item_unitprice": "2663",
              "item_discount": "20",
              "item_total": "2130.40"
            },
            {
              "qty": "1",
              "item_no": "2",
              "item_description": "Item description 2",
              "item_unitprice": "5543",
              "item_discount": "0",
              "item_total": "5543"
            }
          ],
          "total_discount": "532.60",
          "total_sub": "7673.4",
          "total_tax": "537.138",
          "total": "8210.538"
        }
      ]
    }
    
  2. Send it to the Web API:

    curl -s -X POST "https://api.reporting.cloud/v1/document/merge?templateName=sample_invoice.tx&returnFormat=PDF" \
      -H "Authorization: ReportingCloud-APIKey $REPORTINGCLOUD_API_KEY" \
      -H "Content-Type: application/json" \
      --data-binary @invoice.json \
      -o response.json \
      -w '%{http_code}\n'
    

    curl saves the response body in response.json and prints the HTTP status code, 200 when the merge succeeded.

  3. Decode the document from the response into a PDF file:

    jq -r '.[0]' response.json | base64 --decode > invoice.pdf
    

Open invoice.pdf in a PDF viewer to see the merged invoice. A trial account adds the ReportingCloud logo to every document it creates.

What the Request Does

  • The endpoint POST /v1/document/merge merges a template with data. The Web API is reached over HTTPS only, at https://api.reporting.cloud/, and every endpoint is below /v1/.
  • templateName names a template in your template storage. Without it, the request carries the template itself, encoded as Base64 in the template property of the body, as the mail merge overview describes.
  • returnFormat selects the format of the document: PDF, PDFA, RTF, DOC, DOCX, HTML, TX or TXT, and PDF without it. A trial account creates no PDF/A documents.
  • The Authorization header authenticates the request with the API key. The Web API also accepts a Basic header with your user name and password, but API keys are recommended; Authentication compares the two.
  • mergeData is an array with one object per record, the data of one document. Each property is matched with the merge field of the same name in the template, a placeholder such as invoice_no. The array item fills the merge block item, a part of the template that is repeated for each element, here a table row per line item. Merge Data explains the format.
  • The response is a JSON array of strings, each a created document encoded as Base64, such as ["JVBERi0xLjQNJeLjz9MNMSAwIG9iago8PAovVH..."]. jq -r '.[0]' takes the first string without its quotes, and base64 --decode turns it back into the binary PDF.
  • The document quota. Each successful merge request counts 1 against the monthly document quota of your plan. Plans and Licensing lists the quotas.

Merge More Than One Record

Each object in mergeData is merged with the whole template, and the query parameter append decides what the Web API returns for several records: append=false returns one document per record, and append=true one document with all records appended to each other, as does a request without append. So pass the value you want; Create One Document or One per Record compares the two.

Add a second object to the array in invoice.json, for example a copy of the first with another invoice_no, and send the request of step 2 again with &append=false added to its query string. The response then holds two Base64 strings, and the following loop decodes each into a file of its own, invoice-0.pdf and invoice-1.pdf:

for i in $(jq 'keys[]' response.json); do
  jq -r ".[$i]" response.json | base64 --decode > "invoice-$i.pdf"
done

With &append=true instead, the response holds a single string: one document with both invoices.

To create a Word document, set returnFormat=DOCX and save the decoded result as invoice.docx. Supported File Formats lists the formats of every endpoint.

Troubleshooting

When the Web API answers with an error, response.json holds the error instead of a document, jq reports an error in step 3 and invoice.pdf stays empty. Look at the response with cat response.json and at the status code that curl printed:

ResponseCauseFix
500, {"Message":"An error has occurred."}The request has no Authorization header, for example because the -H "Authorization: ..." line is missing from the command.Send the command with the Authorization header, as in step 2.
403The API key is empty, wrong or deleted, the document quota of the month is used up or more than two requests of your account arrived at the same time. An empty REPORTINGCLOUD_API_KEY sends the header without a key, and the Web API answers Invalid username/password combination or invalid APIKey.Run the export command of Store the API Key again in the shell that sends the request, compare the key with the list on Manage Account, check the quota on the dashboard of the portal, and send requests one after the other.
400The template is not in your template storage, or the body holds no data.Check the name with the template list above and that invoice.json has the mergeData property.

The processing time of a request is limited to 60 seconds, after which the Web API cancels it; a typical document takes less than 5 seconds. Errors and Status Codes describes every error of the Web API.

Next Steps

  • ASP.NET Core: merge a template from an ASP.NET Core application with the .NET SDK.
  • PHP: merge this invoice with the PHP SDK.
  • Merge Data: how JSON objects and arrays map to merge fields and merge blocks.
  • Authentication: API keys and Basic authentication for every request.
  • POST /v1/document/merge: every parameter, the merge settings and the responses of the endpoint.