OAuth Tokens
Last updated
Last updated
While API Keys are a quick and convenient way to make API requests from your third-party application in a machine-to-machine setting, sometimes you may want to authorize each user individually with a unique access token for each. This allows you to get the user context for specific users and require each user to authenticate with Pitchly before using Pitchly data in your application.
To get user-specific access tokens, you can use Pitchly's OAuth authorization code flow. OAuth is a global authorization standard for sharing data from one application to another. You can find an example of how this flow generally works here.
Below is a description of each step in the OAuth authorization code flow (and refresh token flow).
This endpoint is triggered by the user opening this page in their browser with the following query parameters in the URL. The user will be presented with the option to authorize your app access to the user's Pitchly account. If approved, your app will receive an authorization code in return. In the next request, you will exchange that code for an actual access token via a server-side call.
GET
https://v2.pitchly.net/oauth/authorize
Redirect the user to this URL with the following query parameters to start the OAuth flow. Once the user approves access (or if they have already approved), the user will be redirected to the appropriate redirect URI (specified in the app's configuration) with an authorization code that can be exchanged for an access token.
Name | Type | Description |
---|---|---|
Call this from your application's server side to exchange the authorization code returned by the previous request for an access token. You can then provide this access token in GraphQL API requests in the accessToken
variable. When using a user-specific access token, replace all instances of secretKey
in your GraphQL requests with accessToken
, and provide your access token within it.
Do not call this endpoint from the client side, since the request contains your application's secret key. You should never make your secret key accessible client side.
POST
https://v2.pitchly.net/api/oauth/access_token
Call this on your backend to exchange the authorization code acquired from the first step for an access token, which you can use to make GraphQL API requests.
This step is optional and only applies if you wish to continue making API calls to Pitchly while the user is offline, or if you would like to continue making API requests without sending the user back through the OAuth flow after the token expires in 2 hours.
Whenever you receive a token-invalid
error from a GraphQL API request, call this endpoint to get a new access token and retry the request. You will need a refresh token either from the previous request or from the result following this request.
While refresh tokens do not expire over time, they do expire as soon as they're used. If you wish to refresh access tokens, we recommend storing the refresh token in your database until it is ready to be used, and once exchanged, swap it with the new refresh token for the next refresh.
POST
https://v2.pitchly.net/api/oauth/access_token
Call this to exchange a refresh token for a new access token and refresh token.
If you wish to use OAuth to acquire user-specific access tokens but don't have a sever side to exchange an authorization code for an access token, you can alternatively use the implicit flow to get an access token directly instead of an authorization code.
This method is not recommended if you do have a server side with which you can exchange authorization codes because it is slightly less secure than the authorization code flow described above. This method should only be used if you do not have a server side that can keep a secret, such as in the case of a single-page application (SPA) that does not have a server or a native mobile or desktop app.
To initiate the implicit flow, send the user to this endpoint:
GET
https://v2.pitchly.net/oauth/authorize
Redirect the user to this URL with the following query parameters to start the OAuth flow. Once the user approves access (or if they have already approved), the user will be redirected to the appropriate redirect URI (specified in the app's configuration) with an access token.
If you do not have a server side, you will not be able to utilize refresh tokens to generate new access tokens once they expire because a secret cannot be kept. Instead, you will need to send the user back through this OAuth flow after the access token expires, so you can receive a new access token. By default, access tokens expire after 2 hours.
In future versions of Pitchly, you will not need to forward the user back through the OAuth flow to refresh access tokens on public clients (such as SPAs). Future versions of Pitchly will instead recommend always using the authorization code flow with PKCE (a new standard for generating dynamic secrets for a public client), which will allow you to exchange an auth code for an access token and refresh token entirely client side using a dynamic secret instead of a fixed secret which we use today.
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
response_type*
String
"code"
client_id*
String
App ID
redirect_uri
String
One of the redirect URIs provided when you configured your app. Note that it must match exactly. If one is not provided, the first one configured for your app is assumed.
state
String
A random string that will be returned back to your redirect URI as a query parameter. If the returned state matches the state originally used at the start of the OAuth flow, you can validate that the request has not been forged (see CSRF attacks).
organization_id
String
If provided, this organization will be selected by default for the user. If the app is already approved for the user on this org, the user will also be immediately redirected back to the app with a valid code. For an app to be approved, an admin must have already allowed the app on the org.
force_prompt
String
If set to "true", "yes", or "1", the user will always be prompted to allow the app, even if organization_id is provided and the app is already approved.
content-type*
String
"application/x-www-form-urlencoded"
accept*
String
"application/json"
grant_type*
String
"authorization_code"
code*
String
The authorization code returned as a query param in the response of the previous request.
client_id*
String
App ID
client_secret*
String
App Secret
content-type*
String
"application/x-www-form-urlencoded"
accept*
String
"application/json"
grant_type*
String
"refresh_token"
refresh_token*
String
Refresh token, returned in the previous request or when rerunning this request.
client_id*
String
App ID
client_secret*
String
App Secret
scope
String
A space-delimited list of permissions to downscope the resulting access token to. Note that the refresh token will still possess full permissions and can be used to generate more access tokens with elevated permissions, but the access token returned in this request will be downscoped, allowing you to pass it to a client with limited permissions. Possible values are: readData
, insertData
, updateData
, deleteData
, addFields
, and readMembers
(see Permissions for details). By default, not providing a scope will fall back to full permissions allowed for the app.
response_type*
String
"token"
client_id*
String
App ID
redirect_uri
String
One of the redirect URIs provided when you configured your app. Note that it must match exactly. If one is not provided, the first one configured for your app is assumed.
state
String
A random string that will be returned back to your redirect URI as a query parameter. If the returned state matches the state originally used at the start of the OAuth flow, you can validate that the request has not been forged (see CSRF attacks).
organization_id
String
If provided, this organization will be selected by default for the user. If the app is already approved for the user on this org, the user will also be immediately redirected back to the app with a valid token. For an app to be approved, an admin must have already allowed the app on the org.
force_prompt
String
If set to "true", "yes", or "1", the user will always be prompted to allow the app, even if organization_id is provided and the app is already approved.