{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["admonition"]},"type":"markdown"},"seo":{"title":"API access - Development Portal | Outreach","description":"Outreach extensibility development and documentation portal","siteUrl":"https://developers.outreach.io","keywords":"outreach developer portal, api documentation, api reference docs, sdk documentation","lang":"en-US","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"api-access","__idx":0},"children":["API access"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Outreach currently enables access to the REST API via API calls authenticated via ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"https://datatracker.ietf.org/doc/html/rfc6749","target":"_blank"},"children":["OAuth 2.0 protocol"]},". Additionally a limited set of API endpoints is available with an authentication  token you can"," ","obtain through a proprietary ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/api/s2s-access"},"children":["S2S protocol"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"oauth-in-a-nutshell","__idx":1},"children":["OAuth in a nutshell"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["OAuth 2.0 is a standard authorization protocol and there is a lot of information online on how to implement it. Here is how it works in a nutshell:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Once you need to connect to Outreach in your own application, you redirect the user to an URL like ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"https://api.outreach.io/oauth/authorize?client_id=ifamislm1dBbDI~YxPBKSDk1jQ3.lMLP9oIbIEUezH13&redirect_uri=https%3A%2F%2Flocalhost%3A8888%2Foauth%2Fredirect&response_type=code&scope=accounts.read","target":"_blank"},"children":["https://api.outreach.io/oauth/authorize?client_id=...&redirect_uri=...&response_type=code&scope=..."]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["At the authorization page user is informed about which data your application intends to use and gives their consent to do so."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Following the consent Outreach redirects the user to the URL on your server passing along a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["code"]}," query parameter also known as the Authorization Grant."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["You use the Authorization Grant to ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#requesting-access-token"},"children":["obtain"]}," the Access Token."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["With the Access Token you call the Outreach REST API endpoints. Outreach will execute all the calls on behalf of the user who performed authorization."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Access token is valid for limited period only but you can refresh it using the refresh token returned in the same response."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"setting-up-oauth","__idx":2},"children":["Setting up OAuth"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To begin using the REST API you need to ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/client-extensions/your-first-outreach-extension/"},"children":["create an Outreach app"]},". Then go to the API access tab to configure access specifics. You'll need to specify one or more redirect URI's and select the OAuth data scopes that your application intends to use. Please select at least one scope and specify at least one redirect URI."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"img","attributes":{"src":"/assets/app-oauth-enable.5379815e354c7ac6047541e6a0d87e6313f07881a9646a920047dae98a9c9db5.9c1bb791.png","alt":"n/a","title":"Outreach API enabled for an app"},"children":[]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"oauth-credentials","__idx":3},"children":["OAuth credentials"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For each Outreach app, the development and production credentials are generated."]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Development"]}," credentials are provisioned immediately and are intended to be used during application development and testing. Any change (e.g. to scopes) is applied immediately on save. The authorization page warns users that they are using development and unreviewed application and usage of development version is ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#limitations-of-development-credentials"},"children":["limited"]},". Do not let your end-users use these development credentials."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Production"]}," credentials are provisioned after the app goes through the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/managing-apps"},"children":["publishing process"]}," and eventually a review. The scopes and URLs are updated when you click on the Publish button."]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Please be aware that OAuth client secrets will be displayed only once, when generated. You cannot display them again. Use the \"Regenerate\" button to create new secrets if necessary."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"limitations-of-development-credentials","__idx":4},"children":["Limitations of development credentials"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If an end-user goes through OAuth flow that contains development credentials they will be warned that the application is not production ready."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"img","attributes":{"src":"/assets/oauth-dialog-with-warning.773399a3bb653443234c4d61acf486c6db87f67e66dac38b1624a45d918972a6.9c1bb791.png","alt":"n/a","title":"#width=500px;Authorize with caution example"},"children":[]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Application's development credentials can be authorized by any user from any org. However, the development credentials are meant for developers and testers only. We do not impose any arbitrary block to enforce fair usage but we expire the grant provided by users and revoke all tokens, so users need to re-authorize the app once in a while."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Development credentials are usable with no limitation for up to 10 people from the organization that owns the app."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Users from other orgs or when there are more users from the owning org will need to reauthorize the app weekly."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"requesting-access-token","__idx":5},"children":["Requesting access token"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Following user authorization browser will redirect the user to the specified redirect URI containing the authorization grant: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["<redirect_uri>?code=<authorization_grant>"]},"."," ","Read the value of the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["code"]}," parameter and pass it to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://api.outreach.io/oauth/token"]}," to get your OAuth token for this user:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl https://api.outreach.io/oauth/token \\\n  -X POST \\\n  -d client_id=<client_id> \\\n  -d client_secret=<client_secret> \\\n  -d redirect_uri=<redirect_uri> \\\n  -d grant_type=authorization_code \\\n  -d code=<authorization_grant>\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Please be aware that the secret might contain URL-unsafe characters and must be properly encoded. Some tools are known to properly encode redirect URL but not the secret."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This call will only be successful if all of the parameter values match ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["exactly"]}," the values which initiated this OAuth flow."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["In some situations you may need to set up different redirect URIs for development and production client IDs so that you know which credential (prod or dev) you need to use in the above call."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The response of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/oauth/token"]}," looks like"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"access_token\": \"eyJhbGc...\",\n  \"token_type\": \"Bearer\",\n  \"expires_in\": 7200,\n  \"refresh_token\": \"EcC-5gWjbN...\",\n  \"scope\": \"users.read\",\n  \"created_at\": 1706289101\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"preventing-csrf-attacks-with-state-parameter","__idx":6},"children":["Preventing CSRF attacks with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["state"]}," parameter"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["state"]}," parameter lets you link the request to your user's session and mitigate the CSRF attacks. Using a unique and non-guessable value associated with each authentication request, and validating that the value coming from the response matches the one you sent makes your application secure."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"  https://api.outreach.io/oauth/authorize?client_id=<client_id>&redirect_uri=<redirect_uri>&response_type=code&scope=<scope1+scope2>&state=34d234fst42twerwr23sd\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["will redirect the client to your server while maintaining the value of the dev parameter ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["<redirect_uri>?code=<authorization_grant>&state=34d234fst42twerwr23sd"]},". You can then read the value of the state parameter, match it and choose the correct credential for the token acquisition call."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Outreach internally protects the Authorization (consent) page against CSFR attacks with similar mechanism using ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["authenticity_token"]}," parameter"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"refreshing-access-token","__idx":7},"children":["Refreshing access token"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You should store the refresh token securely and use it to obtain a new access token once the original expires. Call ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/oauth/token"]}," as above but use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["grant_type=refresh_token"]},"."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl https://api.outreach.io/oauth/token \\\n  -X POST \\\n  -d client_id=<client_id> \\\n  -d client_secret=<client_secret> \\\n  -d grant_type=refresh_token \\\n  -d refresh_token=<refresh_token>\n","lang":"bash"},"children":[]}]},"headings":[{"value":"API access","id":"api-access","depth":1},{"value":"OAuth in a nutshell","id":"oauth-in-a-nutshell","depth":2},{"value":"Setting up OAuth","id":"setting-up-oauth","depth":2},{"value":"OAuth credentials","id":"oauth-credentials","depth":3},{"value":"Limitations of development credentials","id":"limitations-of-development-credentials","depth":3},{"value":"Requesting access token","id":"requesting-access-token","depth":3},{"value":"Preventing CSRF attacks with state parameter","id":"preventing-csrf-attacks-with-state-parameter","depth":3},{"value":"Refreshing access token","id":"refreshing-access-token","depth":3}],"frontmatter":{"seo":{"title":"API access - Development Portal | Outreach"}},"lastModified":"2026-04-29T11:57:31.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/api/oauth","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}