Search code examples
rhttr

How to get httr POST request to work in R?


I'm trying to connect to the Oanda API but struggling to format my request properly.

The API documentation requires the following format:

body=$(cat << EOF
{
  "order": {
    "price": "1.2000",
    "timeInForce": "GTC",
    "instrument": "EUR_CAD",
    "units": "10000",
    "clientExtensions": {
      "comment": "New idea for trading",
      "tag": "strategy_9",
      "id": "my_order_100"
    },
    "type": "MARKET_IF_TOUCHED",
    "positionFill": "DEFAULT"
  }
}
EOF
)

curl \
  -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <AUTHENTICATION TOKEN>" \
  -d "$body" \
  "https://api-fxtrade.oanda.com/v3/accounts/<ACCOUNT>/orders"

My request is as follows:

    require(httr)
    body = list(instrument="EUR_USD", #These 4 are the required fields for this order type
         units="1", 
         side="buy", 
         type="market"
)

auth = paste("Authorization: Bearer ",Token)

POST(add_headers("Content-Type: application/json",auth),
     body = body,
     url = 'https://api-fxpractice.oanda.com')

However, I'm getting the following response 404 back:

    Response [https://api-fxpractice.oanda.com]
      Date: 2020-03-27 09:53
      Status: 404
      Content-Type: application/json
      Size: 170 B
    {
        "code" : 38,
        "message" : "No matching handler for the request is found",
        "moreInfo" : "http:\/\/developer.oanda.com\/docs\/v1\/troubleshooting\/#errors"
    }

What am I doing wrong?


Solution

  • You are missing order and you need to explicitly convert your request to json. Give it a try:

    library("RCurl")
    library("rjson")
    
    # Accept SSL certificates issued by public Certificate Authorities
    options(RCurlOptions = list(cainfo = system.file("CurlSSL", "cacert.pem", package = "RCurl")))
    
    h = basicTextGatherer()
    hdr = basicHeaderGatherer()
    
    
    req = list(
            order = list(instrument="EUR_USD",
                            units="1", 
                            side="buy", 
                            type="market")
    )
    
    body = enc2utf8(toJSON(req))
    Token = "abc123" # Replace this with the API key for the web service
    authz_hdr = paste('Bearer', Token, sep=' ')
    
    h$reset()
    curlPerform(url = "",
                httpheader=c('Content-Type' = "application/json", 'Authorization' = authz_hdr),
                postfields=body,
                writefunction = h$update,
                headerfunction = hdr$update,
                verbose = TRUE
                )
    
    headers = hdr$value()
    httpStatus = headers["status"]
    if (httpStatus >= 400)
    {
        print(paste("The request failed with status code:", httpStatus, sep=" "))
    
        # Print the headers - they include the requert ID and the timestamp, which are useful for debugging the failure
        print(headers)
    }
    
    print("Result:")
    result = h$value()
    print(fromJSON(result))
    

    My guess is that it is automatically conveted into a text, and there is no matching handler method for text