> 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 create an envelope for offline signing (PDF)

> Learn how to create an envelope with the iOS SDK that contains a PDF file that can be used for offline signing.

This topic demonstrates how to create an [envelope](/docs/esign-rest-api/esign101/concepts/envelopes) that contains a PDF file that can be used for offline signing.

> **Note:** To sign the envelope offline, you must set the account used for authentication as either:

* the host for an [In Person Signer](https://support.docusign.com/s/document-item?rsc_301\&bundleId=gav1643676262430\&topicId=hak1578456316043.html)  or as
* a signer.

## Required data

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

| Data element              | Description                                                                                                                                                                                                                                                            |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 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_EMAIL} | A string value for the email address of the [In Person Signer](https://support.docusign.com/s/document-item?rsc_301\&bundleId=gav1643676262430\&topicId=hak1578456316043.html).                                                                                        |
| \{IN_PERSON_SIGNER_NAME}  | A string value for the name of the [In Person Signer](https://support.docusign.com/s/document-item?rsc_301\&bundleId=gav1643676262430\&topicId=hak1578456316043.html).                                                                                                 |
| \{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. Log in to Docusign

To make the API call shown in this how-to, you must be logged in to Docusign.

See [How to log in to Docusign from your app](/docs/mobile-sdks/ios-sdk/how-to/log-in) for details.

## Step 2. Create an envelope definition

To create the envelope definition:

* Create a document. This includes the document’s name, filepath, and ID.
* Create your recipients. For this envelope, create an ‘in person signer’, ’signer’, and a ‘CC’ recipient. In this example, the in person signer name and email are used for the CC recipient, so that the in person signer will receive a copy of the signed document.
* Create and assign signable fields (also known as tabs) specific to each signer within the document.
* Set the envelope definition data, including a name, subject, message, recipients, and documents.

**`Objective-C`**

```text title="Objective-C"
DSMEnvelopeTab *tabA =
[[[[[[[DSMTabBuilder builderForType:DSMTabTypeSignHere]
      addName:@"signTab"]
     addRecipientId:@"1"]
    addDocumentId:@"1"]
   addFrame:CGRectMake(75, 580, 50, 40)]
  addPageNumber:1]
 build];

DSMEnvelopeTab *tabB =
[[[[[[[DSMTabBuilder builderForType:DSMTabTypeSignHere]
      addName:@"signTab"]
     addRecipientId:@"2"]
    addDocumentId:@"1"]
   addFrame:CGRectMake(280, 645, 50, 40)]
  addPageNumber:1]
 build];

DSMEnvelopeRecipient *recipientA = [[[[[[[[[DSMRecipientBuilder builderForType:DSMRecipientTypeInPersonSigner]
                                           addRecipientId:@"1"]
                                          addRoutingOrder: 1]
                                         addHostName:@"{HOST_NAME}"]
                                        addHostEmail:@"{HOST_EMAIL}"]
                                       addSignerName: @"{IN_PERSON_SIGNER_NAME}"]
                                      addSignerEmail:@"{IN_PERSON_SIGNER_EMAIL}"]
                                     addTab:tabA]
                                    build];

DSMEnvelopeRecipient *recipientB = [[[[[[[DSMRecipientBuilder builderForType:DSMRecipientTypeSigner]
                                         addRecipientId:@"2"]
                                        addRoutingOrder: 2]
                                       addSignerName: @"SIGNER_NAME"]
                                      addSignerEmail:@"SIGNER_EMAIL"]
                                     addTab:tabB]
                                    build];

DSMEnvelopeRecipient *recipientC = [[[[[[DSMRecipientBuilder builderForType:DSMRecipientTypeCC]
                                        addRecipientId:@"3"]
                                       addRoutingOrder: 3]
                                      addSignerName: @"{IN_PERSON_SIGNER_NAME}"]
                                     addSignerEmail:@"{IN_PERSON_SIGNER_EMAIL}"]
                                    build];

NSString *fileName = @"{DOC_NAME}";
NSString *pdfFilePath = [[NSBundle bundleForClass:[self class]] pathForResource:fileName ofType:@"pdf"];
DSMEnvelopeDocument *document = [[[[[DSMDocumentBuilder builder]
                                    addName:@"doc1"]
                                   addDocumentId:@"1"]
                                  addFilePath:pdfFilePath]
                                 build];

DSMEnvelopeDefinition *envelopeDefinition = [[[[[[[DSMEnvelopeBuilder builder]
                                                  addEnvelopeName:@"Test Envelope"]
                                                 addEmailSubject:@"Test Envelope -- subject"]
                                                addEmailMessage:@"Message blurb -- \n -- there goes the docusign email message -- sent via sdk --"]
                                               addRecipients: @[recipientA, recipientB, recipientC]]
                                              addDocument:document]
                                             build];
```

**`Swift`**

```swift title="Swift"
let tabA = DSMTabBuilder.init(for: .signHere)
    .addName("signTab1")
    .addRecipientId("1")
    .addDocumentId("1")
    .addPageNumber(1)
    .addFrame(CGRect(x: 75, y: 580, width: 50, height: 40))
    .build()

let tabB = DSMTabBuilder.init(for: .signHere)
    .addName("signTab2")
    .addRecipientId("2")
    .addDocumentId("1")
    .addPageNumber(1)
    .addFrame(CGRect(x: 280, y: 645, width: 50, height: 40))
    .build()

let recipientA = DSMRecipientBuilder.init(for: .inPersonSigner)
    .addRecipientId("1")
    .addHostName("{HOST_NAME}")
    .addHostEmail("{HOST_EMAIL}")
    .addSignerName("{IN_PERSON_SIGNER_NAME}")
    .addSignerEmail("{IN_PERSON_SIGNER_EMAIL}")
    .addRoutingOrder(1)
    .add([tabA])
    .build()

let recipientB = DSMRecipientBuilder.init(for: .signer)
    .addRecipientId("2")
    .addRoutingOrder(2)
    .addSignerName("{SIGNER_NAME}")
    .addSignerEmail("{SIGNER_EMAIL}")
    .add([tabB])
    .build()

let recipientC = DSMRecipientBuilder.init(for: .CC)
    .addRecipientId("3")
    .addSignerName("{IN_PERSON_SIGNER_NAME}")
    .addSignerEmail("{IN_PERSON_SIGNER_EMAIL}")
    .build()

let filename = "{DOC_NAME}"

let filePath = Bundle.init(for: self.classForCoder).path(forResource: filename, ofType: "pdf") ?? ""

let document = DSMDocumentBuilder.init()
    .addName("doc1")
    .addDocumentId("1")
    .addFilePath(filePath)
    .build()

let envelopeDefinition = DSMEnvelopeBuilder.init()
    .addEnvelopeName("Test Envelope -- name")
    .addEmailSubject("Test Envelope -- Subject")
    .addEmailMessage("Message blurb -- \n -- there goes the docusign email message -- sent via sdk -- ")
    .add([recipientA, recipientB, recipientC])
    .add(document)
    .build()
```

## Step 3. Create the envelope

Next, use the definition you created in the previous step to create an envelope.

**`Objective-C`**

```text title="Objective-C"
[self.envelopesManager composeEnvelopeWithEnvelopeDefinition:envelopeDefinition
    signingMode:DSMSigningModeOffline
    completion:^(NSString * _Nullable envelopeId, NSError * _Nonnull error) {
    if (error) {
        NSLog(@"%@", error.localizedDescription);
        return;
    } else {
        NSLog(@"envelope ID: %@", envelopeId);
    }
}];
```

**`Swift`**

```swift title="Swift"
DSMEnvelopesManager.init().composeEnvelope(with: envelopeDefinition,
    signingMode: .offline) { (envelopeId, error) in
    guard error == nil else {
        print(error)
        return
    }
    print("envelope ID: \(envelopeId)")

}
```

## Expected response

If your envelope creation is successful, a temporary envelope ID is returned that can be used to start the offline signing process.

## Next steps

* See [How to start the signing process for an unsigned envelope without connectivity (offline)](/docs/mobile-sdks/ios-sdk/how-to/start-signing-offline).
* Learn [How to sync offline signed envelopes](/docs/mobile-sdks/ios-sdk/how-to/sync-offline).
* See [How to create an envelope for offline signing (from a template)](/docs/mobile-sdks/ios-sdk/how-to/offline-signing-template).