May 5, 2026 · Migration Guide

DocuSign OAuth 2.0 Migration Guide: JWT, Auth Code Grant, and a Simpler Alternative

DocuSign is deprecating legacy authentication. If you're using the X-DocuSign-Authentication header, you need to migrate to OAuth 2.0. Here's how — or why you might want to switch to something simpler.

Michael Beckett
Michael Beckett

Founder, Signbee

TL;DR

DocuSign legacy auth is being deprecated. You need to migrate to either JWT Grant (server-to-server) or Authorization Code Grant (user-present). Migration takes 4-8 hours. If you're considering this as an opportunity to re-evaluate, Signbee's single-endpoint API uses Bearer token auth and takes 30 minutes to integrate.

What's changing

DocuSign is deprecating the X-DocuSign-Authentication header that many older integrations use. This header sent credentials (username, password, integrator key) in plain text with every request — a security risk that OAuth 2.0 eliminates.

BeforeAfter
X-DocuSign-Authentication headerOAuth 2.0 Bearer token
Credentials in every requestShort-lived access tokens (1 hour)
No scopingGranular permission scopes
No token refreshRefresh token flow required

Choose your OAuth flow

Server-to-server (no user present)→ JWT Grant
Web app (user logs in)→ Authorization Code Grant
Mobile app→ Authorization Code Grant + PKCE
Just want it simpleSwitch to Bearer token API

JWT Grant flow (server-to-server)

Use this when your backend sends documents without a user clicking "authorize." This is the most common flow for SaaS integrations.

Step 1: Create a JWT
const jwt = require('jsonwebtoken');

const now = Math.floor(Date.now() / 1000);
const token = jwt.sign(
  {
    iss: YOUR_INTEGRATION_KEY,
    sub: YOUR_USER_ID,  // GUID from DocuSign Admin
    aud: "account-d.docusign.com",  // or account.docusign.com for prod
    iat: now,
    exp: now + 3600,
    scope: "signature impersonation",
  },
  YOUR_RSA_PRIVATE_KEY,
  { algorithm: "RS256" }
);
Step 2: Exchange JWT for access token
const res = await fetch("https://account-d.docusign.com/oauth/token", {
  method: "POST",
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
  body: new URLSearchParams({
    grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
    assertion: token,
  }),
});

const { access_token, expires_in } = await res.json();
// access_token is valid for 1 hour
// You MUST refresh before expiry
Step 3: Use the access token
// Replace the old X-DocuSign-Authentication header:
// ❌ OLD: "X-DocuSign-Authentication": JSON.stringify({...})
// ✅ NEW:
const res = await fetch(`https://${baseUri}/restapi/v2.1/accounts/${accountId}/envelopes`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${access_token}`,
  },
  body: JSON.stringify(envelopeDefinition),
});

Common migration errors

AUTHORIZATION_INVALID_TOKEN

Your RSA private key is malformed. Ensure it includes the full -----BEGIN RSA PRIVATE KEY----- header/footer and has no extra whitespace. Common when copying from environment variables.

consent_required

The user hasn't granted consent to your integration. Navigate the user to: https://account-d.docusign.com/oauth/auth?response_type=code&scope=signature+impersonation&client_id=YOUR_KEY&redirect_uri=YOUR_URI

invalid_grant

Either the JWT is expired (check exp claim), the user ID is wrong (use the GUID, not email), or you're hitting the wrong environment (account-d vs account).

The simpler alternative

If you're spending 4-8 hours migrating DocuSign auth, it's worth asking: do you need DocuSign specifically? If your use case is sending documents for signature via API, simpler alternatives exist:

Signbee — Bearer token, no OAuth, 30 minutes
// No JWT. No RSA keys. No consent flow. No token refresh.
const res = await fetch("https://signb.ee/api/v1/send", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "Bearer YOUR_API_KEY",  // That's it.
  },
  body: JSON.stringify({
    markdown: "# Your Document\n\nContent here...",
    recipient_name: "Jane Smith",
    recipient_email: "jane@example.com",
  }),
});

Frequently Asked Questions

Why is DocuSign migrating to OAuth 2.0?

Legacy auth sent credentials in plain text with every request. OAuth 2.0 uses short-lived tokens, granular scopes, and follows industry security standards.

How long does migration take?

4-8 hours for experienced developers. Main steps: create integration key, generate RSA keys, configure redirect URIs, replace auth headers, implement token refresh, and test.

Is there an alternative that doesn't require OAuth?

Yes — Signbee, SignWell, and BoldSign use simple API key / Bearer token auth. No OAuth flow, no JWT, no RSA keys. Signbee integrates in about 30 minutes.

Skip the OAuth migration — Bearer token, 30 minutes, $0.50/doc.

Last updated: May 5, 2026 · Michael Beckett is the founder of Signbee and B2bee Ltd.

Related resources