> 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 send an envelope to an In Person Signer

> This topic demonstrates how to host an In Person Signing session with embedded signing.

This topic demonstrates how to host an [In Person Signing](https://support.docusign.com/s/document-item?rsc_301\&bundleId=gav1643676262430\&topicId=hak1578456316043.html) session with embedded signing. In Person Signing allows a host to facilitate a Docusign session for a signer who is physically in the same location as them.

> **Note**
>
> Run this code example from our [Quickstart](/docs/esign-rest-api/quickstart) or launcher projects: [Bash](https://github.com/docusign/code-examples-bash), [C#](https://github.com/docusign/code-examples-csharp), [Java](https://github.com/docusign/code-examples-java), [Node.js](https://github.com/docusign/code-examples-node), [PHP](https://github.com/docusign/code-examples-php), [PowerShell](https://github.com/docusign/code-examples-powershell), [Python](https://github.com/docusign/code-examples-python), or [Ruby](https://github.com/docusign/code-examples-ruby).

## 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. |
| Document to be signed    | You must provide at least one document to be signed. Document used in this how-to:- [PDF file](https://github.com/docusign/code-examples-java/blob/master/src/main/resources/World_Wide_Corp_lorem.pdf)                                                                                                                |
| \{HOST_EMAIL}            | A string value for the email address associated with the account which will host an In Person Signer. This value must exactly match (case-sensitive) the value shown in the host’s [account profile](https://admindemo.docusign.com/authenticate?goTo=accountProfile).                                                 |
| \{HOST_NAME}             | A string value for the name associated with the account which will host an In Person Signer. This value must exactly match (case-sensitive) the value shown in the host’s [account profile](https://admindemo.docusign.com/authenticate?goTo=accountProfile).                                                          |
| \{IN_PERSON_SIGNER_NAME} | A string value for the full name of the signer.                                                                                                                                                                                                                                                                        |
| \{RECIPIENT_ID}          | A unique string value that you assign to identify each recipient. This value assigns tabs on a per-[recipient](/docs/esign-rest-api/esign101/concepts/recipients) basis.                                                                                                                                               |
| Return URL               | A URL to which the user will be forwarded after signing is complete.                                                                                                                                                                                                                                                   |

## Step 1. Obtain your OAuth token

To make the API calls shown in this how-to, you need a valid OAuth access token. Docusign supports access tokens for three different recommended OAuth grant types: Public Authorization Code Grant, Confidential Authorization Code Grant, and JSON Web Token (JWT) Grant. Choose the OAuth grant type appropriate for your scenario.

> **Note**
>
> See [Confidential Authorization Code Grant](/platform/auth/authcode#confidential-authorization-code-grant) for guidance on your options to get an Confidential Authorization Code Grant  OAuth token.

![Three icons that represent the three methods a user can use to obtain an OAuth token: JSON Web Token (JWT), Public Authorization Code Grant (ACG), and Confidential Authorization Code grant](/_fern-files/_img/64f473773042ee439449a096bf7673292b1585b86a4ccc55f82ba0dda41f61a1.webp)

## Step 2. Construct the envelope definition

Next, create your envelope definition. Add a document to the definition by saving it to a variable as a binary-encoded Base64 string. Then add an [In Person Signer recipient](/docs/esign-rest-api/reference/envelopes/enveloperecipients#in-person-signer-recipient) to the envelope. In Person Signing requires that a Docusign account holder act as the host. Set the `hostName` and `hostEmail` fields to the name and email address associated with the host’s Docusign account. Set the `signerName` field to the legal name of the In Person Signer. Then add a `signHereTab` to the recipient and set the envelope’s status to `sent`.

**`Bash`**

```bash title="Bash"
printf \
'{
    "emailSubject": "Please host this in-person signing session",
    "documents": [
        {
            "documentBase64": "' > $request_data
            cat $doc1_base64 >> $request_data
            printf '",
            "name": "Lorem Ipsum",
            "fileExtension": "pdf",
            "documentId": "1"
        }
    ],
    "recipients": {
        "inPersonSigners": [
            {
                "hostEmail": "'"${HOST_EMAIL}"'",
                "hostName": "'"${HOST_NAME}"'",
                "signerName": "'"${IN_PERSON_SIGNER_NAME}"'",
                "recipientId": "1",
                "routingOrder": "1",
                "tabs": {
                    "signHereTabs": [
                        {
                            "anchorString": "/sn1/",
                            "anchorUnits": "pixels",
                            "anchorXOffset": "20",
                            "anchorYOffset": "10"
                        }
                    ]
                }
            }
        ]
    },
    "status": "sent"
}' >> $request_data
```

**`C#`**

```csharp title="C#"
private static EnvelopeDefinition PrepareEnvelope(string hostEmail, string hostName, string signerName, string docPdf)
{
    byte[] fileContentInBytes = System.IO.File.ReadAllBytes(docPdf);

    EnvelopeDefinition envelopeDefinition = new EnvelopeDefinition
    {
        EmailSubject = "Please host this in-person signing session",
        Documents = new List<Document>
        {
            new Document
            {
                DocumentBase64 = Convert.ToBase64String(fileContentInBytes),
                Name = "Lorem Ipsum",
                FileExtension = "pdf",
                DocumentId = "1",
            },
        },
    };

    InPersonSigner inPersonSigner = new InPersonSigner
    {
        HostEmail = hostEmail,
        HostName = hostName,
        SignerName = signerName,
        RecipientId = "1",
        RoutingOrder = "1",
        Tabs = new Tabs
        {
            SignHereTabs = new List<SignHere>
            {
                new SignHere
                {
                    AnchorString = "/sn1/",
                    AnchorUnits = "pixels",
                    AnchorXOffset = "20",
                    AnchorYOffset = "10",
                },
            },
        },
    };

    envelopeDefinition.Recipients = new Recipients
    {
        InPersonSigners = new List<InPersonSigner>
        {
            inPersonSigner,
        },
    };

    envelopeDefinition.Status = "sent";

    return envelopeDefinition;
}
```

**`Java`**

```java title="Java"
public static EnvelopeDefinition makeEnvelope(
        String hostEmail,
        String hostName,
        String signerName,
        Integer anchorOffsetY,
        Integer anchorOffsetX,
        String documentFileName,
        String documentName) throws IOException {
    InPersonSigner inPersonSigner = new InPersonSigner();

    inPersonSigner.setHostEmail(hostEmail);
    inPersonSigner.setHostName(hostName);
    inPersonSigner.setSignerName(signerName);
    inPersonSigner.setRecipientId("1");
    inPersonSigner.setRoutingOrder("1");
    inPersonSigner.setTabs(EnvelopeHelpers.createSingleSignerTab("/sn1/", anchorOffsetY, anchorOffsetX));

    Recipients recipients = new Recipients();
    recipients.setInPersonSigners(Collections.singletonList(inPersonSigner));

    EnvelopeDefinition envelopeDefinition = new EnvelopeDefinition();
    envelopeDefinition.setEmailSubject("Please host this in-person signing session");
    envelopeDefinition.setRecipients(recipients);

    Document document = EnvelopeHelpers.createDocumentFromFile(documentFileName, documentName, "1");
    envelopeDefinition.setDocuments(Collections.singletonList(document));
    envelopeDefinition.setStatus(EnvelopeHelpers.ENVELOPE_STATUS_SENT);

    return envelopeDefinition;
}
```

**`Node.js`**

```javascript title="Node.js"
function makeEnvelope(args) {
  // document 1 (pdf) has tag /sn1/
  //
  // The envelope has one recipients.
  // recipient 1 - inPersonSigner

  // read file from a local directory
  // The read could raise an exception if the file is not available!
  const docPdfBytes = fs.readFileSync(args.docFile);

  // create the envelope definition
  let env = new docusign.EnvelopeDefinition();
  env.emailSubject = 'Please sign this document';

  // add the documents
  let doc1 = new docusign.Document();
    let doc1b64 = Buffer.from(docPdfBytes).toString('base64');
  doc1.documentBase64 = doc1b64;
  doc1.name = 'Lorem Ipsum'; // can be different from actual file name
  doc1.fileExtension = 'pdf';
  doc1.documentId = '1';

  // The order in the docs array determines the order in the envelope
  env.documents = [doc1];

  // Create a inPersonSigner recipient to sign the document, identified by host name and email and signer name
  // We're setting the parameters via the object creation
  const inPersonSigner = docusign.InPersonSigner.constructFromObject({
    hostEmail: args.hostEmail,
    hostName: args.hostName,
    signerName: args.signerName,
    recipientId: 1,
    routingOrder: 1,
  });

  // Create signHere fields (also known as tabs) on the documents,
  // We're using anchor (autoPlace) positioning
  //
  // The DocuSign platform seaches throughout your envelope's
  // documents for matching anchor strings.
  const signHere = docusign.SignHere.constructFromObject({
    anchorString: '/sn1/',
    anchorYOffset: '10',
    anchorUnits: 'pixels',
    anchorXOffset: '20',
  });
  // Tabs are set per recipient / signer
  const signerTabs = docusign.Tabs.constructFromObject({
    signHereTabs: [signHere],
  });
  inPersonSigner.tabs = signerTabs;

  // Add the recipient to the envelope object
  const recipients = docusign.Recipients.constructFromObject({
    inPersonSigners: [inPersonSigner],
  });
  env.recipients = recipients;

  // Request that the envelope be sent by setting |status| to "sent".
  // To request that the envelope be created as a draft, set to "created"
  env.status = 'sent';

  return env;
}
```

**`PHP`**

```php title="PHP"
private static function _prepareEnvelope(string $hostName, string $demoPath): EnvelopeDefinition
{
    $file_content_in_bytes = file_get_contents($demoPath . $GLOBALS['DS_CONFIG']['doc_pdf']);
    $document = new Document(
        [
            'document_base64' => base64_encode($file_content_in_bytes),
            'name' => 'Lorem Ipsum',
            'file_extension' => 'pdf',
            'document_id' => '1'
        ]
    );

    $inPersonSigner = new InPersonSigner(
        [
            'host_email' => $GLOBALS['DS_CONFIG']['signer_email'],
            'host_name' => $GLOBALS['DS_CONFIG']['signer_name'],
            'signer_name' => $hostName,
            'recipient_id' => "1",
            'routing_order' => "1"
        ]
    );

    $sign_here = new SignHere(
        [
            'anchor_string' => '/sn1/',
            'anchor_units' => 'pixels',
            'anchor_y_offset' => '10',
            'anchor_x_offset' => '20'
        ]
    );

    $inPersonSigner->settabs(new Tabs(['sign_here_tabs' => [$sign_here]]));

    return new EnvelopeDefinition(
        [
            'email_subject' => "Please host this in-person signing session",
            'documents' => [$document],
            'recipients' => new Recipients(['in_person_signers' => [$inPersonSigner]]),
            'status' => "sent"
        ]
    );
}
```

**`PowerShell`**

```text title="PowerShell"
@{
    emailSubject = "Please sign this document set";
    documents    = @(
        @{
            documentBase64 = "$(Get-Content $docBase64)";
            name           = "Lorem Ipsum";
            fileExtension  = "pdf";
            documentId     = "1";
        };
    );
    recipients   = @{
        inPersonSigners = @(
            @{
                hostEmail    = $hostEmail;
                hostName     = $hostName;
                signerName   = $signerName;
                recipientId  = "1";
                routingOrder = "1";
                tabs         = @{
                    signHereTabs = @(
                        @{
                            anchorString  = "/sn1/";
                            anchorUnits   = "pixels";
                            anchorXOffset = "20";
                            anchorYOffset = "10";
                        };
                    );
                };
            };
        );
    };
    status       = "sent";
} | ConvertTo-Json -Depth 32 > $requestData
```

**`Python`**

```python title="Python"
def make_envelope(cls, args):
    """
    Creates envelope
    args -- parameters for the envelope:
    signer_email, signer_name, signer_client_id
    returns an envelope definition
    """

    # document 1 (pdf) has tag /sn1/
    #
    # The envelope has one recipient.
    # recipient 1 - signer
    with open(path.join(demo_docs_path, DS_CONFIG["doc_pdf"]), "rb") as file:
        content_bytes = file.read()
    base64_file_content = base64.b64encode(content_bytes).decode("ascii")

    # Create the document model
    document = Document(  # create the DocuSign document object
        document_base64=base64_file_content,
        name="Example document",  # can be different from actual file name
        file_extension="pdf",  # many different document types are accepted
        document_id=1  # a label used to reference the doc
    )

    # Create the in person signer recipient model
    signer = InPersonSigner(
        # The signer
        host_name = args["host_name"],
        host_email = args["host_email"],
        signer_name = args["signer_name"],
        recipient_id="1",
        routing_order="1",

    )

    # Create a sign_here tab (field on the document)
    sign_here = SignHere(
        # DocuSign SignHere field/tab
        anchor_string="/sn1/",
        anchor_units="pixels",
        anchor_y_offset="10",
        anchor_x_offset="20"
    )

    # Add the tabs model (including the sign_here tab) to the signer
    # The Tabs object wants arrays of the different field/tab types
    InPersonSigner.tabs = Tabs(sign_here_tabs=[sign_here])

    # Next, create the top level envelope definition and populate it.
    envelope_definition = EnvelopeDefinition(
        email_subject="Please host this in-person signing session",
        documents=[document],
        # The Recipients object wants arrays for each recipient type
        recipients=Recipients(in_person_signers=[signer]),
        status="sent"  # requests that the envelope be created and sent.
    )

    return envelope_definition
```

**`Ruby`**

```ruby title="Ruby"
def make_envelope(pdf_filename, host_email, host_name, signer_name)
  envelope_definition = DocuSign_eSign::EnvelopeDefinition.new
  envelope_definition.email_subject = 'Please sign this document sent from Ruby SDK'

  doc1 = DocuSign_eSign::Document.new
  doc1.document_base64 = Base64.encode64(File.binread(pdf_filename))
  doc1.name = 'Lorem Ipsum'
  doc1.file_extension = 'pdf'
  doc1.document_id = '1'

  # The order in the docs array determines the order in the envelope
  envelope_definition.documents = [doc1]
  # Create an in person signer recipient to sign the document
  # We're setting the parameters via the object creation

  in_person_signer = DocuSign_eSign::InPersonSigner.new
  in_person_signer.host_email = host_email
  in_person_signer.host_name = host_name
  in_person_signer.signer_name = signer_name
  in_person_signer.recipient_id = '1'
  in_person_signer.routing_order = '1'

  # The Docusign platform searches throughout your envelope's documents for matching
  # anchor strings.
  sign_here = DocuSign_eSign::SignHere.new
  sign_here.anchor_string = '/sn1/'
  sign_here.anchor_units = 'pixels'
  sign_here.anchor_x_offset = '20'
  sign_here.anchor_y_offset = '10'
  # Tabs are set per recipient/signer
  tabs = DocuSign_eSign::Tabs.new
  tabs.sign_here_tabs = [sign_here]
  in_person_signer.tabs = tabs
  # Add the recipients to the envelope object
  recipients = DocuSign_eSign::Recipients.new
  recipients.in_person_signers = [in_person_signer]

  envelope_definition.recipients = recipients
  # Request that the envelope be sent by setting status to "sent".
  # To request that the envelope be created as a draft, set status to "created"
  envelope_definition.status = 'sent'
  envelope_definition
end
```

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

Now that you have constructed your API headers and request body, make a POST request to the [Envelopes:create](/docs/esign-rest-api/reference/envelopes/envelopes/create) endpoint and include the request body to create the envelope. Save the envelope ID to use later on when creating the recipient view.

**`Bash`**

```bash title="Bash"
curl --header "Authorization: Bearer ${ACCESS_TOKEN}" \
     --header "Content-Type: application/json" \
     --data-binary @${request_data} \
     --request POST ${base_path}/v2.1/accounts/${account_id}/envelopes \
     --output ${response}

echo ""
echo "Response:" `cat $response`
echo ""

# pull out the envelopeId
envelope_id=`cat $response | grep envelopeId | sed 's/.*\"envelopeId\":\"//' | sed 's/\",.*//'`
echo "EnvelopeId: ${envelope_id}"
```

**`C#`**

```csharp title="C#"
var docuSignClient = new DocuSignClient(basePath);
docuSignClient.Configuration.DefaultHeader.Add("Authorization", "Bearer " + accessToken);

EnvelopesApi envelopesApi = new EnvelopesApi(docuSignClient);

var envelopeSummary = envelopesApi.CreateEnvelopeWithHttpInfo(accountId, envelopeDefinition);
envelopeSummary.Headers.TryGetValue("X-RateLimit-Remaining", out string remaining);
envelopeSummary.Headers.TryGetValue("X-RateLimit-Reset", out string reset);

if (reset != null && remaining != null)
{
    DateTime resetDate = DateTimeOffset.FromUnixTimeSeconds(long.Parse(reset)).UtcDateTime;
    Console.WriteLine("API calls remaining: " + remaining);
    Console.WriteLine("Next Reset: " + resetDate);
}
```

**`Java`**

```java title="Java"
ApiClient apiClient = createApiClient(basePath, accessToken);
EnvelopesApi envelopesApi = new EnvelopesApi(apiClient);

var envelopeSummary = envelopesApi.createEnvelopeWithHttpInfo(
        accountId,
        envelope,
        envelopesApi.new CreateEnvelopeOptions());
Map<String, List<String>> headers = envelopeSummary.getHeaders();
java.util.List<String> remaining = headers.get("X-RateLimit-Remaining");
List<String> reset = headers.get("X-RateLimit-Reset");

if (remaining != null & reset != null) {
    Instant resetInstant = Instant.ofEpochSecond(Long.parseLong(reset.get(0)));
    System.out.println("API calls remaining: " + remaining);
    System.out.println("Next Reset: " + resetInstant);
}
```

**`Node.js`**

```javascript title="Node.js"
const dsApiClient = new docusign.ApiClient();
dsApiClient.setBasePath(args.basePath);
dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken);
const envelopesApi = new docusign.EnvelopesApi(dsApiClient);

// Make the envelope request body
const envelope = makeEnvelope(args.envelopeArgs);

// Call Envelopes::create API method
// Exceptions will be caught by the calling function
let results = await envelopesApi.createEnvelope(args.accountId, {
  envelopeDefinition: envelope,
}, (error, data, response) => {
    const headers = response?.headers;

    const remaining = headers?.['x-ratelimit-remaining'];
    const reset = headers?.['x-ratelimit-reset'];

    if (remaining && reset) {
      const resetInstant = new Date(Number(reset) * 1000);

      console.log(`API calls remaining: ${remaining}`);
      console.log(`Next Reset: ${resetInstant.toISOString()}`);
    }
});

const envelopeId = results.data.envelopeId;
```

**`PHP`**

```php title="PHP"
$envelopeDefinition = InPersonSigningService::_prepareEnvelope($hostName, $demoPath);
$envelopeApi = $clientService->getEnvelopeApi();

try {
    $envelopeSummary = $envelopeApi->createEnvelopeWithHttpInfo($accountId, $envelopeDefinition);

    $remaining = $envelopeSummary[2]['X-RateLimit-Remaining'] ?? null;
    $reset = $envelopeSummary[2]['X-RateLimit-Reset'] ?? null;

    if ($remaining !== null && $reset !== null) {
        $resetInstant = (new DateTime())->setTimestamp((int)$reset);
        error_log("API calls remaining: $remaining");
        error_log("Next Reset: " . $resetInstant->format(\DateTime::ATOM));
    }
} catch (ApiException $e) {
    $clientService->showErrorTemplate($e);
    exit;
}
```

**`PowerShell`**

```text title="PowerShell"
Invoke-RestMethod `
    -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
    -Method 'POST' `
    -Headers @{
    'Authorization' = "Bearer $accessToken";
    'Content-Type'  = "application/json";
} `
    -InFile (Resolve-Path $requestData).Path `
    -OutFile $response

Write-Output "Response: $(Get-Content -Raw $response)"

# pull out the envelopeId
$envelopeId = $(Get-Content $response | ConvertFrom-Json).envelopeId
Write-Output "EnvelopeId: $envelopeId"
```

**`Python`**

```python title="Python"
envelope_args = args["envelope_args"]
# Create the envelope request object
envelope_definition = cls.make_envelope(envelope_args)

# Call Envelopes::create API method
# Exceptions will be caught by the calling function
api_client = create_api_client(base_path=args["base_path"], access_token=args["access_token"])

envelope_api = EnvelopesApi(api_client)
(results, status, headers) = envelope_api.create_envelope_with_http_info(account_id=args["account_id"], envelope_definition=envelope_definition)

remaining = headers.get("X-RateLimit-Remaining")
reset = headers.get("X-RateLimit-Reset")

if remaining is not None and reset is not None:
    reset_date = dt.fromtimestamp(int(reset), tz=timezone.utc)
    print(f"API calls remaining: {remaining}")
    print(f"Next Reset: {reset_date}")

envelope_id = results.envelope_id
```

**`Ruby`**

```ruby title="Ruby"
envelope_api = create_envelope_api(args)

results, _status, headers = envelope_api.create_envelope_with_http_info args[:account_id], envelope

remaining = headers['X-RateLimit-Remaining']
reset = headers['X-RateLimit-Reset']

if remaining && reset
  reset_date = Time.at(reset.to_i).utc
  puts "API calls remaining: #{remaining}"
  puts "Next Reset: #{reset_date}"
end
```

## Step 4. Create the recipient view definition

The recipient view is the screen that Docusign generates and displays in your app to enable embedded signing. The accompanying code demonstrates how to write the request body for your recipient view. Set the `returnUrl` to the URL where your users will be sent after signing is complete and use the host’s name and email address for the `userName` and `email` fields. You will not be able to initiate embedded signing if these fields do not have the same value as the `hostName` and `hostEmail` fields from the envelope definition in Step 3.

**`Bash`**

```bash title="Bash"
printf \
'{
    "returnUrl": "http://httpbin.org/get",
    "authenticationMethod": "none",
    "email": "'"${HOST_EMAIL}"'",
    "userName": "'"${HOST_NAME}"'"
}' >> $request_data
```

**`C#`**

```csharp title="C#"
private static RecipientViewRequest MakeRecipientViewRequest(
    string hostEmail,
    string hostName,
    string returnUrl,
    string pingUrl = null)
{
    var recipientViewRequest = new RecipientViewRequest
    {
        ReturnUrl = returnUrl + "?state=123",
        AuthenticationMethod = "none",
        Email = hostEmail,
        UserName = hostName,
    };

    if (pingUrl != null)
    {
        recipientViewRequest.PingFrequency = "600";
        recipientViewRequest.PingUrl = pingUrl;
    }

    return recipientViewRequest;
}
```

**`Java`**

```java title="Java"
public static RecipientViewRequest makeRecipientViewRequest(
        String hostEmail,
        String hostName,
        DSConfiguration config) {
    String stateValue = "?state=123";
    String authenticationMethod = "none";
    String pingFrequency = "600";

    RecipientViewRequest viewRequest = new RecipientViewRequest();

    viewRequest.setReturnUrl(config.getDsReturnUrl() + stateValue);
    viewRequest.setAuthenticationMethod(authenticationMethod);
    viewRequest.setEmail(hostEmail);
    viewRequest.setUserName(hostName);
    viewRequest.setPingFrequency(pingFrequency);
    viewRequest.setPingUrl(config.getDsPingUrl());

    return viewRequest;
}
```

**`Node.js`**

```javascript title="Node.js"
function makeRecipientViewRequest(args) {
  let viewRequest = new docusign.RecipientViewRequest();

  // Set the url where you want the recipient to go once they are done signing
  // should typically be a callback route somewhere in your app.
  // The query parameter is included as an example of how
  // to save/recover state information during the redirect to
  // the DocuSign signing. It's usually better to use
  // the session mechanism of your web framework. Query parameters
  // can be changed/spoofed very easily.
  viewRequest.returnUrl = args.dsReturnUrl + '?state=123';

  // How has your app authenticated the user? In addition to your app's
  // authentication, you can include authenticate steps from DocuSign.
  // Eg, SMS authentication
  viewRequest.authenticationMethod = 'none';

  // Recipient information must match embedded recipient info
  // we used to create the envelope.
  viewRequest.email = args.hostEmail;
  viewRequest.userName = args.hostName;

  // DocuSign recommends that you redirect to DocuSign for the
  // embedded signing. There are multiple ways to save state.
  // To maintain your application's session, use the pingUrl
  // parameter. It causes the DocuSign signing web page
  // (not the DocuSign server) to send pings via AJAX to your
  // app,
  viewRequest.pingFrequency = 600; // seconds
  // NOTE: The pings will only be sent if the pingUrl is an https address
  viewRequest.pingUrl = args.dsPingUrl; // optional setting

  return viewRequest;
}
```

**`PHP`**

```php title="PHP"
public function getRecipientViewRequest($authentication_method, $envelope_args): RecipientViewRequest
{
    return new RecipientViewRequest(
        [
            'authentication_method' => $authentication_method,
            'client_user_id' => $envelope_args['signer_client_id'],
            'recipient_id' => '1',
            'return_url' => $envelope_args['ds_return_url'],
            'user_name' => $envelope_args['signer_name'],
            'email' => $envelope_args['signer_email']
        ]
    );
}
```

**`PowerShell`**

```text title="PowerShell"
$json = [ordered]@{
    'returnUrl'            = 'http://httpbin.org/get';
    'authenticationMethod' = 'none';
    'email'                = $hostEmail;
    'userName'             = $hostName;
} | ConvertTo-Json -Compress
```

**`Python`**

```python title="Python"
recipient_view_request = RecipientViewRequest(
    authentication_method=authentication_method,
    recipient_id="1",
    return_url=envelope_args["ds_return_url"],
    user_name=envelope_args["host_name"],
    email=envelope_args["host_email"]
)
```

**`Ruby`**

```ruby title="Ruby"
def make_recipient_view_request(ds_return_url, ds_ping_url, host_email, host_name)
  view_request = DocuSign_eSign::RecipientViewRequest.new
  # Set the URL where you want the recipient to go once they are done signing
  # should typically be a callback route somewhere in your app.
  # The query parameter is included as an example of how
  # to save/recover state information during the redirect to
  # the Docusign signing. It's usually better to use
  # the session mechanism of your web framework. Query parameters
  # can be changed/spoofed very easily.
  view_request.return_url = "#{ds_return_url}?state=123"

  # How has your app authenticated the user? In addition to your app's
  # authentication, you can include authenticate steps from Docusign;
  # e.g., SMS authentication
  view_request.authentication_method = 'none'

  # Recipient information must match the embedded recipient info
  # that was used to create the envelope
  view_request.email = host_email
  view_request.user_name = host_name

  # Docusign recommends that you redirect to Docusign for the embedded signing. There are
  # multiple ways to save state. To maintain your application's session, use the pingUrl
  # parameter. It causes the Docusign signing web page (not the Docusign server)
  # to send pings via AJAX to your app
  view_request.ping_frequency = '600' # seconds
  # NOTE: The pings will only be sent if the pingUrl is an HTTPS address
  view_request.ping_url = ds_ping_url # Optional setting

  view_request
end
```

## Step 5. Call the eSignature REST API to create the recipient view

Next, call the [EnvelopeViews:createRecipient](/docs/esign-rest-api/reference/envelopes/envelopeviews/createrecipient) method, passing in your API account ID, envelope ID, and request body generated in previous steps.

Finally, extract the URL for the embedded signing ceremony, 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.

> **Note**
>
> View the source code for this how-to on GitHub: [Bash](https://github.com/docusign/code-examples-bash/blob/master/examples/eSignature/eg039InPersonSigning.sh), [C#](https://github.com/docusign/code-examples-csharp/blob/master/launcher-csharp/eSignature/Examples/InPersonSigning.cs), [Java](https://github.com/docusign/code-examples-java/blob/master/src/main/java/com/docusign/controller/eSignature/services/InPersonSigningService.java), [Node.js](https://github.com/docusign/code-examples-node/blob/master/lib/eSignature/examples/signingInPerson.js), [PHP](https://github.com/docusign/code-examples-php/blob/master/src/Services/Examples/eSignature/InPersonSigningService.php), [PowerShell](https://github.com/docusign/code-examples-powershell/blob/master/examples/eSignature/eg039SigningInPerson.ps1), [Python](https://github.com/docusign/code-examples-python/blob/master/app/eSignature/examples/eg039_in_person_signer.py),  or [Ruby](https://github.com/docusign/code-examples-ruby/blob/master/app/services/e_sign/eg039_signing_in_person_service.rb).

**`Bash`**

```bash title="Bash"
Status=$(curl --header "Authorization: Bearer ${ACCESS_TOKEN}" \
     --header "Content-Type: application/json" \
     --data-binary @${request_data} \
     --request POST ${base_path}/v2.1/accounts/${account_id}/envelopes/${envelope_id}/views/recipient \
     --output ${response})

if [[ "$Status" -gt "201" ]] ; then
    echo ""
	echo "Signing request failed."
	echo ""
	cat $response
	exit 0
fi

signing_url=`cat $response | grep url | sed 's/.*\"url\":\"//' | sed 's/\".*//'`
```

**`C#`**

```csharp title="C#"
RecipientViewRequest viewRequest = MakeRecipientViewRequest(hostEmail, hostName, returnUrl, pingUrl);
var viewUrl = envelopesApi.CreateRecipientViewWithHttpInfo(accountId, envelopeSummary.Data.EnvelopeId, viewRequest);
viewUrl.Headers.TryGetValue("X-RateLimit-Remaining", out remaining);
viewUrl.Headers.TryGetValue("X-RateLimit-Reset", out reset);

if (reset != null && remaining != null)
{
    DateTime resetDate = DateTimeOffset.FromUnixTimeSeconds(long.Parse(reset)).UtcDateTime;
    Console.WriteLine("API calls remaining: " + remaining);
    Console.WriteLine("Next Reset: " + resetDate);
}
```

**`Java`**

```java title="Java"
RecipientViewRequest viewRequest = InPersonSigningService.makeRecipientViewRequest(hostEmail, hostName, config);
```

**`Node.js`**

```javascript title="Node.js"
const viewRequest = makeRecipientViewRequest(args.envelopeArgs);
// Call the CreateRecipientView API
// Exceptions will be caught by the calling function
results = await envelopesApi.createRecipientView(args.accountId, envelopeId, {
  recipientViewRequest: viewRequest,
}, (error, data, response) => {
    const headers = response?.headers;

    const remaining = headers?.['x-ratelimit-remaining'];
    const reset = headers?.['x-ratelimit-reset'];

    if (remaining && reset) {
      const resetInstant = new Date(Number(reset) * 1000);

      console.log(`API calls remaining: ${remaining}`);
      console.log(`Next Reset: ${resetInstant.toISOString()}`);
    }
});
```

**`PHP`**

```php title="PHP"
$authentication_method = 'None';

$envelopeArguments = [
    'signer_email' => $GLOBALS['DS_CONFIG']['signer_email'],
    'signer_name' => $GLOBALS['DS_CONFIG']['signer_name'],
    'ds_return_url' => $GLOBALS['app_url'] . 'index.php?page=ds_return'
];

$recipientViewRequest = $clientService->getRecipientViewRequest(
    $authentication_method,
    $envelopeArguments
);

$viewUrl = $clientService->getRecipientView($accountId, $envelopeSummary[0]->getEnvelopeId(), $recipientViewRequest);
```

**`PowerShell`**

```text title="PowerShell"
Invoke-RestMethod `
    -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes/${envelopeId}/views/recipient" `
    -Method 'POST' `
    -Headers @{
    'Authorization' = "Bearer $accessToken";
    'Content-Type'  = "application/json";
} `
    -Body $json `
    -OutFile $response

Write-Output "Response: $(Get-Content -Raw $response)"
$signingUrl = $(Get-Content $response | ConvertFrom-Json).url
```

**`Python`**

```python title="Python"
(results, status, headers) = envelope_api.create_recipient_view_with_http_info(
    account_id=args["account_id"],
    envelope_id=envelope_id,
    recipient_view_request=recipient_view_request
)

remaining = headers.get("X-RateLimit-Remaining")
reset = headers.get("X-RateLimit-Reset")

if remaining is not None and reset is not None:
    reset_date = dt.fromtimestamp(int(reset), tz=timezone.utc)
    print(f"API calls remaining: {remaining}")
    print(f"Next Reset: {reset_date}")

return {"envelope_id": envelope_id, "redirect_url": results.url}
```

**`Ruby`**

```ruby title="Ruby"
view_request = make_recipient_view_request(ds_return_url, ds_ping_url, host_email, host_name)

# Call the CreateRecipientView API
results, _status, headers = envelope_api.create_recipient_view_with_http_info args[:account_id], envelope_id, view_request

remaining = headers['X-RateLimit-Remaining']
reset = headers['X-RateLimit-Reset']

if remaining && reset
  reset_date = Time.at(reset.to_i).utc
  puts "API calls remaining: #{remaining}"
  puts "Next Reset: #{reset_date}"
end
```

## Expected response

The host will be directed to the screen asking them to host the In-Person Signing session. After choosing **START**, they can hand the device to the in person signer to sign the document. Then the host can complete the signing session per the listed steps.

![In-person signing session directions. 1: Pass control of session to host signer. 2. Signer enters any authentication information. 3. Help signer sign and provide the document. 4. Take control of the session. 5. Log in to Docusign account to finish session.](/_fern-files/_img/8fb93108f15e539cbab9d25141556843ba818b866979232110b744e026c824e2.webp)

## Next steps

* Run this code example from our [Quickstart](/docs/esign-rest-api/quickstart) or launcher projects:    [Bash](https://github.com/docusign/code-examples-bash), [C#](https://github.com/docusign/code-examples-csharp), [Java](https://github.com/docusign/code-examples-java), [Node.js](https://github.com/docusign/code-examples-node), [PHP](https://github.com/docusign/code-examples-php), [PowerShell](https://github.com/docusign/code-examples-powershell), [Python](https://github.com/docusign/code-examples-python), or [Ruby](https://github.com/docusign/code-examples-ruby).
* Learn more about [embedded signing](/docs/esign-rest-api/esign101/concepts/embedding).
* See how to [Go-Live](/docs/esign-rest-api/go-live) with a completed app and find the base path for API calls in the production environment.