# Proper format for simple API call in R

**URL:** <https://forum.ipums.org/t/proper-format-for-simple-api-call-in-r/4901>\
**Category:** IPUMS API\
**Created:** [October 6, 2022, 10:47pm UTC](https://forum.ipums.org/t/proper-format-for-simple-api-call-in-r/4901 "2022-10-06T22:47:06Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![John\_Shadle](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.ipums.org/john_shadle/32/684_2.png) [@John\_Shadle](https://forum.ipums.org/u/John_Shadle)\
**Post date:** [October 6, 2022, 10:47pm UTC](https://forum.ipums.org/t/proper-format-for-simple-api-call-in-r/4901/1 "2022-10-06T22:47:07Z")

</div>

Hi all. I’m new to using APIs in R, so please forgive me for this likely simple question; however, I’m pulling my hair out trying to get this to work. 🙂

I’m not going to post my API key here, but suffice it to say that it is saved in R and it’s called in the code. I keep receiving the same error.

> url ← “[https://api.ipums.org/extracts/?collection=nhgis&version=v1](https://api.ipums.org/extracts/?collection=nhgis&version=v1)”  
> mybody ← '{  
> “datasets”: {  
> “2016\_2020\_ACS5a”: {  
> “data\_tables”: [“B15003”],  
> “geog\_levels”: [“county”]  
> }  
> },  
> “geographic\_instances”: [“010”],  
> “data\_format”: “csv\_no\_header”,  
> “description”: “test\_b15003”  
> }
> 
> ’  
> mybody\_json ← fromJSON(mybody, simplifyVector = FALSE)  
> result ← POST(url, add\_headers(Authorization = my\_key), body = mybody\_json, encode = “json”, verbose())  
> res\_df ← content(result, “parsed”, simplifyDataFrame = TRUE)  
> my\_number ← res\_df$number  
> my\_number

The error is below.

> → POST /extracts/?collection=nhgis&version=v1 HTTP/1.1  
> → Host: [api.ipums.org](http://api.ipums.org)  
> → User-Agent: libcurl/7.64.1 r-curl/4.3.2 httr/1.4.4  
> → Accept-Encoding: deflate, gzip  
> → Accept: application/json, text/xml, application/xml, _/_  
> → Content-Type: application/json  
> → Authorization: 59cba10d8a5da536fc06b59d17125ffa0b114a2cb3f2f546cec95a68  
> → Content-Length: 173  
> →
> 
> > > {“datasets”:{“2016\_2020\_ACS5a”:{“data\_tables”:[“B15003”],“geog\_levels”:[“county”]}},“geographic\_instances”:[“010”],“data\_format”:“csv\_no\_header”,“description”:“test\_b15003”}
> 
> ← HTTP/1.1 500 Internal Server Error  
> ← Content-Length: 0  
> ← Content-Type: text/html; charset=UTF-8  
> ← Date: Thu, 06 Oct 2022 22:39:31 GMT  
> ← Server: nginx/1.18.0 + Phusion Passenger(R) 6.0.15  
> ← Status: 500 Internal Server Error  
> ← Vary: Origin  
> ← X-Powered-By: Phusion Passenger(R) 6.0.15  
> ← X-Ratelimit-Limit: -1  
> ← X-Ratelimit-Remaining: 0  
> ← X-Ratelimit-Reset: 0  
> ← X-Request-Id: a28802ed-ab31-4cec-aa07-70d77b4f284f  
> ← X-Runtime: 0.059476  
> ←
> 
> > res\_df ← content(result, “parsed”, simplifyDataFrame = TRUE)  
> > my\_number ← res\_df$number  
> > my\_number  
> > NULL

---

<div class="post-metadata">

**Author:** ![fran](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.ipums.org/fran/32/363_2.png) [@fran](https://forum.ipums.org/u/fran)\
**Post date:** [October 7, 2022, 1:18pm UTC](https://forum.ipums.org/t/proper-format-for-simple-api-call-in-r/4901/2 "2022-10-07T13:18:10Z")

</div>

Hi John,

How are you forming your JSON payload? Are you writing it in something like Word and then copying it to your code? The reason I ask is that when I cut and paste your JSON, it includes “smart quote” characters instead of regular double quotes, which are not valid JSON. We often see that when text has passed through Word or a similar program.

You can validate that you are starting with valid JSON using a validator like [jsonlint.com](http://jsonlint.com) to rule this out as the cause.

---

<div class="post-metadata">

**Author:** ![Marcos\_Luna](https://avatars.discourse-cdn.com/v4/letter/m/f04885/32.png) [@Marcos\_Luna](https://forum.ipums.org/u/Marcos_Luna)\
**Post date:** [November 25, 2022, 7:27pm UTC](https://forum.ipums.org/t/proper-format-for-simple-api-call-in-r/4901/3 "2022-11-25T19:27:48Z")

</div>

Hi. I’m having a similar problem to John and cannot figure out what’s wrong with my code.

This code works:

# submit data extract request

url ← “[https://api.ipums.org/extracts/?collection=nhgis&version=v1](https://api.ipums.org/extracts/?collection=nhgis&version=v1)”  
mybody ← ’

{  
“datasets”: {  
“2000\_SF1b”: {  
“data\_tables”: [  
“NP001A”  
],  
“geog\_levels”: [  
“blck\_grp”  
]  
}  
},  
“geographic\_extents”: [“250”],  
“data\_format”: “csv\_no\_header”,  
“description”: “sample6”  
}

’

mybody\_json ← fromJSON(mybody, simplifyVector = FALSE)  
result ← POST(url, add\_headers(Authorization = my\_key), body = mybody\_json, encode = “json”, verbose())

However, when I simply change the datatset, data table, and geographic level, the following code does not work:  
mybody ← ’

{  
“datasets”: {  
“1980\_STF1”: {  
“data\_tables”: [  
“NT1A”  
],  
“geog\_levels”: [  
“tract”  
]  
}  
},  
“geographic\_extents”: [“250”],  
“data\_format”: “csv\_no\_header”,  
“description”: “sample6”  
}

mybody\_json ← fromJSON(mybody, simplifyVector = FALSE)  
result ← POST(url, add\_headers(Authorization = my\_key), body = mybody\_json, encode = “json”, verbose())

The error is below:  
 → POST /extracts/?collection=nhgis&version=v1 HTTP/1.1  
 → Host: [api.ipums.org](http://api.ipums.org)  
 → User-Agent: libcurl/7.64.1 r-curl/4.3.2 httr/1.4.3  
 → Accept-Encoding: deflate, gzip  
 → Accept: application/json, text/xml, application/xml, _/_  
 → Content-Type: application/json  
 → Authorization: 59cba10d8a5da536fc06b59da78b632ef9224353a8a79182a1ccc1a0  
 → Content-Length: 158  
 →

> > {“datasets”:{“1980\_STF1”:{“data\_tables”:[“NT1A”],“geog\_levels”:[“tract”]}},“geographic\_extents”:[“250”],“data\_format”:“csv\_no\_header”,“description”:“sample6”}

← HTTP/1.1 400 Bad Request  
 ← Cache-Control: no-cache  
 ← Content-Type: application/json; charset=utf-8  
 ← Date: Fri, 25 Nov 2022 19:25:45 GMT  
 ← Referrer-Policy: strict-origin-when-cross-origin  
 ← Server: nginx/1.18.0 + Phusion Passenger(R) 6.0.15  
 ← Status: 400 Bad Request  
 ← Vary: Origin  
 ← X-Content-Type-Options: nosniff  
 ← X-Download-Options: noopen  
 ← X-Frame-Options: SAMEORIGIN  
 ← X-Permitted-Cross-Domain-Policies: none  
 ← X-Powered-By: Phusion Passenger(R) 6.0.15  
 ← X-Ratelimit-Limit: -1  
 ← X-Ratelimit-Remaining: 0  
 ← X-Ratelimit-Reset: 0  
 ← X-Request-Id: 82ea0305-b21c-4f15-bce2-bb556411cb47  
 ← X-Runtime: 0.133891  
 ← X-Xss-Protection: 1; mode=block  
 ← Content-Length: 231

Again, all I changed was the datatset, data table, and geographic level. What am I doing wrong?

---

<div class="post-metadata">

**Author:** ![fran](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.ipums.org/fran/32/363_2.png) [@fran](https://forum.ipums.org/u/fran)\
**Post date:** [November 27, 2022, 3:20pm UTC](https://forum.ipums.org/t/proper-format-for-simple-api-call-in-r/4901/4 "2022-11-27T15:20:10Z")

</div>

It looks like in the second code sample you are missing the closing ’ on the mybody variable assignment. When I add that back in, the code works for me.

---

<div class="post-metadata">

**Author:** ![Marcos\_Luna](https://avatars.discourse-cdn.com/v4/letter/m/f04885/32.png) [@Marcos\_Luna](https://forum.ipums.org/u/Marcos_Luna)\
**Post date:** [November 27, 2022, 9:46pm UTC](https://forum.ipums.org/t/proper-format-for-simple-api-call-in-r/4901/5 "2022-11-27T21:46:53Z")

</div>

Sorry, I copied my code incorrectly into the Reply. The closing ’ was actually there. Tried it again with the following and still no dice.

mybody ← ’

{  
“datasets”: {  
“1980\_STF1”: {  
“data\_tables”: [“NT1A”],  
“geog\_levels”: [“tract”]  
}  
},  
“geographic\_extents”: [“250”],  
“data\_format”: “csv\_no\_header”,  
“description”: “sample6”  
}

’

---

<div class="post-metadata">

**Author:** ![fran](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.ipums.org/fran/32/363_2.png) [@fran](https://forum.ipums.org/u/fran)\
**Post date:** [November 28, 2022, 3:44pm UTC](https://forum.ipums.org/t/proper-format-for-simple-api-call-in-r/4901/6 "2022-11-28T15:44:53Z")

</div>

Ah, I apologize, an issue with my rstudio environment had me thinking it was working when it was not.

I think I’ve discovered the true source of the issue: 1980\_STF1’s tract geographic level does not support extent selection. I confirmed this using the NHGIS metadata API:

```auto
GET https://api.ipums.org/metadata/nhgis/datasets/1980_STF1?version=v1

...

        {
            "name": "tract",
            "description": "State--County--Census Tract",
            "has_geog_extent_selection": false,
            "sequence": 65
        },

...

```

If you remove the geographic\_extents key-value pair from your JSON, it appears to work.

Hope this helps!

---

<div class="post-metadata">

**Author:** ![fran](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.ipums.org/fran/32/363_2.png) [@fran](https://forum.ipums.org/u/fran)\
**Post date:** [November 28, 2022, 4:01pm UTC](https://forum.ipums.org/t/proper-format-for-simple-api-call-in-r/4901/7 "2022-11-28T16:01:34Z")

</div>

Additionally, the response body contains more details about validation errors. In this example, here is the response body:

```auto
> content(result)
$type
[1] "SemanticValidationError"

$status
$status$code
[1] 400

$status$name
[1] "Bad Request"

$detail
$detail[[1]]
[1] "Geographic extents Extent selection is not required for selected geog levels. Please remove the 'geographic_extents' section of you request."

> 

```

Hopefully this is useful for your future debugging!
