Speakable Summarizer API

API change history

This API gives you RESTful access to our Speakable Summarizer NLP engine.

The Speakable Summarizer is most suitable for producing fluently readable summaries with broadcast applications in mind (example: for likes of Alexa, Google Assistant). This summarizer's strong suit is to cover the main topic from the input documents, so it is best used in cases where we know that the inputs will have a clear focus. Speakable summaries can be optimized to suit client needs, especially if the client provides editorial guidelines and sufficient training data on which we can optimize.

Summarize

Try it

Request

Request URL

Request headers

  • (optional)
    string
    Media type of the body sent to the API.
  • string
    Subscription key which provides access to this API. Found in your Profile.

Request body

The POST request body should be a JSON of the following format:

{
    "summary_length_words": "<how many approximate words the output summary should contain>",
    "articles": [<Article objects>]

}

The Article objects must have one of the following two formats:

  • Web article URLs:

    { "url": "https://www.reuters.com/article/us-usa-immigration/white-house-softens-tone-after-threat-to-close-border-with-mexico-idUSKCN1RE1PE" }
    
  • Article title and body in plain text:

    {
      "title": "An unlikely contender, Sanders takes on ‘billionaire class’ in 2016 bid",
      "text": "The White House took a step back on Tuesday from a threat to close the U.S. border with Mexico, even as a redeployment of border officers in recent days has led to a slowdown of legal crossings and commerce at U.S. ports of entry there. White House spokeswoman Sarah Sanders said the..."
    }
    

Passing multiple input

You can perform multi-document summarization by passing multiple article URLs or text in the request body. The algorithm assumes the input articles are about the same topic or story.

If you pass two distinct stories, the summary for that cluster will not be very meaningful. For example, a story about a semiconductor company’s stock falling due to an earthquake and a story about the earthquake itself are related stories but are distinct stories.

Multiple input can be passed in this JSON format:

{
    "summary_length_words":"100",
    "articles":[
      {
        "url": "https://venturebeat.com/2017/05/03/microsoft-invests-in-agolo-a-startup-thats-fighting-information-overload-with-automated-summarizations/"}
      },
      {
        "url": "https://www.geekwire.com/2017/microsoft-ventures-doubles-ai-new-investments-agolo-bonsai/"}
      }
    ]
}

Example

Requests

{
 "summary_length_words":"150",
 "articles":[
    {
        "type":"article", 
        "text": "President Donald Trump’s threat to shut down the southern border raised fears Monday of dire economic consequences in the U.S. and an upheaval of daily life in a stretch of the country that relies on the international flow of not just goods and services but also students, families and workers. Politicians, business leaders and economists warned that such a move would block incoming shipments of fruits and vegetables, TVs, medical devices and other products and cut off people who commute to their jobs or school or come across to go shopping. \"Let’s hope the threat is nothing but a bad April Fools’ joke,\" said economist Dan Griswold at the Mercatus Center at George Mason University in Virginia. He said Trump’s threat would be the \"height of folly,\" noting that an average of 15,000 trucks and $1.6 billion in goods cross the border every day. \"If trade were interrupted, U.S. producers would suffer crippling disruptions of their supply chains, American families would see prices spike for food and cars, and U.S. exporters would be cut off from their third-largest market,\" he said. Trump brought up the possibility of closing ports of entry along the southern border Friday and revisited it in tweets over the weekend because of a surge of Central Americans migrants who are seeking asylum. Trump administration officials have said the influx is straining the immigration system to the breaking point. Elected leaders from border communities stretching from San Diego to cities across Texas warned that havoc would ensue on both sides of the international boundary if the ports were closed. They were joined by the U.S. Chamber of Commerce, which said such a step would inflict \"severe economic harm.\" In California’s Imperial Valley, across from Mexicali, Mexico, farmers rely on workers who come across every day from Mexico to harvest fields of lettuce, carrots, onions and other winter vegetables. Shopping mall parking lots in the region are filled with cars with Mexican plates. More than 60 percent of all Mexican winter produce consumed in the U.S. crosses into the country at Nogales, Arizona. The winter produce season is especially heavy right now, with the import of Mexican-grown watermelons, grapes and squash, said Lance Jungmeyer, president of the Fresh Produce Association of the Americas. He said 11,000 to 12,000 commercial trucks cross the border at Nogales daily, laden with about 50 million pounds of produce such as eggplants, tomatoes, bell peppers, lettuce, cucumbers and berries. He said a closing of the border would lead to immediate layoffs and result in shortages and price increases at grocery stores and restaurants. \"If this happens — and I certainly hope it doesn’t — I’d hate to go into a grocery store four or five days later and see what it looks like,\" Jungmeyer said. Laredo Mayor Pete Saenz, chairman of the Texas Border Coalition, said a closure would be catastrophic. \"Closing the border would cause an immediate depression in border state communities and, depending on the duration, a recession in the rest of the country,\" he said. \"Our business would end,\" said Marta Salas, an employee at an El Paso shop near the border that sells plastic flowers that are used on the Mexican side by families holding quinceañeras, the traditional coming-of-age celebrations. Salas said her whole family, including relatives who attend the University of Texas at El Paso, would be affected if the border were closed. \"There are Americans who live there. I have nephews who come to UTEP, to grade school, to high school every day,\" Salas said. Meanwhile, the Trump administration said Monday as many as 2,000 U.S. inspectors who screen cargo and vehicles at ports of entry along the Mexican border may be reassigned to help handle the surge of migrants. Currently, about 750 inspectors are being reassigned. That, too, could slow the movement of trucks and people across the border. The effects were evident Monday: Sergio Amaya, a 24-year-old American citizen who lives in Juarez, Mexico, and attends UTEP, said it normally takes him two minutes to cross the bridge. It took an hour this time. \"The Border Patrol agent said it’s going to get worse,\" Amaya said. Instead of ensuring the flow of goods across the border, the inspectors are being put to work processing migrants, taking their applications for asylum and transporting them to holding centers. Homeland Security Secretary Kirstjen Nielsen said the reassignments are necessary to help manage the huge influx that is overloading the system. \"The crisis at our border is worsening, and DHS will do everything in its power to end it,\" Nielsen said. In addition to reassigning inspectors, Nielsen has asked for volunteers from non-immigration agencies within her department and sent a letter to Congress requesting resources and broader authority to deport families faster. The administration is also ramping up efforts to return asylum seekers to Mexico. Apprehensions all along the southern border have soared in recent months, with border agents on track to make 100,000 arrests and denials of entry there in March, more than half of them families with children."
    }
  ]
}

Responses

200 OK

A successful response will be a JSON object with the following attributes:

  • title: The title of the summary, if applicable.

  • sentences: An array of summary sentences and item metadata, grouped by item. Each element is a Summary object.

Representations

{
    "title": "",
    "sentences": [
        "President Donald Trump’s threat to shut down the southern border raised fears Monday of dire economic consequences in the U. S. and an upheaval of daily life in a stretch of the country that relies on the international flow of not just goods and services but also students, families and workers.",
        "Laredo Mayor Pete Saenz, chairman of the Texas Border Coalition, said a closure would be catastrophic.",
        "\"Closing the border would cause an immediate depression in border state communities and, depending on the duration, a recession in the rest of the country,\" he said.",
        "The effects were evident Monday: Sergio Amaya, a 24-year-old American citizen who lives in Juarez, Mexico, and attends UTEP, said it normally takes him two minutes to cross the bridge.",
        "It took an hour this time."
    ]
}

Code samples

@ECHO OFF

curl -v -X POST "https://api.agolo.com/speakable-summarizer/summarization"
-H "Content-Type: application/json"
-H "Ocp-Apim-Subscription-Key: {subscription key}"

--data-ascii "{body}" 
using System;
using System.Net.Http.Headers;
using System.Text;
using System.Net.Http;
using System.Web;

namespace CSHttpClientSample
{
    static class Program
    {
        static void Main()
        {
            MakeRequest();
            Console.WriteLine("Hit ENTER to exit...");
            Console.ReadLine();
        }
        
        static async void MakeRequest()
        {
            var client = new HttpClient();
            var queryString = HttpUtility.ParseQueryString(string.Empty);

            // Request headers
            client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "{subscription key}");

            var uri = "https://api.agolo.com/speakable-summarizer/summarization?" + queryString;

            HttpResponseMessage response;

            // Request body
            byte[] byteData = Encoding.UTF8.GetBytes("{body}");

            using (var content = new ByteArrayContent(byteData))
            {
               content.Headers.ContentType = new MediaTypeHeaderValue("< your content type, i.e. application/json >");
               response = await client.PostAsync(uri, content);
            }

        }
    }
}	
// // This sample uses the Apache HTTP client from HTTP Components (http://hc.apache.org/httpcomponents-client-ga/)
import java.net.URI;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class JavaSample 
{
    public static void main(String[] args) 
    {
        HttpClient httpclient = HttpClients.createDefault();

        try
        {
            URIBuilder builder = new URIBuilder("https://api.agolo.com/speakable-summarizer/summarization");


            URI uri = builder.build();
            HttpPost request = new HttpPost(uri);
            request.setHeader("Content-Type", "application/json");
            request.setHeader("Ocp-Apim-Subscription-Key", "{subscription key}");


            // Request body
            StringEntity reqEntity = new StringEntity("{body}");
            request.setEntity(reqEntity);

            HttpResponse response = httpclient.execute(request);
            HttpEntity entity = response.getEntity();

            if (entity != null) 
            {
                System.out.println(EntityUtils.toString(entity));
            }
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
        }
    }
}

<!DOCTYPE html>
<html>
<head>
    <title>JSSample</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
</head>
<body>

<script type="text/javascript">
    $(function() {
        var params = {
            // Request parameters
        };
      
        $.ajax({
            url: "https://api.agolo.com/speakable-summarizer/summarization?" + $.param(params),
            beforeSend: function(xhrObj){
                // Request headers
                xhrObj.setRequestHeader("Content-Type","application/json");
                xhrObj.setRequestHeader("Ocp-Apim-Subscription-Key","{subscription key}");
            },
            type: "POST",
            // Request body
            data: "{body}",
        })
        .done(function(data) {
            alert("success");
        })
        .fail(function() {
            alert("error");
        });
    });
</script>
</body>
</html>
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    
    NSString* path = @"https://api.agolo.com/speakable-summarizer/summarization";
    NSArray* array = @[
                         // Request parameters
                         @"entities=true",
                      ];
    
    NSString* string = [array componentsJoinedByString:@"&"];
    path = [path stringByAppendingFormat:@"?%@", string];

    NSLog(@"%@", path);

    NSMutableURLRequest* _request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:path]];
    [_request setHTTPMethod:@"POST"];
    // Request headers
    [_request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [_request setValue:@"{subscription key}" forHTTPHeaderField:@"Ocp-Apim-Subscription-Key"];
    // Request body
    [_request setHTTPBody:[@"{body}" dataUsingEncoding:NSUTF8StringEncoding]];
    
    NSURLResponse *response = nil;
    NSError *error = nil;
    NSData* _connectionData = [NSURLConnection sendSynchronousRequest:_request returningResponse:&response error:&error];

    if (nil != error)
    {
        NSLog(@"Error: %@", error);
    }
    else
    {
        NSError* error = nil;
        NSMutableDictionary* json = nil;
        NSString* dataString = [[NSString alloc] initWithData:_connectionData encoding:NSUTF8StringEncoding];
        NSLog(@"%@", dataString);
        
        if (nil != _connectionData)
        {
            json = [NSJSONSerialization JSONObjectWithData:_connectionData options:NSJSONReadingMutableContainers error:&error];
        }
        
        if (error || !json)
        {
            NSLog(@"Could not parse loaded json with error:%@", error);
        }
        
        NSLog(@"%@", json);
        _connectionData = nil;
    }
    
    [pool drain];

    return 0;
}
<?php
// This sample uses the Apache HTTP client from HTTP Components (http://hc.apache.org/httpcomponents-client-ga/)
require_once 'HTTP/Request2.php';

$request = new Http_Request2('https://api.agolo.com/speakable-summarizer/summarization');
$url = $request->getUrl();

$headers = array(
    // Request headers
    'Content-Type' => 'application/json',
    'Ocp-Apim-Subscription-Key' => '{subscription key}',
);

$request->setHeader($headers);

$parameters = array(
    // Request parameters
);

$url->setQueryVariables($parameters);

$request->setMethod(HTTP_Request2::METHOD_POST);

// Request body
$request->setBody("{body}");

try
{
    $response = $request->send();
    echo $response->getBody();
}
catch (HttpException $ex)
{
    echo $ex;
}

?>
########### Python 2.7 #############
import httplib, urllib, base64

headers = {
    # Request headers
    'Content-Type': 'application/json',
    'Ocp-Apim-Subscription-Key': '{subscription key}',
}

params = urllib.urlencode({
})

try:
    conn = httplib.HTTPSConnection('api.agolo.com')
    conn.request("POST", "/speakable-summarizer/summarization?%s" % params, "{body}", headers)
    response = conn.getresponse()
    data = response.read()
    print(data)
    conn.close()
except Exception as e:
    print("[Errno {0}] {1}".format(e.errno, e.strerror))

####################################

########### Python 3.2 #############
import http.client, urllib.request, urllib.parse, urllib.error, base64

headers = {
    # Request headers
    'Content-Type': 'application/json',
    'Ocp-Apim-Subscription-Key': '{subscription key}',
}

params = urllib.parse.urlencode({
})

try:
    conn = http.client.HTTPSConnection('api.agolo.com')
    conn.request("POST", "/speakable-summarizer/summarization?%s" % params, "{body}", headers)
    response = conn.getresponse()
    data = response.read()
    print(data)
    conn.close()
except Exception as e:
    print("[Errno {0}] {1}".format(e.errno, e.strerror))

####################################
require 'net/http'

uri = URI('https://api.agolo.com/speakable-summarizer/summarization')

request = Net::HTTP::Post.new(uri.request_uri)
# Request headers
request['Content-Type'] = 'application/json'
# Request headers
request['Ocp-Apim-Subscription-Key'] = '{subscription key}'
# Request body
request.body = "{body}"

response = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
    http.request(request)
end

puts response.body