Using the API of an NLG Studio App
You can embed calls to your Arria Studio application within web pages and other web services, making it possible for your users to receive dynamically generated content. This is fairly technical, so some level of programming knowledge is assumed.
Index
Accessing the API
Application programming interface (API) deployment makes your application available at an API (or REST) endpoint on the web that can be accessed by any web service or program that holds a valid API key. To make this work, you need two things:
The URL of the API endpoint for the current published version of your application. The URL is shown in a pop-up window when you publish the project and is available afterward in the Publish view (see Publish View > API endpoint).
A valid API key. You can generate or regenerate a key from the API tab in the Publish view (see Publish View > API Key).
Note
Only the project owner can generate API keys.
Calling your project’s API endpoint
To call your published project’s endpoint you need to send it data with an HTTP POST request.
This can be done with one of the following methods:
Studio Runner — an Arria website that enables you to send data to your project’s endpoint and generate text.
The Postman utility — see our Postman example.
The curl utility — see our curl example.
Programmatically — experienced developers only.
The URL for your project’s API endpoint
The URL for the HTTP POST request is the one generated when you publish your project (see Publishing your project). Studio uses the secure version of HTTP so the URL starts with “https” and should look similar to the one below:
|
Authentication with your project’s API endpoint
The API key for your project is required for authentication. You must include the key in the Authorization header of all HTTP requests you send to the API. The Authorization type is 'Bearer':
|
Tip
Note the US English spelling of authorization; the British spelling does not work.
Cross-Origin Resource Sharing (CORS)
If you want to call the endpoint from within a web application where the call to the project endpoint is made from within the browser, you must first add the domain to the CORS list on the the API tab within the Publish view.
Please see Publish View > API key and Deploying a Studio app for details.
Supplying data to your project’s API endpoint
Data sent to your project’s API endpoint is contained in the Request body of the HTTP request. This data must be correctly formatted for the relevant project type. See the following sections for guidance:
Example calls using Postman and curl
To demonstrate how HTTP requests to a project’s API endpoint work, see:
The request body
The request body is a JSON object containing three root-level fields. These fields are optional, but there must still be a JSON object even if the object is empty — i.e. {}
. The three root-level fields are:
Field | Notes |
---|---|
| An array of data objects (or single data object) in JSON format that corresponds to the data required for a single run of your application. This root-level field includes subfields that specify the type as well as the actual data for the project. You must convert CSV data to JSON format. |
| You can use this field to define the focus row for the project. When you specify a row name within the |
| This field allows you to configure the runtime behavior for your project. See Request body options. |
CSV data conversion
The best way to convert CSV data to the correct format for an API call is to use our Convert data to API format feature.
To convert CSV data manually, you must:
Enclose each data item inside double quotes.
Enclose each line of your CSV data within square brackets.
Add a commas at the end of each line.
Enclose the entire dataset within square brackets.
Example:
Data Before Conversion | Data After Conversion |
---|---|
City, Country, Population Tokyo, Japan, 38001000 Delhi, India, 25703168 Shanghai, China, 23740778 | [ ["City", "Country", "Population"], ["Tokyo", "Japan", "38001000"], ["Delhi", "India", "25703168"], ["Shanghai", "China", "23740778"] ] |
Also, you must wrap the converted data in the format required for the request body — see Request Body Examples for guidance.
JSON data conversion
To convert JSON data to the correct format for the API call, use our Convert data to API format feature.
If you want to configure your JSON data manually, remember that JSON data configured as a JSON object does not require conversion to JSON since it is already JSON!
However, additional code is required to call the API endpoint.
Tip
For an example, see Example request — Describe a JSON Object.
Request body examples
This section includes an example request for each project type:
Example request — Describe Each Row
The following request body works with a published version of the "Describe Each Row" sample project. Note how the project's CSV data has been converted to the correct format and given as the value for the dataSet
field.
The type
value is always 1d for "Describe Each Row" projects.
{ "data": [ { "id": "Primary", "type": "1d", "dataSet": [ ["State", "Premier", "Party", "Terms", "StateLandArea", "StatePop2010", "StatePop2016", "Capital", "CapitalPop2010", "CapitalPop2016"], ["Victoria", "Daniel Andrews", "ALP", "1", "227,416", "5,547,500", "5,938,100", "Melbourne", "3,953,939", "4,353,514"], ["the Australian Capital Territory", "Andrew Barr", "ALP", "1", "2,358", "358,900", "390,800", "Canberra", "398,430", "424,666"], ["the Northern Territory", "Michael Gunner", "ALP", "1", "1,349,129", "229,700", "244,600", "Darwin", "112,987", "123,396"] ] } ], "options": { "nullValueBehaviour": "SHOW_IDENTIFIER", "contentOutputFormat": "HTML" } }
A separate response is returned for each row of table data.
Example request — Describe the Table
This example uses the "Describe the Table" sample project. The data is given in the same format as above.
The type
value is always 2d for "Describe the Table" projects.
{ "data": [ { "id": "Primary", "type": "2d", "dataSet": [ ["State", "Premier", "Party", "Terms", "StateLandArea", "StatePop2010", "StatePop2016", "Capital", "CapitalPop2010", "CapitalPop2016"], ["New South Wales", "Mike Baird", "Liberal", "1", "800,641", "7,238,800", "7,618,200", "Sydney", "4,183,471", "4,526,479"], ["Victoria", "Daniel Andrews", "ALP", "1", "227,416", "5,547,500", "5,938,100", "Melbourne", "3,953,939", "4,353,514"], ["Queensland", "Annastacia Palaszczuk", "ALP", "1", "1,730,647", "4,516,400", "4,779,400", "Brisbane", "2,019,074", "2,209,453"], ["Western Australia", "Colin Barnett", "Liberal", "2", "2,529,875", "2,296,400", "2,591,600", "Perth", "1,723,218", "1,958,912"], ["South Australia", "Jay Weatherill", "ALP", "2", "983,482", "1,644,600", "1,698,600", "Adelaide", "1,225,668", "1,288,681"], ["Tasmania", "Will Hodgman", "Liberal", "1", "68,401", "507,600", "516,600", "Hobart", "203,446", "209,254"], ["the Australian Capital Territory", "Andrew Barr", "ALP", "1", "2,358", "358,900", "390,800", "Canberra", "398,430", "424,666"], ["the Northern Territory", "Michael Gunner", "ALP", "1", "1,349,129", "229,700", "244,600", "Darwin", "112,987", "123,396"] ] } ], "options": { "nullValueBehaviour": "SHOW_IDENTIFIER", "contentOutputFormat": "HTML" } }
Example request — Describe Row in Context
This example uses the "Describe Row in Context" sample project. The data is given in the same format as above.
The type
value is always 2d for "Describe Row in Context" projects.
Note the use of the FocusRow
field — a subfield of projectArguments
— to specify the name of the focus row. Giving "Victoria" for the FocusRow
value means the request is for that row's generated narrative only.
Note
If no focus row is specified, a separate narrative is generated for each row of data in the dataSet
field.
{ "data": [ { "id": "Primary", "type": "2d", "dataSet": [ ["State", "Premier", "Party", "Terms", "StateLandArea", "StatePop2010", "StatePop2016", "Capital", "CapitalPop2010", "CapitalPop2016"], ["New South Wales", "Mike Baird", "Liberal", "1", "800,641", "7,238,800", "7,618,200", "Sydney", "4,183,471", "4,526,479"], ["Victoria", "Daniel Andrews", "ALP", "1", "227,416", "5,547,500", "5,938,100", "Melbourne", "3,953,939", "4,353,514"], ["Queensland", "Annastacia Palaszczuk", "ALP", "1", "1,730,647", "4,516,400", "4,779,400", "Brisbane", "2,019,074", "2,209,453"], ["Western Australia", "Colin Barnett", "Liberal", "2", "2,529,875", "2,296,400", "2,591,600", "Perth", "1,723,218", "1,958,912"], ["South Australia", "Jay Weatherill", "ALP", "2", "983,482", "1,644,600", "1,698,600", "Adelaide", "1,225,668", "1,288,681"], ["Tasmania", "Will Hodgman", "Liberal", "1", "68,401", "507,600", "516,600", "Hobart", "203,446", "209,254"], ["the Australian Capital Territory", "Andrew Barr", "ALP", "1", "2,358", "358,900", "390,800", "Canberra", "398,430", "424,666"], ["the Northern Territory", "Michael Gunner", "ALP", "1", "1,349,129", "229,700", "244,600", "Darwin", "112,987", "123,396"] ] } ], "projectArguments": { "vars": { "FocusRow": "Victoria" } }, "options": { "nullValueBehaviour": "SHOW_IDENTIFIER", "contentOutputFormat": "TEXT" } }
Example request — Describe a JSON Object
This request body works with a published version of the "Describe a JSON Object" sample project. The data for this project, which is already in JSON format, is given as the value for the jsonData
field.
The type
value is always json for "Describe a JSON Object" projects.
IMPORTANT: Don’t forget to close the brackets at the end of the data: } ] }
{ "data":[ { "id":"Primary", "type":"json", "jsonData": { "yr2015": { "Revenue": [ { "name": "Premium Income", "value": "21543" }, { "name": "Net investment income", "value": "6387" }, { "name": "Fees and other income", "value": "797" } ], "Expenses": [ { "name": "Policyholders' benefits", "value": "16300" }, { "name": "Change in policyholders' reserves", "value": "8592" }, { "name": "Change in group annuity reserves assumed", "value": "-942" }, { "name": "General insurance expenses", "value": "1793" }, { "name": "Commissions", "value": "869" }, { "name": "State taxes, licenses and fees", "value": "187" }, { "name": "Dividends to policyholders", "value": "1728" }, { "name": "Federal income tax (benefit) expense", "value": "-153" }, { "name": "Net realized capital (losses) gains", "value": "59" } ] }, "yr2016": { "Revenue": [ { "name": "Premium Income", "value": "22166" }, { "name": "Net investment income", "value": "6334" }, { "name": "Fees and other income", "value": "1283" } ], "Expenses": [ { "name": "Policyholders' benefits", "value": "19046" }, { "name": "Change in policyholders' reserves", "value": "7387" }, { "name": "Change in group annuity reserves assumed", "value": "-1510" }, { "name": "General insurance expenses", "value": "2251" }, { "name": "Commissions", "value": "938" }, { "name": "State taxes, licenses and fees", "value": "237" }, { "name": "Dividends to policyholders", "value": "1566" }, { "name": "Federal income tax (benefit) expense", "value": "-326" }, { "name": "Net realized capital (losses) gains", "value": "-208" } ] } } } ], "options": { "nullValueBehaviour": "SHOW_IDENTIFIER", "contentOutputFormat": "HTML" } }
API responses
The return from the HTTP request to the API endpoint includes an HTTP status code and (optionally) a response body. A successful call to the endpoint returns a status code of 200; other codes, such as 400, indicate errors.
(You won't see the status code or response body when using Studio Runner.)
If the call is successful, the code is 200 and the response body is a JSON array. For "Describe the Table" and "Describe a JSON Object" projects, there is only one element in the array because those projects return a single narrative. For "Describe Each Row" and "Describe Row in Context" projects, there is an element for each narrative — that is, one for each row. Each array element contains these fields:
Field | Notes |
---|---|
| Indicates the type of error when narrative generation fails. Null if there are no errors. |
| Provides a description of the error when narrative generation fails. Null if there are no errors. |
| Shows a list of warning messages produced at runtime. Normally, this is empty — i.e. |
| A string containing the text generated by your project for the input data. Usually, this is in HTML format, though you can request plain text if preferred (see Request body options). This field is null when narrative generation fails. |
| The word count for the generated text. |
Here is the response for a successful call.
If the call to the API endpoint is unsuccessful, the HTTP code will be one other than 200:
In such cases, the response body is typically a single JSON object (as above). For some errors, the response body is empty.