RWebData: A High-Level Interface to the Programmable Web

The rise of the programmable web offers new opportunities for the empirically driven social sciences. The access, compilation and preparation of data from the programmable web for statistical analysis can, however, involve substantial up-front costs for the practical researcher. The R-package RWebData provides a high-level framework that allows data to be easily collected from the programmable web in a format that can directly be used for statistical analysis in R (R Core Team 2013) without bothering about the data's initial format and nesting structure. It was developed specifically for users who have no experience with web technologies and merely use R as a statistical software. The core idea and methodological contribution of the package are the disentangling of parsing web data and mapping them with a generic algorithm (independent of the initial data structure) to a flat table-like representation. This paper provides an overview of the high-level functions for R-users, explains the basic architecture of the package, and illustrates the implemented data mapping algorithm.


Introduction
Digital data from the Internet has in many ways become part of our daily lives.Broadband facilities, the separation of data and design, as well as a broader adaption of certain web technology standards increasingly facilitate the integration of data across different software applications and hardware devices over the web.The Internet is increasingly becoming a programmable web 1 , where data is published not only in HTML-based websites for human readers, but also in standardized machine-readable formats to be "shared and reused across application, enterprise, and community boundaries" (W3C 2013).The technical ecology of this programmable web consists essentially of web servers providing data in formats such as Extensible Markup Language (XML) via Application Programming Interfaces (APIs) 2 1 I use the term programmable web synonymously for "Semantic Web" or "Web of Data" and as conceptually motivated by Swartz (2013).
2 Web APIs are a collection of predefined HTTP requests and response messages to facilitate the programmatic exchange of data between a web server and clients.arXiv:1603.00293v1[stat.CO] 1 Mar 2016 to other server-or client-side applications (see, e.g., Nolan and Temple Lang 2014 for a detailed introduction to web technologies for R-programmers).In the conceptual framework of this paper, APIs serve a dual function: they are the central nodes between different web applications and, at the same time, the central access points for researchers when they want to systematically collect and analyze data from the programmable web.More and more of these access points are becoming available every day.Moreover, this trend is likely to continue with the increasing number of people who have devices to access the Internet and the increasing amount of data recorded by embedded systems (i.e., sensors and applications in devices such as portable music players or cars that automatically feed data to web services). 3he rise of the programmable web offers various new opportunities for data-driven sciences.
First, for the social sciences, the programmable web provides big data covering every-day human activities and interrelationships as people leave digital traces by using mobile devices and applications based on APIs.The systematic analysis of such data is likely to offer new insights in fields as diverse as economics, political science, and sociology (see Matter and Stutzer 2015a for a review of the arguments in the case of political economics and political science, as well as, e.g., Dodds et al. 2011;DiGrazia et al. 2013;Preis et al. 2013;Barberá 2015;Matter and Stutzer 2015b for primary research based on data collected via web APIs).
In fact, web APIs might become an important domain of data sources for the evolving field of computational social science (see, e.g., Lazer et al. 2009;Cioffi-Revilla 2010;Conte et al. 2012;Giles 2012).Second, researchers from all fields of science can provide their own prepared data via APIs as a resource to facilitate research, and the consequent aggregation of data sets from diverse disciplines offers new opportunities to create new 'scientific data mash-ups' (Bell 2009) and drive innovation.The provision and hosting of APIs by research institutes and scientists for other scientists is already common practice in the life sciences (see, e.g., the API to the NCBI Gene Expression Omnibus data repository, NCBI 2014).Third, the use of standardized protocols and data formats to exchange data over the web via APIs offers, in general, new approaches to facilitate reproducibility and replicability of research.
While the advantages of accessing the programmable web and integrating it into research projects are very promising, the practical utilization of this technology comes at a cost and demands that researchers possess a specific skill set and a certain knowledge of web technologies.The new R-package RWebData substantially reduces these costs by providing several high-level functions that facilitate the exploration and systematic collection of data from APIs based on a Representational State Transfer (REST) architecture 4 .Moreover, the package contains a unified framework to summarize, visualize, and convert nested/tree-structured web data that works independently of the data's initial format (XML/RSS, JSON, YAML) as well as a framework to easily create R packages as client libraries for any REST API.The package is aimed at empirical researchers using R as their daily data analysis-and statistics tool, but who do not have a background in computer science or data science.In addition, several lower level functions of RWebData might also be useful for more advanced R-programmers who whish

Motivation
How to extract data from the programmable web in a format suitable for statistical analysis?
Particularly social scientists are often confronted with APIs whose initial purpose is not to provide data for scientific research in order to make the researchers' lives easier, but to facilitate the integration of the data in dynamic websites and smartphone applications. 5In such a context, API server and API client share the problem domain, but do not share the same goal.This makes it per se harder to write an API client in order to compile data from the web API (see Richardson and Amundsen 2013 for a discussion of this issue).The API query methods might, for example, not provide the length and breadth of data that the researcher is looking for using a single query, but only with a combination of several query methods.Importantly, the returned data are -due to the initial purpose of most APIsusually not in a format that can be directly integrated in a statistical analysis.Researchers trying to compile data from such an API are thus confronted with two main challenges: 1.The need to query and combine data from different API methods which is likely to involve many requests to the API and demands a basic knowledge of how to interact with an API from within the R-environment.
2. The extraction and conversion of the data records from a nested web data format such as XML, JSON, or YAML to a table-like representation that can be directly used for statistical analyses.
An additional challenge is to overcome the two issues above in a way that supports the reproducibility and replicability of research based on API data (including the pre-processing of raw data).As pointed out by Matter and Stutzer (2015a), this is an increasingly important issue in the context of social science research which needs to be resolved, as the new digital data sources hinder the replicability of research owing to the present 'unique purpose' of the new data sets.

Interacting with REST web APIs
In order to visit a certain website, we normally type a website's address in a web browser's address bar.The browser (a type of web client) then sends a message to the web server behind that address, requesting a copy of the website and then parses and renders the returned website (usually a HTML document) in the browser window.In REST terminology, the website's address is an URL and the website which the URL locates is a resource.The document that the server sends in response to the client's request is a representation of that resource.
Importantly, every URL points only to one resource and every resource should have only one URL (this is one of the REST principles and is referred to as addressability).The message that the browser sends to the web server is a HTTP GET request, a HTTP method that essentially requests a representation of a given resource.
REST web APIs work basically the same way as the website outlined above.The crucial difference is, that their design is intended for programmable clients (rather than humans using a web browser) and that they therefore consist of URLs pointing to resources that are not optimized for graphical rendering, but which instead contain the raw data (often in a format such as XML or JSON that facilitates the integration of the data in a HTML document).
Interacting with a REST API from within the R-environment, therefore, means, sending HTTP requests to a web server and handling the server's response with R. In addition to the basic functionality necessary for this, which are delivered in the base-package (R Core Team 2013), more detailed functions for HTTP requests are provided in packages such as RCurl (Lang 2013a) and httr (Wickham 2014a).RWebData builds on the libcurl-based RCurl package which is designed to interact with web servers hosting a REST API.The implementation is focused on a robust download of resources that checks the received HTTP response for potential problems (e.g., unexpected binary content of the HTTP responses' body-entity) to make sure that the user does not have to specify anything other than the URL.

Web data conversion
Most functions related to the fitting and testing of statistical models as well as to exploratory data analysis and data visualization in the R computing environment work on data represented in data-frames (a table-like flat representation in which each row represents a datarecord/observation and each column a variable describing these records). 6Data-frames are probably the most common R-objects used by researchers when conducting an empirical analysis with R.Many input/output-functionalities in R serve to import (export) data into (from) R as data-frames. 7However, when it comes to reading data from web APIs into R, this is not necessarily the case.The reason lies in the nature of web data formats which allow for more flexibility than solely a table-like data representation and come (in the context of web APIs) typically in a nested structure.While a conversion from one table in, e.g., a XML-document to a data-frame is straightforward (see, i.e., xmlToDataFrame() in Temple Lang 2013b), a conversion of a more complex XML-document with a nested data structure to a flat table-like data representation in R or any other computing environment is ex ante less clear and depends on the nature of the data and the purpose the data is converted for. 8This is particularly the case for data provided by a non-scientific API that is explicitly made for web developers in order to integrate the data in dynamic websites or mobile applications and not for researchers to integrate the data in their analysis.Not surprisingly, there are different solutions offered in the R-environment to map web data formats such as JSON and XML to R-objects. 9Most 6 Technically, a data-frame can contain other r-objects than just scalars (i.e., another data-frame).However, in the vast majority of applications in the context of statistical analysis and data visualization, data-frames are used for a table-like flat data representation.
7 See, i.e., data from CSV-and similar text files: read.table() in R Core Team (2013) or similar functions in Wickham and Francois (2015), Microsoft Excel files: read.xls() in Warnes et al. (2014), data from other statistical computing environments such as Stata: read.dta() in R Core Team (2014), or data from ODBCdata bases sqlQuery() in Ripley and Lapsley (2013).
8 See, e.g., the classical problem of mapping a set of XML-documents to a relational data base scheme (RDBS; i.e., a set of linked tables) with or without knowing the scheme behind the XML-documents (Moh et al. 2000;Men-hin and Fu 2001).See also, in the R context, the different implementations of mapping JSON to R-objects in Couture-Beil (2013), Lang (2013b), or Ooms et al. (2014) as well as a detailed discussion of this matter in Ooms (2014).
9 See, e.g., the CRAN Task View on web technologies and services (http://cran.r-project.org/web/views/WebTechnologies.html)for an overview of popular R-packages that parse data from the web and map it to R-objects.Several contributions in this area also rather focus on the automated information extraction from traditional websites made for human interaction.Such methods are commonly summarized under the packages represent web data as nested lists containing objects of different classes such as atomic vectors or data-frames.After converting the original web data to R-objects, the user, therefore, often has to extract and rearrange the data records of interest in order to obtain a data representation for statistical analysis.This process becomes even more complex, as queries to the same API method might provide slightly different results depending on the amount of detail embedded in the data records.In these cases, data extraction can become particularly costly if the data set that needs to be compiled depends on many API requests involving various API methods.

Data mapping strategy and basic architecture
Web data provided via REST APIs are typically in a format such as XML, JSON, or YAML and are not structured in tables containing data values in rows and columns, but are rather organized in a nested (tree-like) structure.However, independent of the data format and data structure, documents provided by a particular REST API have basic aspects in common.Based on these commonalities, this section presents a conceptual and terminological framework as well as a description of how this framework is used to develop the data mapping strategy applied in RWebData and serves as the foundation of the data mapping algorithm which will be outlined later on.

Original data structure and data semantics
From the researcher's or statistician's point of view, the data sets provided by web APIs obey, independent of the raw data format and nesting structure, some very basic data semantics.For these data semantics, I use mainly the same terminology that is nicely outlined by Wickham terms "web scraping" or "screen scraping".See, e.g., the R-package rvest (Wickham 2015) for functions that facilitate web scraping as well as Munzert et al. (2014) for a practical introduction to web scraping with R.
In addition, each observation and each variable belongs to a specific observation type.Thus, in a multi-dimensional data set describing, for example, a city, observation types could be buildings or citizens.The following fictional XML example further illustrates this point.The XML document contains a data set describing a firm.The variables "firstName" and "secondName" describe observations of type "employee", while observations of type "shareholder" are described by the variables "ID" and "Name".Finally, the variables "firmName" and "firmID" describe the firm itself, which builds another type of observation.The following subsection illustrates how the data would be mapped according to the procedure implemented in RWebData.

Mapping nested web data to data-frames
The core idea behind the data mapping procedure in RWebData is built around the basic se-mantics outlined above.According to this system, documents returned from APIs can contain data describing observational units of one type or several different types.RWebData returns one data-frame for each observation type.Observations and variables belonging to different types are, thus, collected in different data-frames, each describing one type of observational unit.Some observations might describe the document (or main type of observational unit) itself (i.e., metadata).These are collected in a separate data-frame.Tables 1 (a-c) present the XML-document from the example above after mapping to data-frames according to the outlined mapping procedure.The next subsection explains how this process is implemented in RWebData.Table 1: The same data as in the XML code example above, but mapped to data-frames according to the generic RWebData mapping procedure.While (a) contains data describing the firm (the main observational unit) itself, (b) and (c) contain the observations and variables describing the observation types employee and shareholder, respectively.

Parsing and generic mapping of different web data formats
In order to map nested web data to data-frames, RWebData applies, in a first step, existing parsers for different formats (mime-types) of the data in the body of the HTTP response from the API to read the data into R.10 Independent of the initial format, the data is parsed and coerced to a (nested) list representing the tree-structure of the raw data.In a next step, the data is mapped to one or several data-frames depending on the nesting structure and the recurrence of observation types and variables.Appendix A.I presents a detailed description of the mapping algorithm.The data-frames are returned to the user either directly (in a list) or as part of an apiresponse-object.
The core idea behind the generic approach to web data conversion in the RWebData package is thus to disentangle the parsing of web data from the mapping of the data to data-frames.This allows the parsers for different web data formats to be relatively simple, while the same mapping algorithm is focused on the data semantics and can be applied independent of the initial raw data format.In addition, it allows different parsers' advantages to be combined in order to make the parsing process more robust.The suggested procedure goes hand in hand with the object-oriented approach applied in RWebData and provides summary and plot methods that work independent of the initial data format.The modular design of mapping web data to data-frames facilitates the extension of RWebData's compatibility with additional web data formats or alternative parsers that are, for example, optimized for vast web documents.Parsers simply need to read the web data as (nested) lists or in a format that conserves the tree-structure of the raw web data and can be easily coerced to a nested list.

Basic data mapping algorithm
Once the web data-document is downloaded from an API and coerced to a nested list, the algorithm consists essentially of two procedures: 1.The extraction of different observation types (and their respective observations and variables) as sub-trees.While reversely traversing the whole data-tree, the algorithm checks at each level (node) of the tree whether either the whole current sub-tree or one of its siblings can be considered an observation type.If so, the respective sub-tree is extracted and saved in a deposit variable.If not, the algorithm traverses further down in the tree-structure.Checks for observation types are defined as a set of control statements that incorporate the above outlined data semantics.Essentially, the recurrence of the same variables as siblings (containing the actual data values as leaf elements) is decisive in order to recognize observation types.The result of this step is a set of sub-trees, each sub-tree containing one observation type and its respective observations and variables.
2. For each of the resulting observation types (in the form of sub-trees), the respective observations are extracted as character vectors and bound as rows in a data-frame, while the variable names are conserved and added as column names.This procedure is built to be robust to observations described by a differing number of variables.The result of this step is a set of data-frames, each describing one observation type and containing individual observations as rows and variables as columns.
Singly occurring leaf nodes that are not nested within one of the detected observation types are collected along the way and then returned in one data-frame.According to the logic of the data semantics and the algorithm outlined above, these remaining data can be seen as metadata describing the data set as a whole.Appendix A.I presents a detailed, more technical outline of the data mapping algorithm.

Basic architecture
RWebData is specifically written to give practical researchers a high-level interface to compile data from the programmable web.The common user will thus normally not be confronted with the range of internal processes outlined above.The work-flow with RWebData for an average user thus mainly involves the specification of what data should be requested from what API (in the form of either a list, a data-frame or simply a string with a URL) to one of RWebData's high-level functions in order to obtain the desired data mapped to data-frames.Figure 1 illustrates the basic architecture of RWebData, summarizing its internal functionality and the processing procedure when the package is used by an average user.RWebData's high level functions take either lists, data frames, or a URL (as character string) as input values and return a list of data-frames or an apidata-object.First, RWebData generates an apirequest-object based on which the HTTP GET and responses are handled.Upon successful interaction with the API, an apiresponse-object, containing, inter alia, the raw web data, is generated.Subject to consideration of the mime-type of the raw data, the data is then preprocessed, parsed, and coerced to a nested list.Finally, the data mapping algorithm is applied in order to extract the data in the form of data frames as outlined in the previous section.The latter builds the main part of the package.The procedure is straight-forward and user-friendly in practice.

Basic functionality
In order to describe the basic usage of RWebData, this section offers a step-by-step introduction to the high-level functionality of the package.Some of the functions described here offer more options which are not all discussed in this section.Details on all these options are provided by the respective R help files.Users are generally encouraged to read the detailed documentation of RWebData on GitHub (https://github.com/GivenTheData/RWebData).
RWebData's implementation is motivated by the convention over configuration paradigm and thus provides a way for the user to interact with APIs using as few specifications as necessary to access the data.RWebData then converts data in the most common formats provided by APIs to one data-frame or a list of several data-frames.Hence, the user does not need to specify any HTTP options or understand what XML or JSON is and is able to obtain the data directly in the expected format for statistical analysis.There are primarily two high-level functions in RWebData that provide this functionality in different ways: getTabularData() and apiData().

Fetching data from REST APIs
The function getTabularData() provides a straightforward way to get data from web APIs as data-frames.In the simplest case, the function takes a string containing the URL to the respective API resource as an input. 11The function then handles the HTTP request and response, parses the body of the response (depending on the mime-type) and automatically extracts the data records from the nested data structure as data-frames.This enables us to fetch data from different APIs providing data in different formats with essentially the same command.
Consider, for example, the World Bank Indicators API which provides time series data on financial indicators of different countries. 12We want to use data from that API to investigate how the United States' public dept was affected by the financial crisis in 2008.All we need in order to download and extract the data is the URL to the respective resource on the API. 13 R> u <-paste0("http://api.worldbank.org/countries/USA/indicators",# address + "/DP.DOD.DECN.CR.GG.CD?", # query method + "&date=2005Q1:2013Q4") # parameters R> usdept <-getTabularData(u) Without bothering about the initial format 14 , the returned data is already in the form of a data-frame and is ready to be analyzed (e.g., by plotting the time series as presented in  The same approach of fetching data with getTabularData() can be applied to any other REST API that provides data in either XML/RSS, JSON, or YAML.Instead of a URL, 14 The World Bank Indicators API provides time series data by default as XML in a compressed text file.Handling solely one API query of this type might already involve many steps to fetch and extract the data with the existing lower level functions.And, thus, might be tedious for a user who only has limited experience with web technologies.
one can also use a list of request parameters plus the base URL that directs to the API's server as function arguments.We use this approach in order to download data from the HarvardEvents API (https://manual.cs50.net/api/events/),which provides data about current or past events at Harvard University.Data on events can be fetched in various formats.
In the following example, we query the API for upcoming lectures at Harvard and request a different data format each time (note the different format in the output parameter).
While the data format in the examples above varies, the underlying data structure is relatively simple in all these examples.The World Bank Indicators API is specifically devised to provide data for statistical analysis.The HarvardEvents API, although primarily designed for developers, provides data that can be naturally represented in one table (with the exception of responses in RSS format).The next section considers examples where the provided data cannot easily be thought of as one single table.

Nested data structures
The high-level function getTabularData() automatically handles nested data and converts them to a list of various data-frames.It does not, however, provide any information on the initial nesting structure and can only handle individual requests.Alternatively, we can use apiData() in order to exploit RWebData's internal classes and methods to handle requests to APIs.The simplest way to call apiData() is again by using a URL (as a string) pointing to an API resource.apiData() returns an object of class apiresponse.Such apiresponse objects contain additional information about the executed request to the API and support generic plot and summary functions illustrating the structure and content of the retrieved web document.The following example demonstrates the summary methods for apiresponse objects with data from the Ergast API (http://ergast.com/mrd/)on Formula 1 race results.The summary method called by the generic summary(), provides an overview of the variables included in the data and shows how RWebData has split the data into several data-frames.This is particularly helpful in an early phase of a research project when exploring an API for the first time.

R>
The next example demonstrates the visualization of nested data returned from the Open States API 16 .We query data on a legislator in the Council of the District of Columbia with apiData() and call the generic plot() on the returned apiresponse object.Figure 3 shows the result of the plot command below.Note that the Open States API is free to use for registered users.Upon registration a api-key is issued that is then added as a parametervalue to each API request (indicated with "[YOUR-API-KEY]" in the example below).

R> p <-apiData(url)
R> plot(p, type="jitter") The apiresponse plot method illustrates the nesting structure of the original data by drawing entities (variables or types) as nodes and nesting relationships as edges in a Reingold-Tilford tree-graph (Reingold and Tilford 1981; see also Csardi and Nepusz 2006 for the implementation in R on which RWebData relies.).The option type="jitter" shifts the nodes slightly vertically to make long node names better readable in the graph.
The transformed data (in the form of a list of data-frames) saved in an apiresponse-object can be accessed with getdata().In the current example, the data has been split into two data-frames: one with metadata containing general variables describing the legislator, and one containing data on the legislator's roles in the 2011-2012 session.

Interactive sessions
So far, we have only considered individual requests to APIs.In practice, users might want to query an API in many ways in an interactive session to explore the data and assemble the data set that meets their needs.This can easily be done with RWebData.We continue with the Open States API example.First, we fetch general data on all legislators in the DC Council.
R> url <-"http://openstates.org/api/v1/legislators/?state=dc&chamber=upper The goal is to combine these general data with data on the legislators' roles.In particular, we want to download the detailed role data on all legislators and combine these within one data set.As there is no API method provided to obtain these data with one call to the API, we use apiDownload() to handle all individual requests at once.By inspecting the dc_council data-frame from above, we see that the fifth column of that data-frame contains all the IDs (id) pointing to the respective resources on individual council members.We simply paste these ids with the legislators-method and use the resulting URLs as the function argument to apiDownload() in order to obtain all the data compiled in one data-frame.

Writing interfaces to REST APIs
In the context of an ongoing research project, it might be more comfortable to have a specific function for specific queries to the same API.We could manually program such a function based on RWebData's internal functions or using the functions of other packages.However, RWebData provides a way to write such functions automatically.Given the parameters and the base URL for the respective API method/resource, generateQueryFunction() writes a function that includes all the functionality of the package to handle queries to that specific API method/resource.The new functions bitstipTrip() and bitstipSeek() can now be used to query the Bit-sTip.comAPI.

Discussion
Empirically driven social sciences can substantially profit from the rapidly growing programmable web as a data source covering countless dimensions of social activity.However, the purpose and goals that drove the initial development of web APIs focused on providing general data for public use via dynamic websites and other applications, and not on the provision of data formatted for scientific research and statistical analyses.This leads to technical hurdles a researcher has to overcome in order to compile such data in a format that is suitable for statistical analysis.The presented R package RWebData offers a simple high-level interface that helps to overcome such technical hurdles (and the respective costs) associated with the statistical analysis of data from the programmable web.The package facilitates a frictionless and well documented raw data compilation and data preparation process that substantially increases the replicability and reproducibility of original research based on data from the programmable web.As pointed out by Matter and Stutzer (2015a), empirical research based on newly available big public data from web data sources is a challenge demanding scientific rigor, as the repository of 'unique' data sets rapaciously grows.The need for data precision is even greater in the age of big data: Concision must be an essential characteristic of data recording and retrieval with regard to parsing and compilation.Data identification and presentation need to be restricted to minimum informational cues.Rigor applies not only to the final prepared data used in the analysis, but also to the documentation of the data preparation and data selection process.With RWebData, an R-script documenting how the package's high-level functions have been applied to compile data as well as any further step in the data preparation and analysis are enough to ensure the replicability of a study based on big public data from the programmable web.

Length
to develop client applications to interact with REST APIs.The package thus bridges the gap between the fundamental and very valuable R-packages that integrate several web technologies into the R-environment (see, e.g., Temple Lang 2013b,a; Couture-Beil 2013; Ooms et al. 2014) and the statistical analysis of the programmable web universe.The development and use of RWebData is motivated in Section 2, which explains the challenges of extracting data from the programmable web for statistical analysis and introduces the packages that enable R-users to work with web technologies.Section 3 presents the central data mapping strategy and algorithm developed in RWebData as well as an overview of the package's basic architecture.Section 4 illustrates the high-level functionality of RWebData for a typical user.In Section 5, more advanced examples show how RWebData can be used to write Open Source Interfaces/API client libraries.The concluding discussion in Section 6 reviews the potential of RWebData for the empirically driven social sciences in terms of big public data access as well as the reproducibility and replicability of research based on data from web APIs.RWebData is free, open source (under GLP-2 and GLP-3 license), and published on Bitbucket (https://bitbucket.org/ulrich-matter/rwebdata).It can directly be installed from the R-console (using the devtools-package; Wickham and Chang 2015) with the command install_bitbucket('ulrich-matter/RWebData').This paper describes version 0.1 of RWebData, which requires R version 3.0.2or a subsequent version.
(2014b, p. 3): 1. "A dataset is a collection of values, usually either numbers (if quantitative) or strings (if qualitative)."2. "Every value belongs to a variable and an observation."3. "A variable contains all values that measure the same underlying attribute (like height, temperature, duration) across units."4. "An observation contains all values measured on the same unit (like a person, or a day, or a race) across attributes."

Figure 1 :
Figure 1: Basic architecture of the RWebData package.

Figure 2 :
Figure 2: Plot of the time series on United States public dept extracted from the World Bank Indicators API

Figure 3 :
Figure 3: Reingold-Tilford tree-graph illustrating the nested structure of the raw JSON data from the Open States API.
The same works for APIs that accept requests via form URLs, such as the BisTip.comSearch API.Here, only the base URL and the respective parameters have to be specified.