> ## Documentation Index
> Fetch the complete documentation index at: https://docs.iinkedsign.com/llms.txt
> Use this file to discover all available pages before exploring further.

# OAuth 2.0

Get started integrating your OAuth App with iinked Sign via our OAuth 2.0 authorization code flow.

## Requesting your client ID and secret

The first step is to request a client id and secret for one of our sandbox instances so that you can get started. We require that you provide one or more redirect URL(s) for the authorization redirect callback to your application.

[**Complete Request Form (iinked Sign)**](https://sign.syngrafii.com/form/D-qcgcvtTEqAJhJm9w47jQ)

<Tip>
  You can request multiple redirect URLs to be whitelisted. HTTPS is required.

  **Redirect URL Examples**

  If you would like to use Postman's built in OAuth 2.0 authorization during development:
  [https://oauth.pstmn.io/v1/callback](https://oauth.pstmn.io/v1/callback) (default)

  It is also common to include localhost during development:
  [https://localhost/auth/syngrafii](https://localhost/auth/syngrafii) (example)

  Once you have your client id and secret, you can contact [support@syngrafi.com](mailto:support@syngrafi.com) directly to open a ticket and request any additional changes.
</Tip>

## Authorization code flow

iinked Sign provides an OAuth 2.0 authorization code flow [**(RFC 6749, Section 4.1)**](https://datatracker.ietf.org/doc/html/rfc6749#section-4.1) with optional PKCE support.

### Authorizing your application

Direct your user to the `connect/authorize` URL with the following query parameters:

```http Authorize URL theme={null}
https://sandbox.syngrafii.com/connect/authorize
```

<ParamField query="response_type" type="string" required>
  Use `code` as a response type.
</ParamField>

<ParamField query="client_id" type="string" required>
  Your OAuth App client id.
</ParamField>

<ParamField query="redirect_uri" type="string" required>
  One of the redirect URLs you provided when requesting your OAuth App client id and secret. Contact [support@syngrafii.com](mailto:support@syngrafii.com) if you need to modify your redirect URL(s).
</ParamField>

<ParamField query="scope" type="string">
  For most integrations request `profile offline_access organization`. If you support OpenID Connect include `openid` to also receive an `id_token` (for example: `profile openid offline_access organization`).
</ParamField>

<ParamField query="state" type="string">
  A value returned with the callback to help maintain state between the request and callback and to help prevent CSRF attacks. (optional)
</ParamField>

<ParamField query="nonce" type="string">
  When using OpenID Connect, provide a nonce to help prevent replay attacks. (optional)
</ParamField>

<ParamField query="prompt" type="string">
  Prompt options to influence the authorization user experience. See values below.

  <Expandable title="values">
    | Value   | Description                                                                                 |
    | ------- | ------------------------------------------------------------------------------------------- |
    | consent | Require the user to consent to the requested scopes even if they have previously consented. |
    | login   | Require the user to login again even if they are already authenticated.                     |
  </Expandable>
</ParamField>

<ParamField query="code_challenge" type="string">
  (Required when using PKCE) Code challenge value.
</ParamField>

<ParamField query="code_challenge_method" type="string">
  (Required when using PKCE) Code challenge method (for example: `S256`).
</ParamField>

```http Authorize URL Example theme={null}
https://sandbox.syngrafii.com/connect/authorize?client_id=my-client-id&redirect_uri=https%3A%2F%2Flocalhost%3A44319%2Fauth%2Fsyngrafii&response_type=code&scope=profile%20openid%20offline_access%20organization
```

The user will then be prompted to authorize access for your application, once they have authorized the access, they will be redirected back to your application using the provided redirect\_uri query parameter.

If the user had previously authorized your application, they will automatically be redirected back to your application.

### Retrieving tokens

The callback to your application will contain a code query parameter and state query parameter if one was provided with the original request. You must use this code to retrieve your tokens by making a POST request to the connect/token endpoint.

```http POST theme={null}
Authorization: Basic {base64(client_id:client_secret)}
Content-Type: application/x-www-form-urlencoded
https://sandbox.syngrafii.com/connect/token
```

<Tip>
  client\_id:client\_secret must be Base64 Encoded
</Tip>

<ParamField body="grant_type" type="string" required>
  Use `authorization_code` as the grant type.
</ParamField>

<ParamField body="code" type="string" required>
  The authorization `code` returned to your callback. Use this to exchange for tokens.
</ParamField>

<ParamField body="client_id" type="string">
  (Only required if the Authorization header is not provided) Your client\_id.
</ParamField>

<ParamField body="client_secret" type="string">
  (Only required if the Authorization header is not provided) Your client\_secret.
</ParamField>

```json Response theme={null}
{
  "access_token": "XXXX…",
  "refresh_token": "YYYY…",
  "id_token": "ZZZZ…",
  "token_type": "Bearer",
  "expires_in": 1800,
  "scope": "profile openid offline_access organization"
}
```

<ParamField name="access_token" type="string">
  Can be used to call the iinked Sign API as the user. This token has a short lifetime (see `expires_in`).
</ParamField>

<ParamField name="refresh_token" type="string">
  Can be used to request a new `access_token`. The refresh token has a long lifetime and will be renewed with each request. Requires the `offline_access` scope.
</ParamField>

<ParamField name="id_token" type="string">
  A JWT that contains the user's profile claims. Returned when `openid` scope is requested.
</ParamField>

### Using an access token

You can now make requests to the iinked Sign API by adding the access token to Authorization header as a Bearer token.

<Note>
  iinked Sign access tokens are obtained through the OAuth 2.0 authorization process.
</Note>

**Request Header**

```http theme={null}
Authorization: Bearer <TOKEN>
```

### Refreshing an access token

The access token has a short lifetime and must be refreshed by making another POST request to the connect/token endpoint and passing the refresh token.

```http POST theme={null}
Authorization: Basic {base64(client_id:client_secret)}
Content-Type: application/x-www-form-urlencoded
https://sandbox.syngrafii.com/connect/token
```

<Tip>
  client\_id:client\_secret must be Base64 Encoded
</Tip>

| Request Parameter | Description                                                                     |
| ----------------- | ------------------------------------------------------------------------------- |
| grant\_type       | Use **refresh\_token** as grant type.                                           |
| refresh\_token    | Use the **refresh\_token** returned from the last call.                         |
| client\_id        | (Only if **Authorization** header is **not** provided) Your **client\_id.**     |
| client\_secret    | (Only if **Authorization** header is **not** provided) Your **client\_secret.** |

**Single Use Refresh Tokens**

iinked Sign has implemented single use Refresh Tokens. When refreshing the access token, a new refresh token will be returned along with the access token. It is important to replace the previous refresh token with the new one as they will expire 60 seconds after they have been redeemed. This 60 second leeway helps reduce any concurrency issues within your application that may result in using the current refresh token at the same time.

**Rolling Refresh Tokens**

When a new refresh token is returned, its lifetime will be also be renewed. Therefore, reauthorization will only be required when applications have not been used for several months.

## Implementation

### Common workflow

<Steps titleSize="h4">
  <Step title="Authorize your application">
    <ul>
      <li>Store refresh token</li>
      <li>Cache access token</li>
      <li>Set event notification callback <code>api/v1/events/endpoints/set</code> (if required)</li>
      <li>Sync organization and members <code>api/v1/organizations/info</code> (if required)</li>
    </ul>
  </Step>

  <Step title="Get Access Token">
    <ul>
      <li>Get from cache</li>

      <li>
        If expired / not cached

        <ul>
          <li>Get new tokens using refresh token</li>
          <li>Store new refresh token</li>
          <li>Cache new access token</li>
        </ul>
      </li>
    </ul>
  </Step>

  <Step title="Call api/v1/packages/add">
    Call <code>api/v1/packages/add</code> to add a package.

    See the [Packages add API](/v4/api/packages/add) for more information.
  </Step>
</Steps>

### Mapping event notifications

If you set an event notification callback endpoint for the organization, you will be notified as packages progress through their signing workflows. To map those events to a specific package you will need to store the organizationId, memberId, and packageId returned from the **api/v1/packages/add** API call.

See the [Webhooks setup guide](/v4/webhooks/setup) for more information.

## OAuth configuration

| OAuth Endpoints    | sandbox.syngrafii.com used for examples                                                                                                                     |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Authority (OpenID) | `https://sandbox.syngrafii.com`<br />`https://sandbox.syngrafii.com/.well-known/openid-configuration`<br />`https://sandbox.syngrafii.com/.well-known/jwks` |
| Authorize          | `https://sandbox.syngrafii.com/connect/authorize`                                                                                                           |
| Token              | `https://sandbox.syngrafii.com/connect/token`                                                                                                               |
| Revoke             | `https://sandbox.syngrafii.com/connect/revoke`                                                                                                              |
| User Info          | `https://sandbox.syngrafii.com/connect/userinfo`                                                                                                            |

#### Response types

| Response Type | Description             |
| ------------- | ----------------------- |
| code          | Authorization Code Flow |

#### Scopes

| Scope           | Description                                                                                                                                                                                                                                                    |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| profile         | Request access to user's profile.                                                                                                                                                                                                                              |
| openid          | Request that an id\_token is returned containing the user's profile.                                                                                                                                                                                           |
| offline\_access | Request that a refresh\_token is returned that can be stored and used to request new access tokens.                                                                                                                                                            |
| organization    | Request access to the organization. Can access profiles and add packages for all organization members. Can also set a callback URL to receive event notifications from the organization. User must be an Organization Administrator to authorize this request. |
| member          | Request access to the organization member. Can only add packages for this member.                                                                                                                                                                              |

#### Claims

| Claim                                  | Source / Description                                 |
| -------------------------------------- | ---------------------------------------------------- |
| id\_token or connect/userinfo endpoint | Returned from id\_token or connect/userinfo endpoint |
| sub                                    | Subject                                              |
| email                                  | Email address                                        |
| given\_name                            | Given name                                           |
| family\_name                           | Family name                                          |
| s:organization                         | Organization ID                                      |
| s:member                               | Member ID                                            |
