'app_id' and 'app_key' are (probably) not standards-compliant

Out of hundreds of APIs I've interacted with over the years, this is the first one I've run into that requires non-standard HTTP headers. The library I use transforms 'app_id' and 'app_key' header keys into the strictly normalized formats of 'App-Id' and 'App-Key', which the API subsequently rejects. Attempting to use the 'app_id' and 'app_key' in the GET request as query parameters also fails.

As far as I'm concerned, this is a bug in the API. The API should accept case-insensitive transformations AND underscores being converted to hyphens in your incoming headers or at least accept them on the GET URI as parameters. I've never seen underscores as request header keys before. The HTTP/1.1 Standard previously recommended prefixing custom headers with 'X-' and all headers from the IETF are hyphenated, so there is plenty of precedent to back the claim that this is a bug in the API. The HTTP standard and other documents produced by the IETF also frequently state something along the lines of "be strict in what you send, liberal in what you accept".


  • AmosDuveenAmosDuveen Member, Administrator, Moderator admin

    Hi @mikesmoothie,

    Can you please post the relevant snippet of your code (obscuring your credentials, obviously!) so that we can get a sense of what might be happening?

    Given the number of people who are using the API successfully, I'd be quite surprised if there were any such fundamental issues. The fact that your calls get rejected may actually have a different cause altogether so I'd like to get as full a picture as possible, before diagnosing any issues.

  • mikesmoothiemikesmoothie Member
    edited April 2018

    Here is an example raw communication dump with the API. Bytes sent:

    GET /api/v1/entries/en/griddle HTTP/1.1
    Host: od-api.oxforddictionaries.com
    Connection: close
    Accept: text/html, application/xhtml+xml, */*
    Accept-Language: en-us,en;q=0.5
    Cache-Control: max-age=0
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0
    App-Id: [Removed]
    App-Key: [Removed]

    Bytes received:

    HTTP/1.1 403 Forbidden
    Content-Type: text/plain; charset=us-ascii
    Date: Wed, 04 Apr 2018 18:03:29 GMT
    Server: openresty/
    Content-Length: 33
    Connection: Close
    Authentication parameters missing

    As you can see, the library is normalizing 'app_id' and 'app_key' headers into 'App-Id' and 'App-Key'. The server is ignoring that it received valid normalized HTTP headers and responding that it didn't receive the expected information (i.e. a bug in the API). 'app_id' and 'app_key' are also not accepted on the GET request line (i.e. another bug). IMO, while the library I'm using is technically violating the HTTP spec by only allowing specific characters through for header keys, so is the Oxford API by ignoring standards for how HTTP headers have always been transmitted (i.e. hyphenated words). HTTP header keys MUST be normalized on the server side of things anyway or code will inevitably end up doing the wrong thing, possibly leading to security vulnerabilities. Even if you prefer 'app_id' and 'app_key', passing 'ApP-iD' and 'app_KEy' on the wire should still work fine. For GET and POST variables, an API can be far more strict about naming but HTTP headers have always been extremely flexible (in both directions).

  • By the way, I got it working fine by hardcoding the headers to all lowercase 'app_id' and 'app_key' (with underscores) and was the only thing changed about the request.

  • AmosDuveenAmosDuveen Member, Administrator, Moderator admin

    Good to hear you go it working, @mikesmoothie.

    I don't think I've ever tried capitalizing app_id and app_key but when I do, the software I use, Postman (because I'm not actually coding an app), seems to automatically process the headers as lower case.

    To be honest, I'm not sure what language your using or if there is any relevant code I'm not seeing but there doesn't appear to be any indication that app_id and app_key are labelled as headers in the code snippet you posted; maybe that is what changed when you hard coded it?

Sign In or Register to comment.