- SWBAT read NYC Open Data developer documentation to construct an API call
- SWBAT read NYC Open Data developer documentation to interpret an API response
- SWBAT request data from NYC Open Data
- SWBAT integrate a NYC Open Data API data into a React component
- NYC Open Data APIs
- Getting an App Token
- Using Our App Token
- Filtering Data from Socrata
- More Complex Filtering
- Getting NYC Open Data into React
- Keeping Our App Token Safe
- Close
If you haven't yet read through the React APIs mini-unit, please do that before beginning this mini-unit.
Watch this video walk-through to see how NYC Open Data APIs are used with React.
New York City provides free access to numerous data resources on the NYC Open Data website. There you can search for datasets of city-related data, including 311 calls, restaurant inspection results, geographic datasets, and much much more.
Because NYC Open Data is coming from a variety of city departments, there's some variability in the quality, utility, and completeness of the data.
The best way to learn how to use the data at NYC Open Data is to dive in, find the API developer documentation, and begin to get some data.
Let's say we're interested in NYC Film Permits, and we find the dataset below:
Clicking on the title leads to a page with more information about the dataset.
There we can see how many rows are in the dataset (62.6K), how many columns it has (14), how often it's updated (daily), how many people have downloaded it (over 8,100), etc.
At this point, if we weren't sure whether this dataset is useful to us, we could click on the "View Data" button where we can begin to get a sense of what data is in the Film Permits dataset. There, you can view the data in a big table (like in Excel or Google Sheets) or one record at a time:
The dataset has over 62,600 records, and that many records is too cumbersome to load into our app directly! We'll need to use an API.
To get to the API version of the dataset: from the information page, we can click on the "API" button (a few over from the "View Data" button). That will show a modal window with information about the Socrata Open Data API (SODA), including links to the API documentation, the Socrata portal homepage, and the raw API data, e.g. https://data.cityofnewyork.us/resource/tg4x-b46p.json.
Although it may seem like we're good to go now that we know the endpoint for the dataset (the JSON file linked above), Socrata puts a limit on how many times we can access that data without an Application Token. That means we need to register an Application Token (and also create an Account on the Open Data Portal):
-
Sign up for an Open Data Account
-
If you're not directed to the Developer Settings, click "edit profile" and then click "Developer Settings". This link may also get you there.
-
Tap the "Create New App Token" button, fill in the required information about the app/dataset you're using, and then tap "Save".

Note: you get a public and a private App Token - keep the secret token secure and don't share it with others (or in a github repository). Although we won't be using it here, there are other APIs for which you may need to use the secret token to access data.
Now that we have an App Token, we can start to make requests of the API!
According to the Socrata documentation, we can append the variable $$app_token to the endpoint along with our App Token in order to make the request:
https://data.cityofnewyork.us/resource/tg4x-b46p.json?$$app_token=TNxXJT9OVmO6FDIhzqXYaEKJ[{
"eventid": "507027",
"eventtype": "Shooting Permit",
"startdatetime": "2019-09-06T06:00:00.000",
"enddatetime": "2019-09-06T22:00:00.000",
"enteredon": "2019-09-05T14:02:05.000",
"eventagency": "Mayor's Office of Film, Theatre & Broadcasting",
"parkingheld": "PROVOST STREET between FREEMAN STREET and GREEN STREET, PROVOST STREET between GREEN STREET and HURON STREET, PROVOST STREET between GREEN STREET and FREEMAN STREET",
"borough": "Brooklyn",
"communityboard_s": "1",
"policeprecinct_s": "94",
"category": "Television",
"subcategoryname": "Cable-episodic",
"country": "United States of America",
"zipcode_s": "11222"
},
{
"eventid": "506980",
"eventtype": "Shooting Permit",
"startdatetime": "2019-09-06T10:00:00.000",
"enddatetime": "2019-09-07T04:00:00.000",
"enteredon": "2019-09-05T10:38:20.000",
"eventagency": "Mayor's Office of Film, Theatre & Broadcasting",
"parkingheld": "KINGSLAND AVENUE between GREENPOINT AVENUE and NORMAN AVENUE, MONITOR STREET between GREENPOINT AVENUE and NORMAN AVENUE",
"borough": "Brooklyn",
"communityboard_s": "1",
"policeprecinct_s": "114, 94",
"category": "Television",
"subcategoryname": "Episodic series",
"country": "United States of America",
"zipcode_s": "11105, 11222"
},
{
"eventid": "506958",
"eventtype": "Shooting Permit",
"startdatetime": "2019-09-06T07:00:00.000",
"enddatetime": "2019-09-06T21:00:00.000",
"enteredon": "2019-09-05T09:39:17.000",
"eventagency": "Mayor's Office of Film, Theatre & Broadcasting",
"parkingheld": "DIAMOND STREET between MESEROLE AVENUE and CALYER STREET, JEWEL STREET between MESEROLE AVENUE and CALYER STREET, CALYER STREET between DIAMOND STREET and JEWEL STREET, MESEROLE AVENUE between DIAMOND STREET and JEWEL STREET",
"borough": "Brooklyn",
"communityboard_s": "1",
"policeprecinct_s": "94",
"category": "Television",
"subcategoryname": "Episodic series",
"country": "United States of America",
"zipcode_s": "11222"
},
...
]Try using your App Token with the endpoint above to get the raw data.
Note: I've altered the App Token above so you will receive a permissions error if you try to use the token shown. You will know your App Token works because you will get data back from the URL.
Socrata includes a simple way to filter data in API requests: by using column names as parameters.
The NYC Film Permit data has 14 columns, one of which indicates the borough in which filming will take place:
// 14 fields for each entry in dataset
"eventid"
"eventtype"
"startdatetime"
"enddatetime"
"enteredon"
"eventagency"
"parkingheld"
"borough"
"communityboard_s"
"policeprecinct_s"
"category"
"subcategoryname"
"country"
"zipcode_s"To use the borough parameter to filter to only the permits granted in Manhattan, we can append &borough=Manhattan at the end of our request URL (which already includes our App Token):
https://data.cityofnewyork.us/resource/tg4x-b46p.json?$$app_token=TNxXJT9OVmO6FDIhzqXYaEKJ&borough=Manhattan[{
"eventid": "506313",
"eventtype": "Shooting Permit",
"startdatetime": "2019-09-06T06:00:00.000",
"enddatetime": "2019-09-06T21:00:00.000",
"enteredon": "2019-08-30T15:02:36.000",
"eventagency": "Mayor's Office of Film, Theatre & Broadcasting",
"parkingheld": "RIVERSIDE DRIVE between WEST 75 STREET and WEST 74 STREET, RIVERSIDE DRIVE between WEST 75 STREET and WEST 76 STREET",
"borough": "Manhattan",
"communityboard_s": "7",
"policeprecinct_s": "20",
"category": "Film",
"subcategoryname": "Short",
"country": "United States of America",
"zipcode_s": "10023"
},
{
"eventid": "505834",
"eventtype": "Theater Load in and Load Outs",
"startdatetime": "2019-09-06T06:00:00.000",
"enddatetime": "2019-09-07T23:45:00.000",
"enteredon": "2019-08-28T11:05:52.000",
"eventagency": "Mayor's Office of Film, Theatre & Broadcasting",
"parkingheld": "WEST 43 STREET between BROADWAY and 6 AVENUE",
"borough": "Manhattan",
"communityboard_s": "5",
"policeprecinct_s": "14",
"category": "Theater",
"subcategoryname": "Theater",
"country": "United States of America",
"zipcode_s": "10036"
},
{
"eventid": "506218",
"eventtype": "Shooting Permit",
"startdatetime": "2019-09-06T09:00:00.000",
"enddatetime": "2019-09-06T23:00:00.000",
"enteredon": "2019-08-30T09:12:25.000",
"eventagency": "Mayor's Office of Film, Theatre & Broadcasting",
"parkingheld": "5 AVENUE between EAST 26 STREET and WEST 25 STREET, WEST 25 STREET between BROADWAY and 5 AVENUE, BROADWAY between WEST 26 STREET and WEST 25 STREET, WEST 27 STREET between BROADWAY and 6 AVENUE",
"borough": "Manhattan",
"communityboard_s": "5",
"policeprecinct_s": "13",
"category": "WEB",
"subcategoryname": "Not Applicable",
"country": "United States of America",
"zipcode_s": "10001, 10010"
},
...
]Try using your App Token with this endpoint and parameter/variable to get filtered raw data.
What if you wanted to get all of the Film Permits except for the ones in Manhattan?
Socrata has more complex filtering capabilities using SoQL clauses. We might construct the query above using the $where parameter, but in this case the variable is an inequality that indicates how to filter the data, e.g. `$where=(borough!="Manhattan").
https://data.cityofnewyork.us/resource/tg4x-b46p.json?$$app_token=TNxXJT9OVmO6FDIhzqXYaEKJ&$where=(borough!=%22Manhattan%22)Note: the parentheses are not necessary, however they're included for readibility. Note:
%22is the HTML character code for".
[{
"eventid": "186438",
"eventtype": "Shooting Permit",
"startdatetime": "2014-10-30T07:00:00.000",
"enddatetime": "2014-10-31T02:00:00.000",
"enteredon": "2014-10-27T12:14:15.000",
"eventagency": "Mayor's Office of Film, Theatre & Broadcasting",
"parkingheld": "LAUREL HILL BLVD between REVIEW AVENUE and RUST ST, REVIEW AVE between VAN DAM STREET and LAUREL HILL BOULEVARD, 59 ROAD between 60 LANE and 61 STREET, 59 ROAD between 60 LANE and 61 STREET, 61 STREET between 59 ROAD and FRESH POND ROAD, FRESH POND ROAD between 59 AVENUE and 59 DRIVE, 59 DRIVE between FRESH POND ROAD and 63 STREET, 59 DRIVE between FRESH POND ROAD and 64 STREET",
"borough": "Queens",
"communityboard_s": "2, 5",
"policeprecinct_s": "104, 108",
"category": "Television",
"subcategoryname": "Episodic series",
"country": "United States of America",
"zipcode_s": "11378"
},
{
"eventid": "445255",
"eventtype": "Shooting Permit",
"startdatetime": "2018-10-20T07:00:00.000",
"enddatetime": "2018-10-20T18:00:00.000",
"enteredon": "2018-10-09T21:34:58.000",
"eventagency": "Mayor's Office of Film, Theatre & Broadcasting",
"parkingheld": "JORALEMON STREET between BOERUM PLACE and COURT STREET",
"borough": "Brooklyn",
"communityboard_s": "2",
"policeprecinct_s": "84",
"category": "Still Photography",
"subcategoryname": "Not Applicable",
"country": "United States of America",
"zipcode_s": "11201"
},
{
"eventid": "43547",
"eventtype": "Shooting Permit",
"startdatetime": "2012-01-10T07:00:00.000",
"enddatetime": "2012-01-10T19:00:00.000",
"enteredon": "2012-01-04T12:25:37.000",
"eventagency": "Mayor's Office of Film, Theatre & Broadcasting",
"parkingheld": "EAGLE STREET between FRANKLIN STREET and WEST STREET, WEST STREET between EAGLE STREET and FREEMAN STREET, FREEMAN STREET between WEST STREET and FRANKLIN STREET",
"borough": "Brooklyn",
"communityboard_s": "1, 2",
"policeprecinct_s": "108, 94",
"category": "Television",
"subcategoryname": "Episodic series",
"country": "United States of America",
"zipcode_s": "11101, 11222"
},
...
]Pulling together our React component and our NYC Open Data (Socrata) API request, we end up with a React component that's requesting data from Socrata:
import React from 'react';
// any other import statements
class Item extends React.Component {
constructor(props) {
super(props);
this.state = {
// define state variables here
}
}
componentDidMount = () => {
let appToken = 'TNxXJT9OVmO6FDIhzqXYaEKJ'; // see below to secure your App Token
fetch('https://data.cityofnewyork.us/resource/tg4x-b46p.json?$$app_token='+appToken+'&borough=Manhattan')
.then(response => response.json()) // convert response to JSON
.then(data => {
// code to execute once data is defined
})
.catch(e => {
alert(e);
})
}
render() {
return (
// render component HTML here
);
}
}
export default Item;At this point, it's worth re-recognizing that the API's response, the variable response above, is an array of objects. We already know how to use .map() and other JavaScript functions on an array of objects to manipulate and return HTML in a React component! Yay!
Although the Socrata App Token is generally ok to send "in the clear" (without encrypting it or hiding it) when making an API request, there are some credentials that you'll want to keep safe from prying eyes. For those, you'll want to create a special file to store environment variables. This file is called .env, and in React there are a few things to note when creating and using an .env file:
- All React environment variables must start with
REACT_APP_in order to be recognized by the App: e.g.REACT_APP_SOCRATA_TOKEN. - The variable is stored in
.envalong with its value, but the .env file is part of your.gitignorefile so it isn't committed to github:
REACT_APP_SOCRATA_TOKEN = TNxXJT9OVmO6FDIhzqXYaEKJ
- The environment variable can be used in your code by prepending
process.env.to the name of the variable and wrapping it in{}: e.g. `{process.env.REACT_APP_SOCRATA_TOKEN} - If you change the environment variables, you will need to restart the server to implement the new environment variables.
Read more about using Custom Environment Variables in the React Documentation.
Successfully using APIs to get data is all about knowing the data you need, finding a source for that data, and being able to access it via a URL.
At this point, we encourage you to explore the NYC Open Data Portal for data that you find interesting and would like use in a creative and meaningful way.





