For Server-Side Applications

Harvest uses the Authorization Code flow for server-side authorization.

1. Redirect users to Harvest to authorize their accounts with your application.

GET https://example.harvestapp.com/oauth2/authorize?client_id={client ID}&redirect_uri=https%3A%2F%2Fexample.com%2Fredirect_path&state=optional-csrf-token&response_type=code

To limit access to a single Harvest account, you can specify its web address instead of api.harvestapp.com.


2. Get the authorization code when Harvest redirects back to your application. Harvest sends it to your redirect URI as a query parameter.

GET https://example.com/redirect_path?code={authorization code}&state=optional-csrf-token


3. Request an access token using the authorization code.

Note: the Content-Type header for this request must be application/x-www-form-urlencoded.

POST https://example.harvestapp.com/oauth2/token

{
  "code":          "{authorization code from Harvest}",
  "client_id":     "{your application's client ID}",
  "client_secret": "{your application's client secret}",
  "redirect_uri":  "{your application's redirect URI}",
  "grant_type":    "authorization_code"
}


4. Get the access and refresh tokens from the response.

{
    "token_type": "bearer",
    "expires_in": 64799,
    "access_token": "{access token}",
    "refresh_token": "{refresh token}"
}


5. Use the access token to send authorized requests to the Harvest API.

Note: the Content-Type and Accept headers for this request must be application/json or application/xml.

GET https://example.harvestapp.com/account/who_am_i?access_token={access token}


6. Request a new access token after 18 hours using the refresh token.

Note: the Content-Type header for this request must be application/x-www-form-urlencoded.

POST https://example.harvestapp.com/oauth2/token

{
  "refresh_token": "{user's refresh token}",
  "client_id":     "{your application's client ID}",
  "client_secret": "{your application's client secret}",
  "grant_type":    "refresh_token"
}


7. Get the new tokens from the response.

{
  "token_type": "bearer",
  "expires_in": 64799,
  "access_token": "{access token}",
  "refresh_token": "{refresh token}"
}