# Set Up OAuth 2.0

This guide outlines the steps to implement the impact.com OAuth 2.0 Authorization Code flow, which is required for any application that needs to access data on behalf of a user.

Follow these instructions to ensure your application securely requests user consent and manages delegated access, while adhering to modern security standards like ​[PKCE](https://oauth.net/2/pkce/)​​ ​and token rotation.

When you request OAuth 2.0 access from impact.com, it is for a single application with a specific, clear purpose, not for your entire company. You cannot mix access permissions from different areas (like Brand, Partner, or Agency) in the same application.

{% hint style="info" %}
For example, if your company, ACME, builds an application for its media partners called the *ACME Partner Dashboard*, that application would be restricted to only Partner permissions. If ACME wanted to build a separate application for brand advertisers, like *ACME Brand Analytics*, it would have to request new credentials, and that application would only get Brand permissions.
{% endhint %}

### Obtain your application's OAuth 2.0 credentials

#### Log a support ticket​​

To begin the integration process and obtain your OAuth 2.0 credentials, ​[submit a ticket​](https://app.impact.com/support/portal.ihtml?createTicket=true&) to the impact.com support team. impact.com doesn't currently support the [Dynamic Client Registration Protocol (RFC 7591)](https://datatracker.ietf.org/doc/html/rfc7591)​, so your credentials will need to be provisioned manually, once your request is received. The impact.com team will review requests and grant access on a case-by-case basis to ensure the security of the platform.

The support ticket must include the application details listed below:

| **Field**            | **Description**                                                                                                                                                                                                                                                                                                                                                                                                                          | **Example**                                                                                          |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| Client Name          | The name of the application that will be displayed to the user on the consent screen.                                                                                                                                                                                                                                                                                                                                                    | ACME Partner Dashboard                                                                               |
| Redirect URIs        | The secure (https\://) URLs where users will be redirected after authorizing your application.                                                                                                                                                                                                                                                                                                                                           | <https://www.acme.com/landing/>                                                                      |
| Website URL          | The application's website.                                                                                                                                                                                                                                                                                                                                                                                                               | <https://www.acmeapp.com/>                                                                           |
| Terms of Service URL | URL for the application's terms of service.                                                                                                                                                                                                                                                                                                                                                                                              | <https://www.acmeapp.com/terms/>                                                                     |
| Logo                 | An image file, or a publicly accessible link to your application's logo, preferably in .SVG format, for display on the consent screen.                                                                                                                                                                                                                                                                                                   | <https://www.acme.com/logo.svg>                                                                      |
| Required Scopes      | Provide a space-separated list of the API endpoints your application needs permission to access. You can find lists of available URLs in the documentation for [Brand scopes](broken://pages/dkUwXn1yTAIdWrFtOiXI), [Partner scopes](broken://pages/YbeJKubZYLV6rXQ7sqZ1), or [Agency scopes](broken://pages/Ss8cYMUsOYzQwCq1Jk0o), or view the complete list on the impact.com [Integrations Portal](https://integrations.impact.com/). | <p><code>GET: /Advertisers/\<SID>/Ads</code></p><p><code>GET: /Advertisers/\<SID>/Actions</code></p> |

{% hint style="warning" %}
​**Important**: You'll need to submit a request for each application based on the account type the app will serve, either Brand, Partner, or Agency. You can't mix access permissions from different account types (like Brand, Partner, or Agency) in the same application.
{% endhint %}

#### Security Best Practices

* Implement the PKCE extension to protect your authorization code from interception and use the ​`state`​ parameter to protect users from ​[cross-site request forgery​​ (CSRF)](https://en.wikipedia.org/wiki/Cross-site_request_forgery) attacks.
* ​​​Ensure that sensitive credentials, specifically your ​`client_secret`​ and user ​`refresh_tokens`​​, are ​encrypted at rest​​ (i.e., on the storage device) within your backend systems and never stored in plain text.​​​
* Your ​`client_secret`​​ is a highly sensitive credential equivalent to a password. It must only be used on your backend server and must never be exposed in a mobile app, a desktop application, or any client-side JavaScript code running in a user's browser.

{% hint style="danger" %}
​​**Warning**:​ Exposing your ​`client_secret`​​ will lead to a severe security breach.
{% endhint %}

### The OAuth 2.0 flow

<div data-with-frame="true"><figure><img src="/files/PgzkUVDWiEicTkWOryfz" alt="" width="561"><figcaption></figcaption></figure></div>

{% stepper %}
{% step %}

### Generate secrets and redirect

Your application must generate two separate secret values for this specific transaction before redirecting the user.

{% stepper %}
{% step %}

### Generate `state`

Generate ​`state`​​ for CSRF protection by creating a cryptographically secure random string (at least 32 characters). Store this value in the user's session on your server to validate upon their return.
{% endstep %}

{% step %}

### Generate the `code_verifier` for PKCE

The PKCE security model is built on a secret/proof pair, the ​`code_verifier`​ and the ​`code_challenge`​​, that your application must generate for each authorization attempt. The ​`code_verifier`​ is a cryptographically secure random string that your application creates and keeps secret. The ​`code_challenge`​​ is its public proof, created by generating a one-way hash of the verifier, using the SHA-256 algorithm.\
​\
First, send the public code\_challenge and the method ​`(code_challenge_method='S256')`​ to the `​/authorize​` endpoint. This tells the impact.com server to remember the ​*fingerprint*​ of your secret. Then, after receiving the `authorization_code`, send the ​`code`​ to the `​/token`​ endpoint along with the original, secret ​`code_verifier`​​.\
Our server will then hash the verifier you just sent and check if it matches the ​`code_challenge`​​ from the first step. This final check proves that the application redeeming the code is the same that initiated the flow, securely preventing authorization code interception attacks. Always generate a new ​`code_verifier`​ and ​`code_challenge`​ for every call to the `​/authorize`​​ endpoint.\
Now you can generate the ​`code_verifier`​​ for PKCE. Create another high-entropy cryptographic random string between 43 and 128 characters.​
{% endstep %}

{% step %}

### Generate the ​`code_challenge`

Hash the ​code\_verifier​​ using SHA256, then Base64url-encode the result:\
​ ​​`code_challenge = BASE64URL-ENCODE(SHA256(code_verifier))​​`.
{% endstep %}

{% step %}

### Redirect

Redirect the user's browser to the impact.com authorization endpoint.\
`​​https://app.impact.com/oauth2/authorize​​`

| Required parameters​          | ​Description​                                                                   |
| ----------------------------- | ------------------------------------------------------------------------------- |
| ​​​`response_type`​​​         | ​Must be ​code​​.​                                                              |
| ​​​`client_id`​​​             | ​Your application's unique ​client Id​​.​                                       |
| ​​​`redirect_uri`​​​          | ​Your pre-registered redirect URI.​                                             |
| ​​​`scope`​​​                 | ​A space-separated list of permissions, which must include ​offline\_access​​.​ |
| ​​​`state`​​​                 | ​The CSRF token you generated.​                                                 |
| ​​​`code_challenge`​​​        | ​The PKCE challenge you generated.​                                             |
| ​​​`code_challenge_method`​​​ | ​Must be ​S256​​.                                                               |

```
https://app.impact.com/oauth2/authorize?
response_type=code&
client_id=...&
redirect_uri=...&
scope=...&
state=a1b2c3...&
code_challenge=E9Mel...&
code_challenge_method=S256
```

{% endstep %}
{% endstepper %}
{% endstep %}

{% step %}

### Handle the callback and validate the state

Once you've completed authorization, impact.com will redirect the user to your ​`redirect_uri`​ with an ​`authorization_code`​ and ​`state`​​.

{% hint style="danger" %}
**Critical security step**:​ Your server must validate the request by comparing the ​`state`​​ parameter in the URL with the value stored in the user's session. If these values don't match, abort the process immediately.
{% endhint %}
{% endstep %}

{% step %}

### Use the authorization code to get tokens

In this step, submit a ​POST​ request to ​`https://app.impact.com/oauth2/token`​ that includes both the ​`code`​ and the ​`code_verifier`​​ generated earlier.\
​\
Request body (`​​application/x-www-form-urlencoded`​​):

| Required parameters​  | ​Description​                                                |
| --------------------- | ------------------------------------------------------------ |
| ​​​`grant_type`​​​    | ​Must be ​authorization\_code​​.​                            |
| ​​​`code`​​​          | ​The ​code​ from ​Step 2​​.​                                 |
| ​​​`redirect_uri`​​​  | ​The same ​`redirect_uri`​ used in ​Step 1​​.​               |
| ​​​`client_id`​​​     | ​Your application's ​client Id​​.​                           |
| ​​​`client_secret`​​​ | ​Your application's ​client secret​​.​                       |
| ​​​`code_verifier`​​​ | ​The original secret ​code\_verifier​ string from ​Step 1​​. |

Example ​`curl`​​ request:

```
curl --location 'https://app.impact.com/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'code=aBcDeF123456789...' \
--data-urlencode 'redirect_uri=https://yourapp.com/callback' \
--data-urlencode 'client_id=YOUR_CLIENT_ID' \
--data-urlencode 'client_secret=YOUR_CLIENT_SECRET' \
--data-urlencode 'code_verifier=YOUR_ORIGINAL_RANDOM_STRING_FROM_STEP_1'
```

Success response (JSON):

```
{
  "access_token": "eyJz93a...",
  "token_type": "Bearer",
  "expires_in": 300,
  "refresh_token": "GEbRxBN...",
  "scope": "profile offline_access"
}
```

Securely store the ​refresh\_token​ in your database. ​`client_secret`​ and ​`refresh_token`​​s must be encrypted at rest in the user's database.
{% endstep %}

{% step %}

### Get a new access token

When an ​`access_token`​ expires, use the stored ​`refresh_token`​​ to get a new one. ​

Example ​curl​​ request:

```
curl -X POST 'https://app.impact.com/oauth2/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=refresh_token' \
-d 'refresh_token=xxx' \
-d 'client_id=OpenAI-OAuth2-Impact-prod' \
-d 'client_secret=xxx'
```

Success Response (JSON):

```
{
  "access_token": "NEW_eyJz93a...",
  "token_type": "Bearer",
  "expires_in": 300,
  "refresh_token": "NEW_GEbRxBN...",
  "scope": "profile offline_access"
}
```

Your refresh token comes with a 90-day sliding expiration window, to ensure a balance of security and convenience. Each time you successfully use your refresh token to get a new access token, you will also be issued a brand new refresh token, and the 90-day expiration timer will reset.\
​\
The refresh token will expire if it is not used for a period of 90 consecutive days. In this case, the user will need to re-authenticate through the full OAuth login flow to get a new token.

{% hint style="warning" %}
​**Important**:​ You will receive a new ​`access_token`​ and a new ​`refresh_token`​​. You must replace the old ​`refresh_token`​​ in your database with the new one.
{% endhint %}

**Error Handling:**\
​\
If your request to get a new access token from the `/token` endpoint fails with an ​`invalid_grant​​` error, your refresh token is no longer valid. This can happen if:​

* The user has explicitly revoked your application's access from their impact.com account settings.
* The token has been revoked for security reasons.
* The token has not been used for over 90 days and has expired.

Your application must handle the ​`invalid_grant`​​ error gracefully. The correct procedure is to:

1. Securely delete the invalid ​`refresh_token`​​ from your database.
2. Prompt the user to re-authenticate through the full OAuth flow, starting from ​Step 1​​, to establish a new connection.
   {% endstep %}

{% step %}

### Make authenticated API calls

Once you have an ​`access_token`​​, you can make calls to the impact.com API on behalf of the user. To do so, you must include the token in the ​*authorization*​ header of your HTTP request, using the ​*Bearer*​​ scheme.\
​\
Example API call using curl:

```
curl 
    --location 'https://api.impact.com/v1/some-endpoint' 
    --header 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'
```

It's important to handle API responses correctly. If you receive a 401 Unauthorized error, it typically means your ​`access_token`​ has expired, and you should use your ​`refresh_token`​​, as described in ​*Step 4*​​, to get a new token before retrying the API call.
{% endstep %}
{% endstepper %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://integrations.impact.com/rest-apis/wip-not-used-yet/authenticate/set-up-oauth-2.0.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
