> You are reading the Docusign Developer Documentation. For clean Markdown of any page, append .md to the page URL.
>
> Documentation indexes by section:
> - APIs and SDKs: https://docusign.docs.buildwithfern.com/docs/llms.txt
> - Platform 101: https://docusign.docs.buildwithfern.com/platform/llms.txt
> - Extension Apps: https://docusign.docs.buildwithfern.com/extension-apps/llms.txt
> - Docusign CLI: https://docusign.docs.buildwithfern.com/docusign-cli/llms.txt
>
> Authentication (OAuth, JWT Grant, M2M): https://docusign.docs.buildwithfern.com/platform/auth
> Webhooks and Connect: https://docusign.docs.buildwithfern.com/platform/webhooks
>
> OpenAPI specifications: https://docusign.docs.buildwithfern.com/openapi.json
> MCP server: https://docusign.docs.buildwithfern.com/_mcp/server

# How to request a signature through your CORS-enabled browser app

> Learn how to collect signatures directly within your browser app using JavaScript through your Cross-Origin Resource Sharing (CORS) app.

This topic demonstrates how to collect signatures directly within your browser app using JavaScript, without emailing the signer or directing them to an external URL,

through your [Cross-Origin Resource Sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/) (CORS) app within your developer account.

CORS is a technology standard that allows restricted resources such as scripts, forms, or external web pages to be requested from a domain that's different from the server originating the request. Access to each resource requested via CORS is controlled by CORS access policies set on the server hosting that resource.

CORS enables you to build browser-based applications that can directly call the Docusign eSignature REST API. Your app can use React, Vue, or other browser-based frameworks, or just JavaScript. With CORS, no back-end server is needed.

## Prerequisites

To send CORS requests:

* Since the sender needs Docusign credentials to call the eSignature REST API, the sender needs their own login to the Docusign service. If the sender will also be signing the envelope, or if the signer is physically present with the sender, then this example is applicable.

  If the signer does not have a Docusign login, then a back-end service (using JWT authentication) should create an access token and use it to call the eSignature REST API.
* The system administrator for the application’s integration key (client ID) must enable the application to use CORS from the origin(s) the application will be loaded from. For example, if the application’s URL is `https://apps.mycompany.com/docusign`, the origin  `https://apps.mycompany.com` must be enabled for CORS. See [Enable or disable CORS for specific apps](/platform/single-page-applications-cors/enable-disable-cors#update-app-specific-cors-settings) for details.
* The account administrator for every user of your application must also enable CORS access by your application. While the default is to enable CORS access, your users’ administrators can change the default. For instance, suppose your application has 20 users scattered across four companies and five individual eSignature accounts (one of the companies has multiple accounts). In this scenario, five different account administrators must enable CORS access by your application or leave the default setting to **CORS enabled by default for all new apps**. See [Requirements for an app to use CORS](/platform/single-page-applications-cors#requirements-for-an-app-to-use-cors) for details.

## Required data

Running the code in this how-to requires this data:

| Data element           | Description                                                                                                                                                                                                                                                                                                            |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| \{API_ACCOUNT_ID}      | A [GUID](http://guid.one/) value that identifies your account. This value is automatically generated by Docusign for any account you create. Copy the value from the **API Account ID** field on the [Apps and Keys](https://admindemo.docusign.com/authenticate?goTo=appsAndKeys) page.                               |
| \{BASE_PATH}           | A string value that forms the root of the URL required to make API calls. The base path value in the example code is set to target the developer environment at https\://\<domain>/restapi Where \<domain> is demo.docusign.net for the developer environment and is the result of the GetUserInfo call in production. |
| \{CLIENT_USER_ID}      | A string value that serves as an identifier of an individual signer throughout the signing process. The combination of this value, the signer's name, and the signer's email is used to uniquely identify them.                                                                                                        |
| Documents to be signed | You must provide at least one document to be signed. Document used in this how-to:- [PDF file](https://docusign.github.io/examples/docs/anchorfields.pdf)                                                                                                                                                              |
| Redirect URI           | A URL to which the user will be forwarded after authentication. The value for this URL must exactly match one of those pre-registered for the [integration key](/platform/configure-app#integration-key) in your Docusign account. See [redirect URI](/platform/configure-app#redirect-uri) for details.               |
| Return URL             | A URL to which the user will be forwarded after signing is complete.                                                                                                                                                                                                                                                   |
| \{SIGNER_EMAIL}        | A string value for the email address where the signer will receive a notification of the signing request.                                                                                                                                                                                                              |
| \{SIGNER_NAME}         | A string value for the full name of the signer.                                                                                                                                                                                                                                                                        |

## Step 1. Obtain your OAuth token

To make the API calls shown in this how-to, you need a valid OAuth access token.

CORS-enabled apps should use OAuth Authorization Code Grant, without a secret, with [Proof Key for Code Exchange (PKCE)](/platform/auth/authcode#public-authorization-code-grant) to obtain an access token. A special `cors` [scope](/platform/auth/reference/scopes) is required along with `signature` when generating your OAuth token request.

**`JavaScript`**

```javascript title="JavaScript"
class ImplicitGrant {
  constructor(args) {
    this.oAuthServiceProvider = oAuthServiceProvider;
    this.implicitGrantPath = implicitGrantPath;
    this.oAuthClientID = oAuthClientID;
    this.oAuthScopes = oAuthScopes;
    this.oAuthReturnUrl = oAuthReturnUrl;
    this.workingUpdateF = args.workingUpdateF || null;

    // public variables
    this.working = false;
    this.accessToken = null;
    this.accessTokenExpires = null;
    this.errMsg = null;

    // internal
    this._loginWindow = null;
    this._nonce = null;
  }

/*
 * Start the login process in a new browser tab
 */
async login() {
    this.working = true;
    this.errMsg = null;
    if (this.workingUpdateF) {
        this.workingUpdateF(this.working);
    }

    // Get a random nonce to use with OAuth call
    // See https://oauth.net/articles/authentication/#access-token-injection
    // Using https://www.random.org/clients/http/
    this._nonce = Date.now(); // default nonce
    this._nonce = (await this.randomNonce()) || this._nonce;
    const url =
      `${this.oAuthServiceProvider}${this.implicitGrantPath}` +
      `?response_type=token` +
      `&scope=${this.oAuthScopes}` +
      `&client_id=${this.oAuthClientID}` +
      `&redirect_uri=${this.oAuthReturnUrl}` +
      `&state=${this._nonce}`;
    this._loginWindow = window.open(url, "_blank");
    const newTab = this._loginWindow;
    if (!newTab || newTab.closed || typeof newTab.closed=='undefined') {
        // POPUP BLOCKED
        alert ("Please enable the popup login window.")
    }
    this._loginWindow.focus();
}
```

## Step 2. Construct the request body

Construct the request body by defining a method named `createEnvelope` that creates the envelope definition. The `createEnvelope` method demonstrates how to:

* Create a new, signable PDF document in code
* Attach your document to the envelope
* Set signer data
* Create and assign a `SignHere` tab to the signer

Define the `createEnvelope` method with this code.

**`JavaScript`**

```javascript title="JavaScript"
const signer = {
name: {SIGNER_NAME},
email: {SIGNER_EMAIL} ,
clientUserId: 1000
};
const envelopeId = await createEnvelope(signer);

async function createEnvelope({ name, email, clientUserId }) {
const docB64 = await data.callApi.getDocB64(docUrl); // fetch a document

const req = {
  emailSubject: "Please sign the attached document",
  status: "sent",
  documents: [
    {
      name: "Example document",
      documentBase64: docB64,
      fileExtension: "pdf",
      documentId: "1",
    }
  ],
  recipients: {
    signers: [
      {
        email: email,
        name: name,
        clientUserId: clientUserId,
        customFields: ["field1: value 1", "field2: value 2"],
        recipientId: "1",
        tabs: {
          signHereTabs: [
            {
              anchorString: "/sig1/",
              anchorXOffset: "20",
              anchorUnits: "pixels"
            }
          ],
          checkboxTabs: [
            {
              anchorString: "/sig1/",
              anchorXOffset: "180",
              anchorUnits: "pixels",
              tabLabel: "checkbox 1",
              tabGroupLabels: ["checkbox group"]
            },
            {
              anchorString: "/sig1/",
              anchorXOffset: "180",
              anchorYOffset: "20",
              anchorUnits: "pixels",
              tabLabel: "checkbox 2",
              tabGroupLabels: ["checkbox group"]
            }
          ],
          tabGroups: [
            {
              groupLabel: "checkbox group",
              groupRule: "SelectExactly",
              minimumRequired: "1",
              maximumAllowed: "1",
              validationMessage:
                "Please check one option",
              tabScope: "document",
              pageNumber: "1",
              documentId: "1"
            }
          ],
          textTabs: [
            {
              anchorString: "/sig1/",
              anchorXOffset: "195",
              anchorUnits: "pixels",
              value: "I agree with license 1",
              locked: "true",
              font: "Helvetica",
              fontSize: "Size12",
              bold: "true"
            },
            {
              anchorString: "/sig1/",
              anchorXOffset: "195",
              anchorYOffset: "20",
              anchorUnits: "pixels",
              value: "I agree with license 2",
              locked: "true",
              font: "Helvetica",
              fontSize: "Size12",
              bold: "true"
            },
            {
              anchorString: "/sig1/",
              anchorXOffset: "20",
              anchorYOffset: "50",
              anchorUnits: "pixels",
              bold: "true",
              font: "Helvetica",
              fontSize: "Size14",
              fontColor: "NavyBlue",
              value:
                "Addendum\n‣ Item 1\n‣ Item 2\nThis is a multi-line read-only text field"
            }
          ]
        }
      }
    ]
  }
};
```

## Step 3. Call the eSignature REST API to create the envelope

Now that you have constructed your API headers and request body, you can

make a POST request to the [Envelopes:create](/docs/esign-rest-api/reference/envelopes/envelopes/create) method and include the request body to send

an embedded envelope using CORS.

Here’s how you make the call, but make sure to substitute your API account ID for \{ACCOUNT_ID}

. Save the envelope ID to use in the next step.

**`JavaScript`**

```javascript title="JavaScript"
   const apiMethod = `/accounts/{ACCOUNT_ID}/envelopes`;
        const httpMethod = "POST";
        const results = await data.callApi.callApiJson({
            apiMethod: apiMethod,
            httpMethod: httpMethod,
            req: req
        });
        if (results === false) {
            errMsg(data.callApi.errMsg);
            return false;
        }

        return results.envelopeId;
    }
```

## Step 4. Call the eSignature REST API to initiate the embedded signing request

Next, create the recipient view. Use the [EnvelopeViews:createRecipient](/docs/esign-rest-api/reference/envelopes/envelopeviews/createrecipient) method, passing in your API account ID and the `envelopeId` and `viewRequest` objects generated in previous steps.

Finally, extract the URL for embedded signing, which is the value of the `Url` key from the JSON response. You can redirect your app's internal browser to this URL to begin signing.

**`JavaScript`**

```javascript title="JavaScript"
async function embeddedSigningCeremony({ envelopeId, signer }) {
    const req = {
        returnUrl: dsReturnUrl,
        authenticationMethod: "None",
        clientUserId: signer.clientUserId,
        email: signer.email,
        userName: signer.name
    };
    // Make the API call
    const apiMethod = `/accounts/{ACCOUNT_ID}/envelopes/${envelopeId}/views/recipient`;
    const httpMethod = "POST";
    const results = await data.callApi.callApiJson({
        apiMethod: apiMethod,
        httpMethod: httpMethod,
        req: req
    });
    if (results === false) {
        errMsg(data.callApi.errMsg);
        return false;
    }
    msg(`Displaying signing ceremony...`);
    signingCeremonyWindow = window.open(results.url, "_blank");
    if(!signingCeremonyWindow || signingCeremonyWindow.closed ||
       typeof signingCeremonyWindow.closed=='undefined') {
        // popup blocked
        alert ("Please enable the popup window signing ceremony");
    }
    signingCeremonyWindow.focus();
    return true;
}
```

## Expected response

You should see a JSON response similar to the code shown.

After signing is complete, the recipient receives a carbon copy (CC) of the email that includes all of the completed and signed documents.

**`Sample response`**

```javascript title="Sample response"
{
  "url": "https://demo.docusign.net/Signing/MTRedeem/v1/54984548-xxxx-xxxx-xxxx-cd0772818bbf?slt=eyJ0eX...m87j8w"
}
```

## Next steps

* See

  [How to request a signature by email using CORS](/docs/esign-rest-api/how-to/request-signature-email-browser-cors)

  .
* See [How to get an access token using Public Authorization Code Grant](/platform/auth/public-authcode-get-token).
* Learn more about [Single-page applications and CORS](/platform/single-page-applications-cors).