eBay REST API OAuth2: Plain English Edition

I’ve been working with the eBay API since my time at a small Chicago startup a few years back. In fact, it was working at this particular startup with a lot of people far smarter than myself that pushed me in the direction of web development, nearly mid career. I had developed some in the past, but mostly small utilities with .NET (C#) or analytical apps/scriptlets with Python. The eBay API is challenging, which appealed to me, as working with it helped propel me into new avenues of learning and innovation.

The eBay API documentation is rather difficult to understand at times, equally difficult to navigate, and constantly expanding. In the documentation, you can see new beta releases for several upcoming API endpoints. All of that aside, one of the most difficult things for me to work through was eBay’s implementation and documentation of OAuth 2.0. eBay offers two methods for obtaining User Tokens which an app would use to authenticate calls. Let me outline both methods and provide some basic examples with JS — keep in mind I typically develop a separate backend with Node.JS and my “front-end” is React, however most of the tools I use have a vanilla JS equivalent.

Client credentials grant👎

This is, admittedly, the easiest to implement, albeit least desirable, method as it allows access to a very limited number of scopes within the eBay API. This is assumably because it is less secure and has fewer “legs”. I won’t go into too much detail, but with this request the client_id and client_secret are Base64 encoded and passed in the header of a POST request, while the request body contains the grant type of “client_credentials”, the RuName-value (retrieved from the developer portal) and the required scope. As I mentioned before, the available scopes are very, very limited for this type of authentication.

Authorization code grant 👍

The authorization code grant provides authentication for a much broader scope within the eBay REST API and is 3-legged in its implementation. Here are the steps — in (hopefully) plain English (so I can validate the title for this publication):

  1. Your app redirects the user to a page (hosted by eBay) where they login with their account credentials. Note: This URI also contains your client_id and the API scopes you plan to work with and is provided in the eBay dev portal labeled Your branded eBay Production Sign In (OAuth)
    Example: https://auth.ebay.com/oauth2/authorize?client_id=TestAcct-0123-4567–890d-a1bcde23456&response_type=code&redirect_uri=Test_Account-TestAcct-0123-4-dxluzra&scope=https://api.ebay.com/oauth/api_scope%20https://api.ebay.com/oauth/api_scope/sell.marketing.readonly%20https://api.ebay.com/oauth/api_scope/sell.marketing
  2. eBay redirects the user back to your application to a URI you have provided beforehand with an authorization code appended.
    Example: https://localhost:3000?code=<authentication code>
  3. Your application parses the authorization code from the URI and uses it to make a POST call to the eBay API for an access token. (Don’t forget to Base64 encode your client_id and client_secret. With Node.js, I use the btoa npm package along with qs to compose my request using fetch.

Example:

fetch(‘https://api.ebay.com/identity/v1/oauth2/token', {
method: ‘post’,
headers: {
‘Content-Type’: ‘application/x-www-form-urlencoded’,
‘Authorization’: ‘Basic ‘ + btoa(`${clientId}:${clientSecret}`)
},
body: qs.stringify({
grant_type: “authorization_code”,
// parsed from redirect URI after returning from eBay,
code: authCode,
// this is set in your dev account, also called RuName
redirect_uri: ‘Test_Account-TestAcc-0123–4-abcdefg’
})
})
.then(response => response.json())
.catch(err => console.log(err));

4. eBay returns the access token which is used to make subsequent calls to the eBay API. A refresh token and associated expiry time (in seconds) is returned in this response.

Example:

{
"access_token": "v^1.1#i^1#p^3#r^1...XzMjRV4xMjg0",
"expires_in": 7200,
"refresh_token": "v^1.1#i^1#p^3#r^1...zYjRV4xMjg0",
"refresh_token_expires_in": 47304000,
"token_type": "User Access Token"
}

5. Use the refresh token to refresh the access token when it expires — you know when to do this when your call to the API returns a status code of 401 and the following body:

{ 
“errors”:[
{
“errorId”:1001,
“domain”:”OAuth”,
“category”:”REQUEST”,
“message”:”Invalid access token”,
“longMessage”:”Invalid access token. Check the value of the Authorization HTTP request header.”
}
]
}

That’s it — easy stuff right? Hopefully this short article helps decrypt the oftentimes confusing eBay API authentication documentation. I’ll put it this way: If you can master any part of the eBay REST API, you can (probably) master anything. 💪

Terms to Understand:

  • client_id: Called App ID in the “Key Sets” of the developer portal
  • client_secret: Called Cert ID in the “Key Sets” section of the dev portal
  • RuName: Redirect URL name Ex: Test_Account-TestAcc-0123–4-abcdefg
  • authorization code: code used to request access token
  • access token: token used to authenticate requests to the eBay API
  • refresh token: token used to refresh the access token when it expires