Skip to navigation

How to get an access token with JWT Grant

View as Markdown

This topic demonstrates how to generate an access token manually using JSON Web Token (JWT) Grant authentication.

Note: Instead of generating the access token manually, you can also implement JWT Grant authentication by:

  • Using code from Quickstart and modifying it to meet your app’s needs. Quickstart provides a JWT Grant remote signing example project that demonstrates how to implement JWT Grant authentication that is personalized with your account settings and in your choice of programming language.
  • Using methods from one of the SDKs.

For context around what JWT Grant authentication is, when you should use it, and its advantages and disadvantages, see JSON Web Token (JWT) Grant.

Walkthrough video

You can also see a walkthrough video of how to get an access token using JWT Grant.

Prerequisites

To obtain an access token with JWT Grant, you must meet the following prerequisites.

Data elementDescription
You have defined an integration key.An integration key identifies your integration and links to its configuration values. Create an integration key.
You have defined a redirect URI for your integration key.The redirect URI is the URI (URL) to which Docusign will redirect the browser after authentication. Set a redirect URI.
Your application has an RSA key pair.Add the RSA key pair.

Note: You can define a maximum of 5 RSA key pairs. If you have already defined 5 key pairs, you must delete one of them before creating a new one.

Before you can make any API calls using JWT Grant, you must get your user’s consent for your app to impersonate them.

To get this consent, open the accompanying Sample URI in your embedded browser, replacing the value of client_id with your integration key.

Your user will be prompted to sign in to their account and give consent for your app to impersonate them. After your user grants permission, your app will be able to use the OAuth JWT Grant flow to impersonate them and make API calls. A set of query parameters will be returned to the redirect URI; in the JWT flow, these parameters (such as code) are not used.

Note: After selecting Accept, the user’s browser will display a message saying that it can’t load the page. You can safely ignore this page and close the tab.

The constructed URI for obtaining application consent contains five parts:

  • A base path for the authentication service. This path differs depending on whether your app is in the developer environment or in production.

    • For the developer environment, the base URI is https://account-d.docusign.com/oauth/auth
    • For the production environment, the base URI is https://account.docusign.com/oauth/auth
  • Your application’s integration key.

  • A Base64URL-encoded redirect URI that matches one of those configured for the application with the specified integration key.

  • A space-delimited list of the scopes your app needs. For JWT, this should include the impersonation scope.

  • A response_type value of code.

The accompanying URI syntax and Sample URI show how these values map to the sections of the URI.

You only need to get consent from a user for a given set of scopes once. In subsequent authentication workflows, you can skip this step unless you are requesting a different set of scopes or authenticating a different user.

See How to obtain individual consent for details.

Note: This example’s request for consent requires that your app is set as a User Application (this is the default setting for new apps). Otherwise, you will receive an error.

https://account-d.docusign.com/oauth/auth?
response_type=code
&scope=YOUR_REQUESTED_SCOPES
&client_id=YOUR_INTEGRATION_KEY
&redirect_uri=YOUR_REDIRECT_URI
JWT Grant: Docusign permission request dialog box

Step 2. Create a JWT

To authenticate in the JWT Grant flow, you will need to create a JWT containing data on the authentication request, then exchange it for an access token.

A Docusign JWT contains three JSON blocks that are encoded and separated by period characters. You will need three pieces of information to create a JWT for authenticating a user:

  • Consent from the user or the administrator of their organization (obtained in Step 1)

  • Integration key (also called the client ID)

  • User ID, you can find your User ID on the Apps and Keys page.

    Note: Although this information is required to create a JWT, it is not necessarily encoded within the created JWT.

You can create a sample JWT by using an online JWT tool like jwt.io and adding the following fields for the header, body, and signature sections, or Build a JWT with AI, supplying your own integration key, user ID, and example RSA key.

Tools like jwt.io should only be used for used for initial tests. Use a function like requestJWTUserToken in the Docusign SDKs (or a similar variant depending on the language) to implement JWT creation programmatically for your full implementation.

Header:

{
"alg": "RS256",
"typ": "JWT"
}

Body:

{
"iss": "<your_integration_key>",
"sub": "<your_user_ID>",
"aud": "account-d.docusign.com",
"iat": <current_unix_epoch_time>,
"exp": <current_unix_epoch_time+6000>,
"scope": "signature impersonation"
}

Signature:

RSASHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(body),
"<your_private_RSA_key>"
)

The JSON body of the JWT should look similar to the sample JWT. See JWT structure and properties for details.

Note: You can find your User ID and Integration Key on the Apps and Keys page. You can find or add the RSA key pair.

{
"alg": "RS256",
"typ": "JWT"
}

The header, shown here, specifies the type of the token and algorithm used for encoding it. For a Docusign service integration, the header structure should always have a type of JWT and use RS256 as its algorithm.

JWT header

BODY

The body contains the data for the claims that your application is making. Each Docusign JWT contains the following set of claims, as shown.

ClaimDescription
issThe integration key (also known as client ID) of the application.
subThe User ID of the user to be impersonated. (The person granting permission must have a Docusign user account.)
The provided User ID must be in GUID (not email) format. You can look up a user’s GUID from their email using the Users:list
method.
Note: If you don’t already have the User ID of the user to act on behalf of, you can obtain it by completing the Request the authorization code
step of Authorization Code Grant.
iatThe date-time when the JWT was issued, in Unix epoch

format. You must include an iat value when creating a JWT, typically set to the current time.
expThe date-time when the JWT assertion will expire, in Unix epoch

format. Defaults to one hour from the value of iat. You must include an exp value when creating a JWT.
audThe URI of the authentication service instance to be used.
  • For developer environments, use
    account-d.docusign.com
  • For production environments, use
    account.docusign.com
Important: Do not include https:// in the aud value!
scopeThe scopes to request.
JWT body

SIGNATURE

This is a digital signature that enables Docusign to verify that the JWT was created by your application and has not been modified since it was created. The first two parts of the JWT are signed with your application’s private key (using the RSA SHA-256 digital signature algorithm) as shown in the diagram.

JWT signature

Step 3. Obtain the access token

To request an access token, send a POST request containing the JWT to the Docusign authentication service.

  • For the developer environment, the URI is https://account-d.docusign.com/oauth/token
  • For the production environment, the URI is https://account.docusign.com/oauth/token

The response to a successful request will include your access token value.

The request contains the following parameters.

ParameterDescription
grant_typeMust be urn:ietf:params:oauth:grant-type:jwt-bearer.
assertionThe encoded value of the JWT that you created in Step 2.

If successful, an access token will be returned in the response body.

The access token contains the following fields.

NameDescription
access_tokenThe value of the access token. This value will be added to the Authorization header of all Docusign API calls.
token_typeThe type of token. For access tokens, the value of this will be Bearer.
expires_inThe number of seconds before the access token expires. When your access token expires, your application should generate a new JWT with your credentials and request a new access token.

Otherwise, the operation may return one of the following errors.

Response code and bodyDescription
400 {"error":"consent_required"}The user or administrator hasn’t granted (or has revoked) their consent to be impersonated by the app, or you have not requested a scope that is required for your operation. See How to obtain individual consent for details.
400 {"error":"invalid_grant"}The JWT was valid, but some of the claims were not. See Create a JWT for details.
curl --data "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&
assertion=YOUR_JSON_WEB_TOKEN" --request POST https://account-d.docusign.com/oauth/token

Step 4. Get your user’s base URI

To make an API call to the Docusign platform, your application needs both an access token (which you obtained in the previous step), and a base URI that is unique to the user on whose behalf your application is making the API call.

To get the base URI, call the /oauth/userinfo endpoint, supplying your application’s access token as a header.

  • For the developer environment, the URI is https://account-d.docusign.com/oauth/userinfo
  • For the production environment, the URI is https://account.docusign.com/oauth/userinfo

The request must contain an Authorization header that holds your access token.

NameDescription
AuthorizationContains the word Bearer and the access token that you received in the previous step.

If successful, this returns a set of data for each user who has granted consent and the account(s) that user is a member of, as shown by the Sample response.

You will need the account_id and the base_uri claims of the user that your application is acting on behalf of to make calls to a Docusign API.

Docusign enforces hourly limits on the number of /oauth/userinfo requests per user ID and per integration key. See User info endpoint limits for details.

GET https://account-d.docusign.com/oauth/userinfo
Authorization: Bearer YOUR_ACCESS_TOKEN

Step 5. Use the access token to make an API call

Now that you’ve obtained an access token and the user info, your application is authenticated and has all of the information that it needs to make a call to a Docusign API. To make an eSignature REST API request, you must include:

  • The acquired access token in the request’s Authorization header.
  • The base URI for the request, built from the account_id and the base_uri of the user account.

For example, the syntax to call AccountBrands:list to return details about all of the brands associated with an account is: GET restapi/v2.1/accounts/{accountId}/brands

Substituting the base URI of https://demo.docusign.net and API Account ID of 18b4799a-xxxx-xxxx-xxxx-b5b4b8a97604, the request path would be: GET https://demo.docusign.net/restapi/v2.1/accounts/18b4799a-xxxx-xxxx-xxxx-b5b4b8a97604/brands

The final piece of information needed to access the API is the access token, prefixed with Bearer and provided in the Authorization header.

Sample request
curl -- request GET https://demo.docusign.net/restapi/v2.1/accounts/18b4799a-xxxx-xxxx-xxxx-b5b4b8a97604/brands
--header "Authorization: Bearer eyJ0eX...V8KroQ"

Token expiration and best practices

The access token granted by JWT Grant expires after one hour, and no refresh token is provided. After the token expires, you must generate a new JWT and exchange it for a new access token.

You can reuse most of the old assertion, just modifying the iat and exp values and updating the signature, then submit the updated JWT to get a new access token.

Generally, apps that use JWT should get a new access token about 15 minutes before their existing one expires. This gives your system time to recover in case something goes wrong with the exchange.

JWT Grant Authentication with SDKs

Instead of getting the access token manually using JWT, you can implement JWT Grant authentication by calling specific methods within the Docusign SDKs. The SDKs provide the requestJWTUserToken and getUserInfo methods for automating JWT Grant authentication. You can see these method definitions in the ApiClient class. See the language-specific SDK authentication page for details.

SDK authentication pagerequestJWTUserToken
SDK method
getUserInfo
SDK method
ApiClient class
C# SDK authenticationRequestJWTUserTokenGetUserInfoDocusignClient.cs
Java SDK authenticationrequestJWTUserTokengetUserInfoApiClient.java
Node.js SDK authenticationsendJWTTokenRequestgetUserInfoApiClient.js
PHP SDK authenticationrequestJWTUserTokengetUserInfoApiClient.php
Python SDK authenticationrequest_jwt_user_tokenget_user_infoapi_client.py
Ruby SDK authenticationrequest_jwt_user_tokenget_user_infoapi_client.rb

The requestJWTUserToken method is passed a user’s integration key, user ID, base path, requested scopes, and their private key in byte array format. The method performs JWT Grant authentication for the specified user and returns an access token.

The getUserInfo method is passed an access token and returns the owning user’s information, including the base URI that is needed to construct the paths to make other Docusign API calls.

Troubleshoot errors

BadRequest

Indicates that one or more of the JWT fields has been entered improperly. Ensure that the epoch times specified in the JWT fields have not already passed.

Make sure that your application is attempting to connect to the correct authentication URI.

  • For the developer environment, the URI is from the https://account-d.docusign.com/oauth domain.
  • For the production environment, the URI is from the https://account.docusign.com/oauth domain.

Indicates that the user has not consented to allow your application to make calls on their behalf or you have not requested a scope that is required for the operation.

If the user has supplied consent and you are still receiving this error, there may have been something wrong with the URI being used, or you may be lacking a required scope. Double check to make sure the integration key has not been cut off and ensure that the scope is signature impersonation.

Invalid authentication request: The response type is not supported

Indicates that your application is not set to be able to securely store a client secret. The step to request individual consent requires that you set your User Application setting to Yes:

  1. Access the Apps and Keys page Open the Apps and Keys page for your developer account.
  2. Select the app to configure On the list of your apps and integration keys, find the row of the app to configure, then select EDIT from its ACTIONS context menu. This will open the configuration page for that app.
  3. Set User Application to Yes, indicating that your application can securely store a secret key.

invalid_grant: no_valid_keys_or_signatures

One of the most common ways to encounter this error is for the iat and exp timestamp values in the JWT body to be incorrect. To test this, you can update the value of iat to the current Unix epoch time and exp to that value + 4000, then run the call again.

This error can also indicate that the RSA private key used to sign the assertion is invalid (such as referencing the wrong environment or a revoked secret), that the assertion is expired, or the “issued at” time hasn’t elapsed yet.

Invalid RedirectUri

Indicates that the redirect URI specified for authentication does not match any of the redirect URIs defined for the integration key. The redirect URI strings must match exactly, including space and slash characters.

Partner Authentication Failure / Integration key disabled

Indicates that there was a problem creating the JWT with one of the Docusign SDK projects. Try creating the JWT outside of the SDK to make sure that everything has been configured correctly.

Next steps