# eClose > Snapdocs Connect — create closings, upload documents, and track every milestone from your LOS or POS. ## OpenAPI specs - [Authentication](https://developers.snapdocs.com/content/eclose/specs/authentication.json) - [eClose APIs](https://developers.snapdocs.com/content/eclose/specs/snapdocs-connect.json) - [Reporting](https://developers.snapdocs.com/content/eclose/specs/reporting.json) (Specs are schemas, not prose — fetch the JSON directly rather than pasting it here.) ## Shared platform guides Authentication, environments, webhooks, and testing are shared across every Snapdocs product — see [Getting Started](https://developers.snapdocs.com/platform/llms.txt). ## Introduction ### Welcome to the eClose API # Welcome to the eClose API The eClose API creates closings in Snapdocs, uploads documents to them, and tracks every milestone from drawn documents through signing and completion. It spans two integration types: LOS-driven closing workflows and POS-driven signer engagement. From your Loan Origination System (LOS), create closings and upload documents, receive status updates, submit revised documents, and download signed packages. From your Point of Sale (POS) system, listen for major events — documents ready to review, eSigning available — and prompt signers to act from your own experience. Platform behavior is documented once, in [Getting Started](https://developers.snapdocs.com/platform/guides/start-here/what_you_can_build): [authentication](https://developers.snapdocs.com/platform/guides/authentication/oauth2_client_credentials), [environments](https://developers.snapdocs.com/platform/guides/environments/environments), [the Subscriptions API](https://developers.snapdocs.com/platform/guides/webhooks/subscriptions_api), [webhook security](https://developers.snapdocs.com/platform/guides/webhooks/webhook_security), and [testing](https://developers.snapdocs.com/platform/guides/testing/test_your_integration). This tab covers what's specific to eClose: * **Introduction** — the [Postman collection](https://developers.snapdocs.com/eclose/guides/introduction/postman_collection) and testing walkthroughs, [event payloads](https://developers.snapdocs.com/eclose/guides/introduction/events), [errors](https://developers.snapdocs.com/eclose/guides/introduction/errors), and the [glossary](https://developers.snapdocs.com/eclose/guides/introduction/glossary). * **Security** — signer SSO (OAuth 2.0 and SAML), SCIM role management, and company user validation. * **Lender Integration** — building closings into your LOS: [architecture](https://developers.snapdocs.com/eclose/guides/lender-integration/los_integration_architecture), [scope](https://developers.snapdocs.com/eclose/guides/lender-integration/los_integration_scope), closing creation, redraws, statuses, and scanbacks. * **Borrower Engagement (POS) Integration** — event-driven signer workflows for POS systems. Every endpoint's details live in the API Reference tab. --- ### Postman Collection # Postman Collection Snapdocs offers a public Postman collection demonstrating the basic client use cases of the eClose API. Download and install the [Postman desktop application](https://www.postman.com/downloads/), then download the collection and its accompanying environment here. The collection works in conjunction with the Postman "Public Collection" environment to run simple end-to-end (ETE) closing workflows. It saves request responses into environment variables and uses them in subsequent requests: upon creating a closing, the new closing UUID is saved and used to upload documents to that closing in the next request. New to Postman? Start with importing and exporting data. ## Collections by integration type There are multiple collections because clients usually focus on one experience: * Lender or LOS systems * Borrower or POS systems * Settlement Agents or TPS systems Closings are created by the LOS, so you always need the LOS collection to create closings. Download all the collections and import them into Postman with **Import** → **Folder**. Inside each collection, requests are grouped by functionality, and every collection starts with a "Get Access Token" request — you need the token before any other request. The LOS collection carries requests to get a token, create a closing, and operate on the closing. {417} LOS Postman Collection The POS collection is much smaller, since POS integrations mostly consume broadcast events through webhooks. {399} POS Postman Collection ## Set up the environment 1. Import both JSON files (collection and environment) into your Postman workspace. 2. Navigate to **Environment** > **Public Collection** and update the variables. Defaults are provided for a basic demo; customer support may recommend changes. The important ones: * `AuthBaseUrl` — URL for acquiring an authentication token * `BaseUrl` — URL to access the eClose API * `ClientId` — the preconfigured client ID for authentication * `ClientSecret` — the preconfigured client secret for authentication * `audience` — the API you intend to call with the generated token * `company_id` — Snapdocs's assigned company ID for your organization 3. Select the Public Collection environment. ## How the collections use variables The collections lean on Postman collection variables to store and reuse values between requests. Select a collection's **Variables** tab to see them: some are set once and used across requests (like `BaseUrl`), others are set by JavaScript after a response arrives. Edit the "Current Value" to change one. The "Get Token" request reads the configuration variables (`AuthBaseUrl`, `ClientId`, `ClientSecret`, `audience`); its **Tests** tab holds the script that saves `access_token` into the `ApiToken` variable used by every following request's authorization header. Requests can also run scripts before sending — "Step 1 Create Closing Record" generates testing values in its **Pre-request Script** tab and uses them in the request body. {804} Postman Collection Variables ## Run workflows With the environment selected, either run the entire collection, or run individual workflows: * Select **Auth** > **Regular Use** and click **Run** to obtain an authenticated client. * Select any workflow folder and click **Run** — for example, **Closings** > **ETE Happy Path Wet Closing** walks from creating a wet closing through completing it. To receive events while you test, stand up the local webhook sink from [Test your integration](https://developers.snapdocs.com/platform/guides/testing/test_your_integration), then continue to [Set Up Testing](https://developers.snapdocs.com/eclose/guides/introduction/set_up_testing). --- ### Set Up Testing # Set Up Testing Now that you have Postman collection imported and local server ready to receive incoming requests. Let's create a closing at Snapdocs! ## Set Collection Variable Values First, update your collection variables to set the value for * AuthBaseUrl * BaseUrl * ClientId * ClientSecret Above variables are for the purpose of authentication. You should be able to get them from the Snapdocs representative. Note, if you are testing from POS or TPS perspectives, you will receive two sets of credentials, one for the LOS collection, and the other one for POS or TPS. Most likely you will also need to set * external\_system * external\_type The external system is used by Snapdocs to identify parties involved in the closing. Please reach out to your Snapdocs representative to inquire the appropriate value. Now let's test the Snapdocs Connect API! Select the "Subscriptions" folder, then the "List subscriptions" request, click "Send" button. You should get the 2XX HTTP response code. ## Authenticate with Snapdocs Select the Postman Collection for your use case, then choose "Get Token" request, click "Send" button. {1302} Get-Access-Token Request You should expect to see response like below ![1864](../images/get_token_response.jpg "get_token_response.jpg") > 📘 The “scope” are the permissions that are set up at Snapdocs for the particular client credential (identified by the client id and client secret). The token will be valid for 7200 seconds (2 hours). ## Create Subscription Next, we will create subscriptions to receive broadcasted events from Snapdocs Connect. Before making the create-subscription request, first set the "webhookUrl" collection variable value to the Ngrok url of your local JSON-server. Select the "Create Subscription" request in the "Subscriptions" folder, and click "Send" ![1734](../images/create_sub.jpg "create_sub.jpg") That is it! Now Snapdocs Connect will be able to broadcast those subscribed events to your local JSON-server when they happen to your closings. --- ### Successful Testing # Successful Testing Snapdocs API based integrations will require thorough testing, and it includes requirements that may not be obvious to those who are not steeped in Snapdocs eClose interactions. The following are some major themes we find are not well understood when trying to test with Snapdocs APIs. * Interacting with the closing as various user roles (borrower, settlement, lender users) through a browser and manual clicks * Setting fields at Closings Create such that they are correctly firing events and connections in a test transaction * Using documents that will pass Snapdocs Document processing * Leveraging Closings Create postman calls, when the integration may not require that endpoint This guide is going to call out a few workflows that have caused issues for some integrations, and hopefully help frame the concerns so that other details are easy for our integrators to find themselves. ## Interaction Expectations Many integration workflows require the firing of Snapdocs Webhook events, listening and processing those events to kick off integration workflows on your integration and backend. Snapdocs testing expects that you are interacting with the closing as each party in order to reliably trigger those events. Logging in as a Borrower or Settlement Agent, and performing activities like preview, esign, download the wet package, upload a PDF that pretends to be the signed completed package, etc. ### Borrower For example, the Borrower is a party who has actions that are required to make various signing events happen. | Event Triggers | Action(s) Required | | --- | --- | | borrower.preview\_available | • Proper documents were uploaded successfully. Borrower email address is valid.
• Email is generated for the borrower. Test resource is able to access the Review and eSign Email pending. | | borrower.preview\_complete | • Review button in borrower email is clicked.
• Tester logs in as borrower (settings are appropriate for tester to log in (i.e. US phone number, 2fa, username/pw).
• Tester is logged in as consumer, scrolls through preview experience, finishes preview | | borrower.esigning\_available | • Closing created as hybrid or hybrid with eNote
Preview has completed
• Closing date was sent through as today (and/or \* eSign constraints are loosened in the customer configuration)
• Company eSign constraints are configured appropriately for testers to eSign to be available soon after preview | | borrower.esigning\_complete | Button may be available immediately after preview, depending on the date of the signing and eSign constraint settings. The actions below assume you leave Snapdocs after preview.
• Review and Esign button in borrower email is clicked.
• Tester logs in as borrower.
• Tester eSigns the documents through the eSign experience. | ### Settlement Agent Settlement agents, Title or Escrow company users, or whatever other parties are providing the settlement signing services will interact with Snapdocs in order to process the wet documents. | Event Triggers | Action(s) Required | | --- | --- | | | • Log in as Settlement Agent
• Download wet sign package | | document.created
scanback documents | • Log in as Settlement Agent
• Upload a pdf document for signed scanback (there is no requirement that it has real signatures) | | document.created
signed complete package | • Upon upload of pdf (prior step), click the appropriate button to signify you are done uploading scanbacks. The combined signed document process will kick off in the background, firing this event. |
> ❗️ Production delay > > Please note: In production there is a 5 minute delay in kicking off the generation of the signed complete package. The 5 minute delay allows for the adding of multiple documents by settlement agents within that window. After the window closes a single document package of all documents on the closing will be sent via API. ### Lender The third primary user type is lender users, however for integration testing through Snapdocs Connect we don’t expect in-app actions to unlock webhook events. Snapdocs builds its APIs and Integrations to enable Lender Users to control their interactions and updates through the LOS systems, without manual steps in the Snapdocs applications. ## Important Closings Create fields There are various downstream actions that require that you’re passing in fields that will help your testing go smoother. ### Identifiers Your webhook listener and subsequent processor / handler methods will likely need to make determinations about what action / transaction to take on, based on the matching of a Closing Identifier to your core system.\ Update your closings create API calls to include appropriate test transaction identifiers, such that webhooks will contain them as later events take place on the closing. * **file\_number**: often this is a readable file value, only used for display. However, this could be a value that connects transactions. * **reference\_id**: this is often populated with the unique identifier in the LOS system, whether that is a loan guid or a numeric file id. To mimic what is sent by an LOS integration, we recommend test transactions start with this id. * **external\_identifiers array**: these are values that are published in the webhook payload for every Snapdocs webhook. The values in this array may include the LOS identifier, TPS identifiers (settlement company software id), or other system identifiers. The acceptable current values for the system and field type is available on the Closings Create external identifiers object.\ [Create a new closing](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateClosing) #### Emails and Phone Numbers * borrowers array - phone, email * closing\_users array - phone, email * settlement\_agents array - phone, email * settlement\_office\_email Our Snapdocs cs-demo0 environment sends emails and SMS messages to end users. Various borrower, settlement company, lender user interactions require clicking buttons that are in the email. It is important to use distinct emails per user, and use email addresses your testing team has access to. Snapdocs encourages the use of gmail based inboxes, as they have the + feature that allows unique email values to act as separate Snapdocs users, while routing everything to a single inbox. Your cs-demo0 account may be set to our standard borrower authentication which includes the email messages and 2fa texts. However, our text policy only sends SMS messages for 2fa to US based cell numbers. If your development team is unable to reliably use a US based cell number, we strongly recommend working with your Business Development, Customer Success, or Engineering contact to configure your cs-demo0 environment for username and password borrower authentication. #### Dates Our standard cs-demo0 company setup includes a set of eSigning constraints about when eSigning can take place. Most of these rules calculate when to send emails or webhooks based on the company configured rules and the closing dates on the closing. * Appointment\_earliest\_at & appointment\_latest\_at: for customers or transactions that allow date ranges for eSigned closing documents you can pass both of these values in. Our email sends at midnight in the timezone of the closing on the earliest date. * Appointment\_date: for customers who set a single date for the closing, our email sends at midnight on the date of the appointment.\ If you are not seeing the preview or eSign borrower events you can validate if your closing date was set appropriately. The eSign constraints are configurable for the account your key is configured for, and you can contact your Business Development, Customer Success, or Engineering contact to update the configuration to match your needs. ## Documents Snapdocs uses our document processing AI technology in our non-production and production environments, so to ensure original closing packages are split into eSign and Wet packages you must submit packages that our document processing is trained for. Work with your Business Development, Customer Successcontact at Snapdocs in order to ensure you have appropriate documents for your use case. For example, if you want to create a Hybrid with eNote you need to ensure that your package contains at least 1 document to wet sign, 1 document to eSign, and a promissory note that matches the supported eVault forms for your configured test vault. ## Standard Test Scenarios Below are some possible differences per closing. Your integration should ensure it works well for various combinations of settings. * Single borrower, multiple borrowers * Signing types - wet, full eClosings, hybrid, hybrid with eNote * Closing same day, preview today and close tomorrow * Redraws - full, partial redraws, before any Borrower / Settlement interactions, after Settlement has downloaded, after Borrower has eSigned, with note replaced ## Troubleshooting FAQ I did not get the borrower email? * Was the closing initiated with an email address where you have access to the inbox? * Was the date set in the future, such that you’ll receive the email in the coming days? * Did you create the closing, attach documents, and submit the closing to processing? * Did you use documents that will pass Snapdocs doc processing as expected? Why is my closing a wet closing when I submitted it as hybrid? * Did you use a closing package that contains valid documents that will be hybrid documents? * Can you confirm with your BD, CS, or Engineering contact at Snapdocs that there are classification preferences for your account and they include eSignable documents? * Has your company submitted sample packages such that we have an AI model for your account? * Are you using the Snapdocs sample documents from your BD or CS partner? Why can’t I log in with the 2fa text code? * Did you submit your borrower with a phone number where you have access to that device? * Is your submitted phone number a US based phone number? Why am I not seeing the borrower eSign events? * Did you set the appropriate closing date to today? * Have you signed in as the borrower to preview? Preview is what unlocks the eSign. --- ### Create A Hybrid Closing # Create A Hybrid Closing Time to close! ## 1-2-3 Create A Closing Remember that closings are typically created by the lender or LOS system, thus we will use the “LOS” collection for this purpose. First, let’s get the access token with lender credentials\ Select the “Get token” request from the LOS collection, and click “Send” {1286} Get Access Token There are 3 steps to create closing at Snapdocs Step 1, Create the closing object\ Step 2, Upload the documents, for example, the loan disclosure document, title document etc.\ Step 3, Finally, once all the documents are uploaded, notify Snapdocs to start processing the closing. ## Create Closing Object Select the request “step 1 create a closing record” within the “Create Closing” group and click "Send" {1322} Create Closing Object More information of the request can be found at\ [Create a Closing](https://developers.snapdocs.com/eclose/guides/lender-integration/closings_creation_guide)\ [Create a new closing](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateClosing) If the request succeeds you will receive response like below with HTTP response code 201 ```json { "closing_uuid": "d5236672-7933-4c77-a7c2-17ad65609472", "snapdocs_url": "https:/....snpd.io/closings/d5236672-7933-4c77-a7c2-17ad65609472", "errors": [] } ``` The “closing\_uuid” is the identifier of the newly created closing. ## Upload Closing Document The closing is useless without any document, next let’s upload a document to our newly created closing!\ Go to the “LOS” collection, select the “step 2 - upload original document” in the “Create Closing” folder. Along with the Postman collection, you should also receive some testing files, including the “sample\_with\_enote.pdf” (don’t mind the “enote” part, we will not use enote in this example). Check the “body” tab and select the testing file. Then click the “Send” button. ![1802](../images/upload_original_doc.jpg "upload_original_doc.jpg") ## Submit Original Documents Select the “step 3 - submit closing”, and click “Send”. This request indicates to Snapdocs that the lender has finished uploading all the original documents needed for the closing. {1536} Submit Closing Documents You should expect response code 200 from the API. This will kick off the AI process at Snapdocs: 1. Classifying the documents 2. Annotate the documents 3. Broadcast events to listening parties 4. Send notification to closing users including borrowers per the setup by lenders. --- ### eClose Events Catalog # eClose Events Catalog ## Structure ```json { "event_id": string, "subscription_id": string, "closing_uuid": string, "event_name": string, "signing_method": string, "created_at": unix epoch time (seconds), "payload": { "external_identifiers": [ // external identifiers, can be empty ] // other fields of the event. } } ``` 1. event\_id: unique identifier of the event 2. subscription\_id: identifier of the subscription 3. closing\_uuid: uuid of closing. 4. event\_name: name of event 5. signing\_method: can be "wet\_only", "hybrid", "hybrid\_with\_enote", "full\_eclosing", "full\_eclosing\_with\_enote", [Create a new closing](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateClosing) 6. created\_at: the epoch timestamp of the event 7. payload: the payload JSON object of the event. * external\_identifiers: JSON array of the external identifiers of the closing. If the closing was created with external identifiers [Create a new closing](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateClosing), they will be included in the array, otherwise the array is empty. * other fields: some events have additional data, for example, the borrower UUID. ## Borrower Preview Events [Integrate with Borrower Preview Events](https://developers.snapdocs.com/eclose/guides/pos-integration/integrate_with_borrower_preview_events) ```json { "event_id": "b85e055a-57c5-4968-b742-e4180913a349", "subscription_id": "e040c30e-dfe4-49c3-933e-9781cf70a764", "closing_uuid": "7e22f055-2e77-4234-accb-df953801eac1", "event_name": "borrower.preview_available", "signing_method": "hybrid", "created_at": 1656524428, "payload": { "external_identifiers": [ ... ], "borrower_uuid": "95e7638b-93a8-27de-4243-3d46e5b942a5" } } ``` *** ```json { "event_id": "2a7b8734-f944-4963-b23e-cffbea59cde9", "subscription_id": "e040c30e-dfe4-49c3-933e-9781cf70a764", "closing_uuid": "8ca4bfe2-7beb-45c2-9182-9c3bcf4dc37e", "event_name": "borrower.preview_complete", "signing_method": "hybrid", "created_at": 1655817730, "payload": { "external_identifiers": [ ... ] } } ``` *** ```json { "event_id": "25146b6b-c46d-417c-90e2-da7df4737a2e", "subscription_id": "2afae178-498d-4f19-8857-279bf25e06d3", "closing_uuid": "23242df7-f83e-4b5e-a30d-56b520e62056", "event_name": "borrower.redraw_preview_available", "signing_method": "hybrid", "created_at": 1655161244, "payload": { "external_identifiers": [ ... ], "borrower_uuid": "78986eab-39e4-78db-b733-eda256b53274" } } ``` *** ## Borrower eSign Events [Integrate with Borrower eSign Events](https://developers.snapdocs.com/eclose/guides/pos-integration/integrate_with_borrower_esign_events) ```json { "event_id": "9bf64f7c-1e3e-4d1b-84d5-5e95c95dd0d5", "subscription_id": "f2012e25-4388-432e-b53d-01236cdb159a", "closing_uuid": "6be819e3-8ef5-4d84-833d-8102adbe8273", "event_name": "borrower.esigning_available", "signing_method": "hybrid", "created_at": 1654741164, "payload": { "external_identifiers": [ ... ], "borrower_uuid": "729452a7-ae89-42d7-98ae-4d7365b6b83e" } } ``` *** ```json { "event_id": "d54e2bb1-540a-47fe-bae9-ae119d1fc879", "subscription_id": "e040c30e-dfe4-49c3-933e-9781cf70a764", "closing_uuid": "500a54ef-ccf3-4b46-ab0c-2f571b5db503", "event_name": "borrower.esigning_complete", "signing_method": "hybrid", "created_at": 1656684029, "payload": { "external_identifiers": [ ... ] } } ``` *** ```json { "event_id": "0337e34c-1acd-4b6a-afab-cacca4b605a4", "subscription_id": "2afae178-498d-4f19-8857-279bf25e06d3", "closing_uuid": "878b5a9d-4d96-a8e8-b4a9-ae5b37273624", "event_name": "borrower.redraw_esigning_available", "signing_method": "hybrid", "created_at": 1644432694, "payload": { "external_identifiers": [], "borrower_uuid": "8d89b65a-3764-d2e2-a5d8-2e9b58ad3427" } } ``` *** ```json { "event_id": "28e430b1-b33d-4575-b875-110d8bf185df", "subscription_id": "2afae178-498d-4f19-8857-279bf25e06d3", "closing_uuid": "7edbc5c2-b665-49b8-9d15-da5ddcccd1b1", "event_name": "borrower.esign_reminder", "signing_method": "hybrid", "created_at": 1655257575, "payload": { "external_identifiers": [ ... ], "borrower_uuid": "385a6eb9-45b2-37d6-6a44-7d8e96a37842", "trigger": "automated", "reminder_type": "email" } } ``` 1. trigger: `manual` or `automatic` 2. reminder\_type: `email` *** ## Borrower Events [Integrate with Borrower Events](https://developers.snapdocs.com/eclose/guides/pos-integration/all_other_subscription_events#opt-outopt-in-to-esign) ```json { "event_id": "7b5a1ccd-488e-4a51-8374-b24da4cccf83", "subscription_id": "f2012e25-4388-432e-b53d-01236cdb159a", "closing_uuid": "a367a76e-a036-47cd-ac1e-c7932ef9c687", "event_name": "borrower.opted_out", "signing_method": "wet_only", "created_at": 1656533310, "payload": { "external_identifiers": [ ... ] } } ``` *** ```json { "event_id": "ebb6c143-a26b-4ba6-9d97-83240df17d26", "subscription_id": "f2012e25-4388-432e-b53d-01236cdb159a", "closing_uuid": "a367a76e-a036-47cd-ac1e-c7932ef9c687", "event_name": "borrower.opted_in", "signing_method": "hybrid", "created_at": 1656533378, "payload": { "external_identifiers": [ ... ] } } ``` *** ## Closing Events [Integrate with Closing Events](https://developers.snapdocs.com/eclose/guides/pos-integration/all_other_subscription_events#closing-events) ```json { "event_id": "2b48395e-f1e0-482e-842b-9cedbd37ac7b", "subscription_id": "f2012e25-4388-432e-b53d-01236cdb159a", "closing_uuid": "500a54ef-ccf3-4b46-ab0c-2f571b5db503", "event_name": "closing.completed", "signing_method": "hybrid", "created_at": 1656684040, "payload": { "external_identifiers": [ ... ] } } ``` *** ```json { "event_id": "c997b0b2-40d7-4190-8484-76bc68a68d3c", "subscription_id": "e040c30e-dfe4-49c3-933e-9781cf70a764", "closing_uuid": "500a54ef-ccf3-4b46-ab0c-2f571b5db503", "event_name": "closing.created", "signing_method": "hybrid", "created_at": 1656683649, "payload": { "external_identifiers": [ ... ] } } ``` *** ```json { "event_id": "99f28b08-8991-40ea-b3fe-19616776d308", "subscription_id": "f2012e25-4388-432e-b53d-01236cdb159a", "closing_uuid": "6be819e3-8ef5-4d84-833d-8102adbe8273", "event_name": "closing.canceled", "signing_method": "hybrid", "created_at": 1654741233, "payload": { "external_identifiers": [ ... ] } } ``` *** ```json { "event_id": "0ca41d68-4e31-4460-8f8b-3bfd9081217c", "subscription_id": "34d047d1-d29b-4837-ab6f-18b060a4290a", "closing_uuid": "1237f99f-9685-448d-a0fb-605655027144", "event_name": "closing.created_from_redraw", "signing_method": "hybrid", "created_at": 1655412862, "payload": { "external identifiers": [], "linked_closing_uuid": "d896e48b-0b71-4e31-aadd-dd50d20ea904" } } ``` 1. linked\_closing\_uuid: the UUID of the original closing (canceled due to full redraw) *** ```json { "event_id": "fb5383f4-1109-4b6f-9822-bb59da8652d8", "subscription_id": "34d047d1-d29b-4837-ab6f-18b060a4290a", "closing_uuid": "d896e48b-0b71-4e31-aadd-dd50d20ea904", "event_name": "closing.canceled_for_full_redraw", "signing_method": "hybrid", "created_at": 1655412863, "payload": { "external_identifiers": [], "linked_closing_uuid": "1237f99f-9685-448d-a0fb-605655827144" } } ``` 1. linked\_closing\_uuid: the UUID of the new closing due to redraw *** ```json { "event_id": "152b5eda-9ff0-4e08-b112-6eaeacf148e2", "subscription_id": "2afae178-498d-4f19-8857-279bf25e06d3", "closing_uuid": "32f1624f-5143-4010-98c5-593dcd2407da", "event_name": "closing.type_converted", "signing_method": "wet_only", "created_at": 1655229527, "payload": { "external_identifiers": [ ... ], "converted_from": "hybrid", "converted_to": "wet_only", "converted_by": "lender" } } ``` 1. converted\_from: the original signing method, refer to [Create a new closing](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateClosing) for the signing method values 2. converted\_to: the new signing method, refer to [Create a new closing](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateClosing) for the signing method values. 3. converted\_by: `settlement agent` or `lender` *** ```json { "event_id": "dd9fa380-4925-4d41-84ef-4b3723b82b68", "subscription_id": "e040c30e-dfe4-49c3-933e-9781cf70a764", "closing_uuid": "a1a946a0-c673-4ffa-a6fe-d13fd60e7fbf", "event_name": "closing.appointment_details_changed", "signing_method": "hybrid", "created_at": 1656532871, "payload": { "external_identifiers": [ .. ] } } ```
*** ```json { "event_id":"ec5ea44c-363d-468f-a98b-a92063eecadd", "subscription_id":"fa7f57fa-11bc-40e8-af26-3891f338822e", "closing_uuid":"2496d7ba-24c6-46b4-ad12-342bc0a304fb", "event_name":"closing.signed_document_available", "signing_method":"hybrid", "created_at":1756844620, "payload":{ "external_identifiers":[ { "external_system":"other_los", "external_type":"file_number", "value":"12345" } ] }, "document_uuid":"73a72a36-eb22-9745-73e3-34856ad9d8e3", "document_type":"signed complete package" } ``` ## Document Events [Integrate with Document Events](https://developers.snapdocs.com/eclose/guides/pos-integration/all_other_subscription_events#document-events) ```json { "event_id": "497e0c55-757b-482a-81b5-1bbf53277587", "subscription_id": "e040c30e-dfe4-49c3-933e-9781cf70a764", "closing_uuid": "500a54ef-ccf3-4b46-ab0c-2f571b5db503", "event_name": "document.created", "signing_method": "hybrid", "created_at": 1656684343, "payload": { "external_identifiers": [ ... ], "document_uuid": "729452a7-ae89-42d7-b5a8-d7365b6b83eb", "document_type": "signed complete package" } } ``` ## Mobile Notary Events [Integrate with Mobile Notary Events](https://developers.snapdocs.com/eclose/guides/pos-integration/integrate_with_notary_events) ```json { "event_id": "426d3fc6-9379-47f8-aa48-8183f4da6e86", "subscription_id": "5e8ca921-85c1-4819-a229-19bd6351e8e7", "closing_uuid": "9d1efc56-a58e-41bf-8ee3-1cb94ce1ae0d", "event_name": "notary.order_created", "signing_method": "hybrid", "created_at": 1657242464, "payload": { "external_identifiers": [ ... ] } } ``` *** ```json { "event_id": "ace6b917-cd0f-465a-94b5-fdfe457dca0e", "subscription_id": "5e8ca921-85c1-4819-a229-19bd6351e8e7", "closing_uuid": "9d1efc56-a58e-41bf-8ee3-1cb94ce1ae0d", "event_name": "notary.assigned", "signing_method": "hybrid", "created_at": 1657242622, "payload": { "external_identifiers": [ ... ] } } ``` *** ```json { "event_id": "303e8fda-3335-443a-b059-0630637f603b", "subscription_id": "5e8ca921-85c1-4819-a229-19bd6351e8e7", "closing_uuid": "9d1efc56-a58e-41bf-8ee3-1cb94ce1ae0d", "event_name": "notary.appointment_confirmation_status_changed", "signing_method": "hybrid", "created_at": 1657242881, "payload": { "external_identifiers": [ ... ] }, "status": "confirmed" } ``` *** ```json { "event_id": "29782d80-6238-437b-82ec-8fd22470460e", "subscription_id": "5e8ca921-85c1-4819-a229-19bd6351e8e7", "closing_uuid": "9d1efc56-a58e-41bf-8ee3-1cb94ce1ae0d", "event_name": "notary.order_canceled", "signing_method": "hybrid", "created_at": 1657243119, "payload": { "external_identifiers": [ ... ] } } ``` *** ```json { "event_id": "716624d8-1548-441b-b4f5-9a1e672a8c61", "subscription_id": "5e8ca921-85c1-4819-a229-19bd6351e8e7", "closing_uuid": "9d1efc56-a58e-41bf-8ee3-1cb94ce1ae0d", "event_name": "notary.order_completed", "signing_method": "hybrid", "created_at": 1657243300, "payload": { "external_identifiers": [ ... ] } } ``` *** ```json { "event_id": "8f4a05bb-6f3a-448e-9766-eb6d64dd33fc", "subscription_id": "5e8ca921-85c1-4819-a229-19bd6351e8e7", "closing_uuid": "3c7d1644-db1a-4203-8d6e-ad30401ca207", "event_name": "notary.order_did_not_sign", "signing_method": "hybrid", "created_at": 1657243656, "payload": { "external_identifiers": [ ... ] } } ``` *** ```json { "event_id": "ed3a4f90-7423-4d64-82db-4f0faa17dfca", "subscription_id": "5e8ca921-85c1-4819-a229-19bd6351e8e7", "closing_uuid": "9d1efc56-a58e-41bf-8ee3-1cb94ce1ae0d", "event_name": "notary.attachment_delivery_status_changed", "signing_method": "hybrid", "created_at": 1657242622, "payload": { "external_identifiers": [ ... ] }, "status": "sent_by_client" } ``` | Status value | Status Meaning | | :----------------------- | :------------------------------------------------------ | | `null` | docs have not been sent | | `sent_by_client` | docs sent through API or by client | | `emailed_to_notary` | docs emailed by scheduler | | `direct_links` | docs emailed by scheduler | | notary\_picked\_up\_docs | docs not emailed | | overnighted | docs not emailed | | at\_closing | docs not emailed | | downloaded | docs were emailed and notary has downloaded all of them | *** ```json { "event_id": "92eb7336-aef8-47b7-a544-f6c971e78258", "subscription_id": "5e8ca921-85c1-4819-a229-19bd6351e8e7", "closing_uuid": "9d1efc56-a58e-41bf-8ee3-1cb94ce1ae0d", "event_name": "notary.appointment_confirmed", "signing_method": "hybrid", "created_at": 1657242881, "payload": { "external_identifiers": [ ... ] } } ``` *** `unconfirmed` `confirmed` `change_requested` --- ### Errors # Errors Snapdocs Connect uses conventional HTTP response codes to indicate the success or failure of an API request. In general: * Codes in the 2xx range indicates success. * Codes in the 4xx range indicates an error that failed given the information provided (e.g., a request is not authorized, a resource could not be found, etc.). * Codes in the 5xx range indicates an error with servers. Below is the list of HTTP response codes that our API may return: | Http Response Code | Description | | --- | --- | | 200 | “OK” success code, for GET, PUT or HEAD request. | | 201 | “Created” success code, for POST request. | | 204 | No Content” success code, for DELETE request. | | 400 | The request could not be understood, usually because the request body contains an error. | | 401 | The OAuth token used has expired or is invalid. | | 403 | The user is unauthorized to access the resource. | | 404 | The requested resource could not be found. Check the URI for errors, and verify that there are no sharing issues. | | 409 | The request is in conflict with the current state of the resource. | | 415 | Content type is not supported. Currently, Content-Type header must be 'application/json'. | | 422 | The request cannot be processed as submitted. Check your URL parameters. | | 429 | Too Many Requests. The rate limit has been reached. Please try again later. | | 500 | An error has occurred within the system. | | 503 | The server is unavailable to handle the request. This should be very rare because Snapdocs APIs maintain three 9s uptime. | Snapdocs Connect provides additional information in the HTTP response body, including a JSON array of errors to help our clients. The error object has 3 fields: | Field | Type | Description | | --- | --- | --- | | status | String | The conventional HTTP code associated with the error. | | title | String | A high level description of the error. | | detail | String | Further detail regarding the source of the error. | Below are examples of success and error responses. ## 2XX 2XX code indicates the success of the operation. ```json { "status": "201", "closing_uuid": "uuid of the closing", "snapdocs_url", "Snapdocs URL of the closing", "errors": [] } ``` ## 4XX Client errors indicate that Snapdocs found a problem with the client request, such as an authentication failure or missing required parameters. We suggest clients to log the response, fix the issue in the client application before submitting the request again. ### 401 Auth Error 401 errors may happen due to authentication or authorization problems. Clients should pay special attention to this error because it usually means invalid configuration or setup issues. Example: error response from the Token API when clients send incorrect credentials. ```json 401 { "error": "invalid_client", "error_description": "Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method." } ``` Example: error response when clients send invalid access token to Closing API ```json 401 { "errors": [ { "status": "401", "title": "Invalid Authorization", "detail": "Authorization is invalid" } ] } ``` Example: error response when clients don't have sufficient scope to access the requested resources: ```json 401 { "errors": [ { "status": "401", "title": "Invalid Authorization", "detail": "Insufficient scope" } ] } ``` ### Other 4XX Client Errors The 4xx status codes are often returned when a problem exists in the client application code. Client can find more information in the error object. Example: error response when the closing does not exist: ```json 404 { "errors": [ { "status": "404", "title": "Not found", "detail": "Unable to find closing" } ] } ``` Example: error response when required fields are missing in request: ```json 400 { "errors": [ { "status": "400", "title": "Missing Attribute", "detail": "signing_method must be present" }, { "status": "400", "title": "Missing Attribute", "detail": "settlement_office_email must be present" }, ] } ``` Example: error response when clients send invalid data: ```json 422 { "errors": [ { "status": "422", "title": "Invalid Attribute", "detail": "settlement_office_email must be a valid email address" }, { "status": "422", "title": "Invalid Attribute", "detail": "Closing user 2 email must be a valid email addres" }, { "status": "422", "title": "Invalid Attribute", "detail": "Settlement agent 0 email must not be empty" } ] } ``` ### 429 Too Many Requests Client applications encounter this error code when they have reached the rate limit. The simplest way to fix an HTTP 429 error is to respect the “Retry-after” header and wait to send another request. ```json 429 { "error": "Throttle limit reached. Retry later." } ``` ## 5XX Internal Error When the Snapdocs systems fail to process the requests, clients will get 5XX error code. For example: ```json { "errors": [ { "status": "500", "title": "Something Went Wrong", "detail": "There was an error while processing your request" } ] } ``` A common approach to handle 500 or 503 errors is to implement retry with exponential back-off method. If you continue to see this error, please contact the support at Snapdocs or your Customer Success Manager for assistance. --- ### Glossary # Glossary | Terminology | Description | | --- | --- | | Closing | Relating to a digital closing transaction | | Credential | Security credential to access Snapdocs API | | Document | A collection of pages within a package with consecutive page numbers and the same document type. Attachments are files in an order. | | Document type | A designation as to whether a given document class is typically uploaded by lenders (title) or settlement agents (settlement) | | eNote | An electronic version of the promissory note | | LOS | Loan Origination System. This system can support many origination processes, including lead management, document intake and processing, credit analysis, pricing, and more. | | Package | The entire esigning to be signed by the consumer(s) | | POS | Point of Sale. Interface that consumers interact with when applying for a loan. The consumer can securely enter in information that’s needed for their loan application and track the progress of their application. Consumers may also be able to upload any necessary documentation, verify data, pre-qualify, and receive pricing information. | | Settlement agent | Closing agent or escrow agent. The party who helps complete a transaction between a buyer and seller. This is done through the transfer of securities to the buyer and the transfer of cash or other compensation to the seller. (See definition for escrow) | | TPS | Title Production Software | | Scanbacks | This is a term used to represent signed documents that have been scanned and uploaded to Snapdocs by the notary. Also referred to (albeit outdatedly) as faxbacks, scanbacks are specifically for the company to review for errors before the physical package is returned.
In Snapdocs, companies can note on an order whether scanbacks are required. We also offer specific tools for managing scanbacks such as Post Closing tools and QC. | --- ### Examples # Examples For example code to use Snapdocs Connect, please use the below Github repository. [GitHub - snapdocs/the-acme-lender: code example to demonstrate integration with Snapdocs API](https://github.com/snapdocs/the-acme-lender) --- ## Security ### Borrower SSO Instructions (OAuth) # Borrower SSO Instructions (OAuth) > 📘 This page provides an overview and instructions to complete the setup and testing of the Snapdocs feature that allows borrowers to log in using their SSO provider. > > We will first set up the SSO connection in a test instance. After it is working, repeat the process to move it to production. # Overview **What does the feature do?** Allows borrowers to sign into Snapdocs using the credentials from their POS system **How does the feature work?** 1. As a borrower I receive an email notification from Snapdocs to take action on my closing. 2. When I click the link in the email, I am sent to my POS’s sign-in page 3. When I sign in through my POS credentials, I am redirected back to Snapdocs and taken to my closing! # OAuth Setup: 1. Provide the following information to Snapdocs. You can choose to do the same or go straight to production on your side. 1. Client ID 2. Client Secret (ideally SHA1 fingerprint) 3. Site URL 4. Authorize URL 5. Token URL 6. User Info URL 2. Snapdocs will configure the setup on their side and alert you when they are ready to test. 3. On a call, Snapdocs will add you (or one of your users) as a user in our test environment. You will receive an email giving you access to the platform. When you click the link in the email, you should be given a choice of logging in via user name/password or SSO. Choose SSO and attempt to log in. 4. After it is working in the test environment, you will now move to production. Snapdocs will provide you with the metadata file from the Production environment. Please use this to either set up the production SSO or update your previous setup. 5. Snapdocs will turn on SSO in the production environment and repeat step 3 until successful. --- ### Borrower SSO Instructions (SAML 2.0) # Borrower SSO Instructions (SAML 2.0) > 📘 This page provides an overview and instructions to complete the setup and testing of the Snapdocs feature that allows borrowers to log in using their SSO provider. > > We will first set up the SSO connection in a test instance. After it is working, repeat the process to move it to production. # Overview **What does the feature do?** Allows borrowers to sign into Snapdocs using the credentials from their POS system **How does the feature work?** 1. As a borrower I receive an email notification from Snapdocs to take action on my closing. 2. When I click the link in the email, I am sent to my POS’s sign-in page 3. When I sign in through my POS credentials, I am redirected back to Snapdocs and taken to my closing! # Setup 1. Provide the following information to Snapdocs. Both of these can be found in a “SAML metadata” file. Snapdocs will first be tested in our UAT environment. You can choose to do the same or go straight to production on your side. 1. SSO Target URL 2. SSO Certification Fingerprint (SHA1) 2. Snapdocs will provide you with a SAML metadata file. The EntityID is `https://app.snapdocs.com` and the ACS URL is located in the “Location” tag in the SAML metadata file we provide. Configure your UAT or production SSO provider.\ **NOTE**: Replace the subdomain in the ACS URL with “app” - instead of `lender.snapdocs.com/auth/saml/callback`, set `app.snapdocs.com/auth/saml/callback` 3. Snapdocs will configure the setup on their side and alert you when they are ready to test. 4. On a call, Snapdocs will add you (or one of your users) as a user in our test environment. You will receive an email giving you access to the platform. When you click the link in the email, you should be given a choice of logging in via user name/password or SSO. Choose SSO and attempt to log in. 5. After it is working in the test environment, you will now move to production. Snapdocs will provide you with the metadata file from the Production environment. Please use this to either set up the production SSO or update your previous setup. 6. Snapdocs will turn on SSO in the production environment and repeat step 5 until successful. --- ### SCIM for Role Management # SCIM for Role Management This documentation outlines the SCIM (System for Cross-domain Identity Management) APIs implemented for managing roles within the Snapdocs ecosystem. Designed for seamless integration, these API support connections from Identify Providers (IDPs) such as Microsoft Entra ID, Okta, and other IDPs that support SCIM configurations. The Snapdocs SCIM API is based on version 2.0 of the SCIM protocol. ## Snapdocs SCIM Service Provider Our SCIM service provider follows the [SCIM 2.0 API](http://www.simplecloud.info/) as described in [RFCs 7643](https://tools.ietf.org/html/rfc7643) and [7644](https://tools.ietf.org/html/rfc7644). You do not need to implement all aspects of the SCIM 2.0 specification to integrate your user information with Snapdocs. In general, you should not be implementing SCIM yourself, as your IDP already does. The information provided here is designed to aid you in configuring a SCIM connection in your IDP, not to enable you to write an API client yourself. ## Authentication Requests to the SCIM API must be authenticated with a secret token. Please contact your Snapdocs Customer Success Manager or Implementations Manager to acquire an authentication token. ### Host The following are the values for the Tenant URLs for the endpoints for our production and non-production environments. | Environment | Tenant URL | | :---------- | :----------------------------------------- | | cs-demo0 | | | production | | # APIs ### Supported Resources We only support the User resource. Groups are not supported at this time. *Bulk operations are not supported. For more information on how the RFC describes the resource endpoints, see RFC 7644 SCIM Protocol Specification.* ### Supported Attributes Below is an example POST body to create a user containing all supported attributes. Use this as a guide to which attributes you should map in your IDP. Other standard SCIM attributes are allowed, but will be ignored and won't be persisted or returned. We recommend that you not map them in your IDP. Most IDPs will continually attempt to update the user if the attributes it expects are not returned. Those updates will succeed, but will do nothing. To avoid needless updates to set ignored attributes, refrain from mapping unsupported attributes. ```json { "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"], "externalId":"dschrute", "userName":"dschrute@dundermifflin.com", "active": true, "name":{ "givenName": "Dwight", "familyName": "Schrute" }, "title": "Assistant to the Regional Manager", "timezone": "America/New_York", "phoneNumbers":[ { "value":"555-555-8377", "type":"work" }, { "value":"555-555-8378", "type":"mobile" }, { "value":"555-555-8379", "type":"fax" } ], "roles":[ { "primary": true, "value": "closer" } ] } ``` * **userName**: required to be an email address, and the email address that the user will use to sign into Snapdocs * **timeZone**: if present, must be a US timezone in Olson format * **roles** - **primary**: required. Valid values include the following values. Note that roles in Snapdocs Closings are concentric, and are presented here in order of increasing access. Each role grants all the permissions of the roles above it. | Primary Role Value | Functionality Available | | :--------------------- | :------------------------------------------------------------------------------------------------------- | | **view\_and\_comment** | Read only user role, limited to transactions they're added to. | | **closer** | Role that can interact with the closing, perform actions. Limited to the transactions they're added to. | | **manager** | Role that can interact with the closing, perform actions. Can interact with all closings. | | **admin** | Manager role, with the ability to edit settings and add/remove users from the account. | Because Groups are not supported, you cannot use them to set roles. Roles must be set directly on the User resource. > 📘 **Note on roles for Entra** > > In Entra, the role can be set by defining app roles in your Snapdocs Entra application. Define four roles, each with a value matching a role name in the above table. Assign users (directly or via groups) to these app roles, and add a SCIM attribute mapping for the target attribute `roles[primary eq true].value` with the expression `SingleAppRoleAssignment([appRoleAssignments])`. Make sure not to assign multiple roles to a user, as there's no guarantee which will be provisioned by the expression in that case. > 📘 **Note on roles for Okta** > > In Okta, the role can be set as a user attribute with external name `roles.^[primary==true].value`. We recommend you define the attribute as an enum with type `string`. Here is an example of a working attribute configuration: > > ![](../images/okta_scim.png) ### Operations The Snapdocs SCIM integration supports these standard SCIM operations. Please note that DELETE is implemented by deactivating the user. Therefore, deleted users will still appear in search results as inactive. | Operation | HttpCommand | URL | | :-------- | :---------- | :----------------------------------------------------------------------------------------------------- | | Create | POST | `https://api.snapdocs.com/api/scim/v2/Users` | | Read | GET | `https://api.snapdocs.com/api/scim/v2/Users/{id}` | | Replace | PUT | `https://api.snapdocs.com/api/scim/v2/Users/{id}` | | Delete | DELETE | `https://api.snapdocs.com/api/scim/v2/Users/{id}` | | Update | PATCH | `https://api.snapdocs.com/api/scim/v2/Users/{id}` | | Search | GET | `https://api.snapdocs.com/api/scim/v2/Users?filter={attribute}{op}{value}&startIndex={int}&count={int}` | #### Search Parameters The filter attribute is optional. We have limited support for filters, including only the following two filters. * `userName eq {value}` - when looking for a specific user with only the userName (email) value * `externalId eq {value}`- when looking for a specific user with only the external identifier attirbute We do not support sorting at this time. IDPs very rarely use more complicated filters, or sorting. Paging parameters are optional. startIndex defaults to 1 and count defaults to 100 if not provided. --- ### Company Users Endpoint # Company Users Endpoint Validate user lists against your internal employee systems. # Overview This document outlines the process for using the Snapdocs GET call for company users. This endpoint allows you to validate current users and address general user-matching needs against core Employee systems, serving as an effective alternative to a dedicated user-synchronization integration. ### Details GET /api/v1/company\_users available at [GET Company Users](https://developers.snapdocs.com/platform/reference/company-users/operations/getCompanyUsers) will return the full list of users and their current active status. User email address is the expected user object connection between Snapdocs and lender User systems, in that email is the username for sign on in the Snapdocs platform. Snapdocs assumes SSO, SCIM, or manual intervention on the Users list in the Admin page of the UI is the resulting action when there are users that do not meet your expectations. Please note that there is a Snapdocs user that is required to exist on the account as account owner, and will be in the returned user list. ### Example Script This script is meant as a starting point for your exercise, as it does not know what user-synchronization work would include. We hit our cs-demo0 non-production API endpoint, return a list of users, and print to the command line. The script starts with a Bearer token while a real solution would make the auth call at the [Oauth Guide](https://developers.snapdocs.com/platform/guides/authentication/oauth2_client_credentials). ```csharp using System; using System.Collections.Generic; using System.Net.Http; using System.Net.Http.Headers; using System.Text.Json; using System.Threading.Tasks; namespace GetUsersScript { public class CompanyUser // Model for the user data from Snapdocs API { public bool active { get; set; } public string email { get; set; } = string.Empty; public string first_name { get; set; } = string.Empty; public string last_name { get; set; } = string.Empty; public string role { get; set; } = string.Empty; } public class GetUsersResponse // Model for the API response { public List company_users { get; set; } = new List(); } class Program { private static readonly HttpClient httpClient = new HttpClient(); private const string SNAPDOCS_API_USERS_URL = "https://api.cs-demo0.snpd.io/api/v1/company_users"; // Update with actual base URL private const string BEARER_TOKEN = ""; // Obtain from the Generate a JWT bearer token endpoint static async Task Main(string[] args) { Console.WriteLine("Starting Snapdocs Get Users Script..."); Console.WriteLine(); try { httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", BEARER_TOKEN); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var users = await GetUsersFromSnapdocs(); ProcessUsers(users); } catch (Exception ex) { Console.WriteLine($"Error occurred: {ex.Message}"); Console.WriteLine($"Stack trace: {ex.StackTrace}"); } finally { httpClient.Dispose(); } Console.WriteLine(); Console.WriteLine("Script completed. Press any key to exit..."); Console.ReadKey(); } private static async Task> GetUsersFromSnapdocs() { Console.WriteLine("Calling Snapdocs Get Users API..."); string apiUrl = $"{SNAPDOCS_API_USERS_URL}"; var response = await httpClient.GetAsync(apiUrl); if (response.IsSuccessStatusCode) { var jsonContent = await response.Content.ReadAsStringAsync(); Console.WriteLine($"API Successful! Response received: {jsonContent.Length} characters"); Console.WriteLine(); var apiResponse = JsonSerializer.Deserialize(jsonContent, new JsonSerializerOptions{ PropertyNameCaseInsensitive = true}); return apiResponse?.company_users ?? new List(); } else { throw new HttpRequestException($"API call failed with status code: {response.StatusCode}. Reason: {response.ReasonPhrase}"); } } private static void ProcessUsers(List users) { Console.WriteLine($"Processing {users.Count} users from Snapdocs..."); Console.WriteLine(new string('-', 60)); for (int i = 0; i < users.Count; i++) { //In your implementation, you would run a comparison against the IDP with this data. var user = users[i]; Console.WriteLine($"User {i + 1}: {user.first_name} {user.last_name} : {user.email} : {user.role} : active={user.active}"); } } } } ``` --- ## Lender Integration ### Introduction # Introduction Use **Snapdocs Connect** to embed functionality in your application to create closings, receive status, issue revised documents (e.g., redraws), and retrieve signed documents (e.g., scanbacks). | Functionality | Description | Endpoint | | --- | --- | --- | | Create a closing | Create a closing in Snapdocs with the closings endpoint. | [POST /api/v1/closings](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateClosing) | | Check closing status | Receive real-time status updates on the progress of the closing, including both document and signing status with the closing status endpoint.
You can use a webhook subscription to automatically retrieve all updates or get the status of a specific closing. | [GET /api/v1/closings/\{closing\_uuid}/status](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetStatus) | | Upload closing documents | Upload a new closing document into Snapdocs' system with the document endpoint. | [POST /api/v1/closings/\{closing\_uuid}/documents](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/UploadDocument) | | Submit documents of a specified type after uploading | Signify Snapdocs that all required documents have been uploaded. | [PUT /api/v1/closings/\{closing\_uuid}/documents/submit](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/SubmitDocuments) | | Submit a document redraw | Issue revised documents for the closing with the full redraw endpoint. | [POST /v1/closings/\{closing\_uuid}/full\_redraw](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/SubmitFullRedraw) | | Complete a closing | Complete the closing and ready to retrieve all signed documents. | [PUT /api/v1/closings/\{closing\_uuid}/complete](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CompleteClosing) | | Download signed documents | Retrieve all signed documents associated with the closing. | [GET /api/v1/closings/\{closing\_uuid}/documents](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetDocuments) | | Cancel a closing | Cancel an existing closing. | [PUT /api/v1/closings/\{closing\_uuid}/cancel](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CancelClosing) | | Reopen a closing | Reopen a closed closing. | [PUT api/v1/closings/\{closing\_uuid}/reopen](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/ReopenClosing) | | Create a webhook subscription | Get notified via webhook of major events happening in the closing. | [POST /api/v1/subscriptions](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateSubscription) | | Delete a webhook subscription | Remove an unwanted subscription. | [DELETE /api/v1/subscriptions/:id](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/DeleteSubscription) | | Download Audit Trail of Closing | Get audit events of a closing | [https://api.snapdocs.com/api/v1/closings/\{closing\_uuid}/audit\_trail](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetAudit) | | Download Audit Trail of a Date | Query audit events of the specified date of a lender company | [POST
https://api.snapdocs.com/api/v1/closings/audit\_trail](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetAuditQuery) | --- ### LOS integration architecture # LOS integration architecture Snapdocs has built integrations to many LOS platforms and is opinionated about the architecture that lets customers use every workflow. Every LOS is different, so treat this as the recommended shape and adapt where your platform requires it. The recommendation has three kinds of parts: UI for lender users inside the LOS, a listener for events arriving from Snapdocs, and adaptor code (a "connector") that manages everything in between. ![Inside the lender's LOS, a Snapdocs Connector with a Closing Sender, a Listener, a Status Handler, and a Doc(s) Handler. The Closing Sender sends Create closing, Redraw, and Attach docs requests to Snapdocs Connect. Snapdocs Connect sends events to the Listener, which routes them to the Status Handler (which calls Get status and updates the LOS's Snapdocs Status screen) and the Doc(s) Handler (which calls Get docs and uploads executed documents to the LOS's document store).](../images/connector_architecture_eclose.png) ## The connector 1. **Authentication and token management** — fetch, cache, and reuse bearer tokens ([the shared pattern](https://developers.snapdocs.com/platform/guides/authentication/bearer_token_caching)). 2. **Request/response handling** with persistence to the LOS backend, plus retries or replays for outages and networking blips. 3. **Data mapping** from loan fields to Snapdocs request fields, including customer-specific field overrides ([scope guide](https://developers.snapdocs.com/eclose/guides/lender-integration/los_integration_scope) covers the discovery work). 4. **Workers for webhook events**: jobs that download documents on document events and act on the other event types. 5. **Event logging** in a lightweight database or other structured storage. Where required, closing events can also feed LOS logs or disclosure tracking. Persist Closings Create requests and listener events when they're received, and enqueue senders and handlers to act on them. Queues, database persistence, and in-memory stores such as Redis all work in practice. ## LOS screens To fit lender workflows, expect to build several screens or forms: - **Configuration** — opt in to Snapdocs, toggle features, store API keys and secrets (with rotation), and manage field overrides or data maps per lender. - **Action UI** — however the loan gets sent: a Send To Snapdocs button, a dropdown option, fields on an existing screen, or a fully implicit flow with no new UI. - **Closing values** — editable Snapdocs fields where lender users work: closing type (defaulting to hybrid is a good start), redraw selection (original, full, partial), and unmapped extras such as additional contact emails or external identifiers. - **Closing display** — a form showing the mapped values that will be, or were, sent to Snapdocs, often re-displaying existing loan values in one screen. - **Status, per loan and per list** — [status updates](https://developers.snapdocs.com/eclose/guides/lender-integration/status_guide) broadcast multiple states back to each loan; display them at full granularity on the loan, and add Snapdocs status columns to loan lists and pipeline views so users can see closing state without opening each loan. ## Triggers Snapdocs expects the LOS to create the closing once a defined event has taken place — generally after final closing-package documents are drawn or redrawn and disclosure tracking entries are made. The trigger can be explicit (each loan has a Send To Snapdocs action, or Snapdocs appears as a document-destination selection) or implicit (a loan reaching a milestone, such as drawn documents returning, auto-triggers Closings Create or Redraw). Snapdocs supports any trigger mechanism, and it can differ per lender customer, so this decision lies with lender preference more than Snapdocs preference. --- ### LOS integration scope # LOS integration scope Snapdocs supports more workflows than any first release should carry. Scope the integration around the workflows customers request most, and release in phases as each milestone lands. | Workflow | Summary | Priority | | --- | --- | --- | | Closings Create | Create a closing from a clear-to-close event in the LOS and attach the unsigned closing document package. | MVP | | Redraw (full/partial) | Send an updated package, with or without field updates. Leverages 95% of Closings Create code — see the [redraw guide](https://developers.snapdocs.com/eclose/guides/lender-integration/redraw_guide). | MVP | | Signed document retrieval | Download the completed package(s) when signing events finish — see the [scanbacks guide](https://developers.snapdocs.com/eclose/guides/lender-integration/scanbacks_guide). | MVP | | Compliance downloads | At post-closing, download the audit trail and tamper-sealed originals, then auto-close the closing — see [compliance downloads](https://developers.snapdocs.com/eclose/guides/lender-integration/compliance_downloads). | Phase 2 | | Status updates | Receive events tracking the closing's progress — see the [status guide](https://developers.snapdocs.com/eclose/guides/lender-integration/status_guide). | Phase 2 | | Accelerated eNote | Create eNotes from LOS data instead of having Snapdocs parse the PDF note, by sending the eNote object within [Create a New Closing](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateClosing) — see [eNote MISMO mapping](https://developers.snapdocs.com/eclose/guides/lender-integration/snapdocs_enote_mapping_mismo). | Phase 3 | | Post Close QC | Snapdocs reviews the closing, credit, and origination packages against the lender's QC checklist — the [Post Close QC](https://developers.snapdocs.com/post-close-qc) API. | Phase 3 | | CD Balancing | Compare CDs to highlight fee changes and push results back to the LOS — the [CD Balancing](https://developers.snapdocs.com/cd-balancing) API, in active development. | Phase 3 | For the Phase 3 products, plan the data path now even if you build later: QC and CD Balancing both need the LOS to send loan data points and documents beyond the closing package, so an integration that can already ship arbitrary loan fields to Snapdocs layers them in easily. ## Data mapping comes first The largest body of work in Closings Create is mapping loan fields from the LOS into the closing objects for the initial POST. The required fields per closing type are listed on [Create a New Closing](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateClosing). Two kinds of gaps surface during mapping, and both are cheaper to find early: - **Field identification.** Snapdocs has a field per borrower called Borrower Name Suffix; an LOS may call it Borrower Generation (Jr, Sr). Every field needs this reconciliation. - **Field customization.** Lenders map the same target field differently. Lender A maps borrower email from the primary email of the first borrower; Lender B maps the same field only when an eConsent flag is true. Snapdocs has historically handled this with per-lender field-mapping overrides on a single codebase; if your platform lacks field-level override flexibility, plan an alternative. Do this discovery at the start of the integration. Fields that don't exist in the LOS, fields with unexpected names, and fields populated later than the integration reads them have all delayed launches. ## Drawn documents are a prerequisite Closings Create assumes the lender has access to the drawn closing package returned from their doc prep provider, with all ancillary signable documents identified. Snapdocs expects to receive every document meant to be signed as attachments on the closing. For the return direction, decide with each lender how signed documents come back: as they become available or as one final combined package (timing), as a fully executed package versus separate eSign and wet-sign sets (size), and to what location, named and organized how (location). The platform's Doc Pushback setting per lender produces an event matching the document shape the lender wants; the [scanbacks guide](https://developers.snapdocs.com/eclose/guides/lender-integration/scanbacks_guide) covers the options. ## Other supported workflows A few functions exist in the API but have historically stayed out of integrations — lightly used, or early access. Worth joint exploration for a later release: - **Comments** — read closing comments in the LOS and respond via the integration. - **Close closings** — Snapdocs prefers signed-and-returned closings to be completed, so successful signings are tracked. - **Cancel closings** — let the LOS cancel when a loan is no longer going to close. --- ### API Data Diagram # API Data Diagram ![1775](../images/Snapdocs_Closings_Workflows_-_API_Data_Diagram.jpg "Snapdocs Closings Workflows - API Data Diagram.jpg") --- ### Create a Closing # Create a Closing # Create closings with Snapdocs Connect To create a closing with Snapdocs Connect, all lender systems must complete the following steps: 1. Map your loan data and [create closing object](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateClosing) at Snapdocs. 2. [Upload a new document](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/UploadDocument) signing to the closing. 3. [Submit documents](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/SubmitDocuments) so Snapdocs can begin processing the documents. Here’s an example integration where you add the ability to create a closing in an LOS: # Steps to create a closing Before sending request to Snapdocs to create closing, you will need to collect and map your loan data to Snapdocs Connect request fields. ## Data mapping Each integration will have to understand where on the existing loan do the closing fields exist. This must also take into account any lender by lender differences, if that mapping might not be the same source per lender. Snapdocs closings do not require a large amount of data, but will include the following fields (repeated for multiple borrowers, other parties) * File number or system IDs (such as loan uuid, escrow id, etc.) * Closing dates * Signing method (wet, hybrid, hybrid with eNote, full eClosing, full eClosing with eNote) * Lender connected team member(s) * Settlement company / office / agent(s) and email addresses * Property information * Borrower / Signer details In the case of fields with multiple sources, we have made the suggestion that a custom mapped field should be made, should be what the integration reads from, and then the calculation is put in the hands of each lender. Out of the above fields, most will map from an existing loan field. However, `signing_method` will be a new custom field. We suggest building a calculation that makes loans as "e" as they can be, but we have also seen drop-downs or other manually set values. ## Trigger The initial sending of the closing to Snapdocs will happen at the time that a loan is ready to be closed and drawn documents are available to send. We suggest automating that trigger mechanism that will call the custom integration code to POST data and documents via Snapdocs Connect. In this example, we'll walk you through the steps to embed a form and submission button to capture the required information for a closing, send the closing to Snapdocs, and make it ready for processing. Please refer to [Create a new closing](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateClosing) for the request and response details. ## "Custom Loan" screens We recommend having some custom screens on your LOS to display the following information about the integration. * Data-mapped values that would be / were sent to Snapdocs, including any custom fields. * Any action buttons for closings create or document redraw action. * Closing status values of active closings.\        -- Per loan on some loan details page.\        -- Some list of active closings and current status that require Loan Officer action. ## Build the "Closing Creation Experience" in your LOS a. Capture required information for the closings (e.g., file number/system ID, signing method, settlement office details, closer's details, borrower's details, etc.) Reference the [closing create endpoint](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateClosing) for the required fields. b. Embed a **Create Closing** button that is available after the user enters all required information. c. Set up a webhook to capture closing statuses and show the information in your UI.\ See more in the [Subscriptions](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetSubscriptions) reference. In the below example, the UI is automatically updated after a user submits the closing. It shows the closing status (Pending Uploading Documents), and the **Create Closing** button is no longer available. ## Upload documents Provide a way for your loan officers to upload closing documents. The functionality makes a POST call to the `documents` endpoint with the unique `closing_uuid`. See the [Upload a new document](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/UploadDocument) reference. ## Mark "Document Upload" as complete Snapdocs does not process the uploaded documents until the closing is marked ready. To do so, provide a way for your loan officer to mark the "document upload" task as complete. The functionality makes a PUT call to the `api/v1/closings/{closing_uuid}/documents/submit` endpoint. See the [Submit documents](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/SubmitDocuments) endpoint reference. Set up a webhook to the status updates and show the information in your UI. See more in the [Subscriptions](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetSubscriptions) reference. Below is a sample button that marks the closing ready and updates the status: ![](../images/closing_in_progress_-_Window.png "closing_in_progress - Window.png") --- ### Handling POA, Trust, LLCs # Handling POA, Trust, LLCs # Overview Snapdocs supports the handling of closings where the borrowers are either representing other people and entities or being represented by other people. This guide is meant to detail how to build to the Snapdocs Connect APIs via an integration in a way that handles the top three use cases; Power of Attorney signings, signing on behalf of a Trust, and signing when the entity involved in a Business entity such as an LLC. The primary hurdle in handling these use cases takes place at Closings Creation via the integration, ensuring that data that comes across will support the eSign requirements for all signers. ### Special Callouts: * First, Snapdocs always supports a Wet Closing in these use cases 100% of the time. Our customers get the benefit of a single process for engaging settlement to perform the closing in person, and there are no added hurdles to the transaction. * A hybrid transaction supports one "shared" signer email address. In scenarios where there are more than one "shared" email address across signers, the closing type should be updated to "wet\_only". * Lastly, it’s recommended to implement POA, Trust and LLC closing submissions after you’ve successfully set up basic closing creation. ### Snapdocs Hybrid Requirement Snapdocs connect requires a borrower object for each persona signing on the closing or required to view and interact with the transaction. When the loan involves POA, Trusts, or LLCs then it may not align with the LOS construct of “loan borrower” objects. This may result in a mapping between the LOS and Snapdocs APIs to ensure Snapdocs receives one row per persona. Once we have the appropriate number of personas to send over, we also need to understand the signing details. Snapdocs supports a Closings Create endpoint, borrower object field called signature\_name which needs to match the value the persona is signing as. When no signature name is provided, we are expecting the signer is signing as ***First\_Name + Middle\_Name + Last\_Name + Suffix*** However in the case of a POA, for example, we may see something in a format such as ***\[Borrower full name] by \[Signer Name], POA*** It is crucial to understand how your LOS and Doc Prep determine signature names, as this calculation must be replicated when sending data to Snapdocs. Please note that many of these use cases are not yet supported for eNote or RON (Full eClose) transactions. Please work with your Snapdocs team to validate if you can send any transactions as anything more than Hybrid before selecting eNote or RON closing types. ## Example LOS Images While Loan Origination Systems (LOS) vary, most include the concept of borrowers or co-borrower pairs. For each borrower there are a number of fields filled out differently when the loan is designated as a POA, Trust, or LLC / Business Entity transaction. It is expected that the integrator knows their LOS well and to understand how to map from their object to the requirement of a single row per signer persona for the Snapdocs APIs. This guide leverages images that correspond to an example LOS and how it represents the Loan Borrowers screens and objects in the cases of POA, Trust, and LLC. In our example LOS, we have checkboxes for borrower designations, and buttons that will bring up secondary popup screens with extra information for each special type of signer situation. Walking through the use cases we will assume we have checked the boxes and are editing the POA, Trust, and Business details. ## Snapdocs UI Output We submitted POAs, Trustees, and LLCs with similar signing names in a Snapdocs environment, and it results in a borrowers list like in this screenshot. Once submitting correctly with borrower details, no further change is needed to support POA, Trust, and LLC Hybrid closings. --- ### Power of Attorney (POA) # Power of Attorney (POA) # Overview Below is how a Power of Attorney LOS screen may look, attached to the signer or borrower object. In our sample LOS for Joe Timothy Borrower, we have checked Power of Attorney and filled out the Edit POA popup to call out Polly Powers as the POA for our borrower. The final signature name in this case shows up in the grayed out box. **Borrower: Joe Timothy Borrower (Individual) POA: Polly Powers (Attorney-in-Fact)** To ensure correct mapping to Snapdocs, the Final Signer Name must be placed in the signature\_name field of the borrower object. The value that our Doc Prep will print on the page needs to match the value sent to Snapdocs. Here is what our PDF closing package looks like when we draw the final pages. ## Snapdocs expected Borrower Object In this case we expect to receive a borrower object that will allow both Joe and Polly to receive a preview, but only Polly will esign as the POA of Joe. Joe will be sent as a normal borrower and Snapdocs will note he has nothing to sign, but will be allowed to preview the documents if lender settings allow. The other important part is to ensure that Snapdocs receives that Final Signer Name on the Polly object, the value that is being printed on the document by the Doc Prep, into our signing borrower’s **signature\_name** field. ```json "borrowers": [ { "first_name": "Joe", “middle_name”:”Timothy”, "last_name": "Borrower", “suffix”:”Sr.”, "email": "Joe_Borrowz@gmail.com", "phone": "555 123 4567" }, { "first_name": "Polly", "last_name": "Powers", "email": "PollyP@fancyattorney.com", "phone": "555 123 9876", "signature_name": "Joe Timothy Borrower, BY Polly Powers, Attorney-in-Fact" } ] ```
--- ### Trust # Trust In the case that a loan involves a Trust, Snapdocs will want the Trustees (signers) to come across as borrower objects, regardless of the shape of object in the LOS. In some cases, an LOS may have a separate set of objects for Trusts and the Parties of a trust and the mapping may not be 1:1 for borrower objects. In the example, the Trust is a party to the loan with Alice Firsttimer as the primary borrower. Additionally, two other trustees are required to sign. The borrower object itself is under Alice, who is a Trustee and the first named Trust party. Perhaps she’s the grantor of the Trust, as well as its first Trustee. When it comes to the actual signature lines, the logic between LOS and Doc Prep say that because Alice Firsttimer is the party on the loan, we’re using her normal name there (no signature\_name) and then the Trustee details of the other two Trustees. Snapdocs mapping logic matches, such that my 1 borrower object + 3 trustees turns into 3 Snapdocs objects. ## Snapdocs expected Borrower Object Please note the signature\_name fields on each borrower passed in. ```json "borrowers": [ { "first_name": "Alice", "last_name": "Firsttimer", "email": "alice.firsttimer@aol.com", "phone": "555 444 3333" }, { "first_name": "Fred", "last_name": "Firsttimer", "email": "fred.firsttimer77@gmail.com", "phone": "555 444 8712", "signature_name": "Fred Firsttimer, Trustee of the Joe B Irrevocable Trust dated 1/1/2020" }, { "first_name": "Sally", “middle_name”:”Signer”, "last_name": "Firsttimer", "email": “sally@somebusinessemail.com", "phone": "555 444 7654", "signature_name": "Sally Signer Firsttimer, Trustee of the Joe B Irrevocable Trust dated 1/1/2020" }, ] ```

--- ### LLC # LLC
## Overview When submitting a business or LLC through Snapdocs for a Hybrid signing your LOS may contain details about the business itself in the borrower / party object, while storing the signer details in an Officers or Owners object instead. What Snapdocs will need for the Borrowers objects in this case is the details about the signers, which may be in an Officers and Owners screen, or similar sub screen. In this example we will have two officers and owners of the company who will show up as signers on the drawn package. The logic between the LOS and the Doc Prep seems to take the shape of **\[Borrower First + Borrower Middle + Borrower Last] OF \[Company Name]** ## Snapdocs expected Borrower Object ```json "borrowers": [ { "first_name": "Samwise", "last_name": "Gamgee", "email": "rosie.cotton@hobbitsots.com", "phone": "555 444 8712", "signature_name": "Samwise Gamgee OF Hobbits of the Shire" }, { "first_name": "Frodo", "last_name": "Baggins", "email": "frodo@hobbitots.com", "phone": "555 444 5432", "signature_name": "Frodo Baggins OF Hobbits of the Shire" } ] ```
--- ### Snapdocs eNote mapping - MISMO # Snapdocs eNote mapping - MISMO A MISMO level field mapping for the Snapdocs Closing Create eNote object This guide maps the [Snapdocs Closing API enote object](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateClosing) fields on a `hybrid_with_enote` or `full_eclose_with_enote` signing\_method closing mapped their corresponding MISMO v3.4/v3.5 Reference Model XML paths. These paths are consistent across both MISMO versions for the fields listed below. > 📘 > > All MISMO paths are rooted at MESSAGE/DEAL_SETS/DEAL_SET/DEALS/DEAL/ however, this prefix is omitted for readability and shown as DEAL/... below. > > Some fields (execution location, property county) were renamed/deprecated between MISMO versions 3.4 and 3.5. the deprecated element name is noted where applicable, but the recommended v3.5 path is listed as the primary. > 🚧 > > Not all mortgage tech partners interpret fields the same way. Please confirm values against real notes to ensure the MISMO mapping places the loan field in the path below.
## Loan Terms | Snapdocs API Field | MISMO v3.4 / v3.5 XML Path | | :----------------------------------------------- | :------------------------------------------------------------------------------ | | `original_loan_amount` | `DEAL/LOANS/LOAN/TERMS_OF_LOAN/NoteAmount` | | `note_rate_percent` | `DEAL/LOANS/LOAN/TERMS_OF_LOAN/NoteRatePercent` | | `scheduled_first_payment_date` | `DEAL/LOANS/LOAN/TERMS_OF_LOAN/ScheduledFirstPaymentDate` | | `original_principal_and_interest_payment_amount` | `DEAL/LOANS/LOAN/PAYMENT/PAYMENT_RULE/InitialPrincipalAndInterestPaymentAmount` | | `loan_maturity_date` | `DEAL/LOANS/LOAN/MATURITY/MATURITY_RULE/LoanMaturityDate` | ## Loan Identifiers | Snapdocs API Field | MISMO v3.4 / v3.5 XML Path | | :----------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `lender_loan_id` | `DEAL/LOANS/LOAN/LOAN_IDENTIFIERS/LOAN_IDENTIFIER/LoanIdentifier` where `LoanIdentifierType = "LenderLoan"` | | `mers_min_number` | `DEAL/LOANS/LOAN/LOAN_IDENTIFIERS/LOAN_IDENTIFIER/LoanIdentifier` where `LoanIdentifierType = "MERSMin"` — *or equivalently* — `DEAL/LOANS/LOAN/MERS_REGISTRATIONS/MERS_REGISTRATION/MERSMINIdentifier` | | `agency_case_identifier` | `DEAL/LOANS/LOAN/LOAN_IDENTIFIERS/LOAN_IDENTIFIER/LoanIdentifier` where `LoanIdentifierType = "AgencyCase"` | ## Execution / Closing Information | Snapdocs API Field | MISMO v3.4 / v3.5 XML Path | | :----------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `execution_date` | `DEAL/LOANS/LOAN/CLOSING_INFORMATION/CLOSING_INFORMATION_DETAIL/ExecutionDate` | | `execution_city` | `DEAL/LOANS/LOAN/DOCUMENT_SPECIFIC_DATA_SETS/DOCUMENT_SPECIFIC_DATA_SET/EXECUTION/ADDRESS/CityName` *(v3.5 preferred; deprecated element: `ExecutionCityName`)* | | `execution_state` | `DEAL/LOANS/LOAN/DOCUMENT_SPECIFIC_DATA_SETS/DOCUMENT_SPECIFIC_DATA_SET/EXECUTION/ADDRESS/StateCode` *(v3.5 preferred; deprecated element: `ExecutionStateName`)* | ## Subject Property | Snapdocs API Field | MISMO v3.4 / v3.5 XML Path | | :------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------- | | `property_street_address` | `DEAL/COLLATERALS/COLLATERAL/PROPERTIES/PROPERTY/ADDRESS/AddressLineText` | | `property_city` | `DEAL/COLLATERALS/COLLATERAL/PROPERTIES/PROPERTY/ADDRESS/CityName` | | `property_state` | `DEAL/COLLATERALS/COLLATERAL/PROPERTIES/PROPERTY/ADDRESS/StateCode` | | `property_postal_code` | `DEAL/COLLATERALS/COLLATERAL/PROPERTIES/PROPERTY/ADDRESS/PostalCode` | | `property_county` | `DEAL/COLLATERALS/COLLATERAL/PROPERTIES/PROPERTY/ADDRESS/CountyName` *(v3.5 preferred; deprecated element: `PropertyCountyName` under PROPERTY\_DETAIL)* | ## Note Payee / Pay-To Address | Snapdocs API Field | MISMO v3.4 / v3.5 XML Path | | :--------------------------- | :------------------------------------------------------------------------------------------------------------------------ | | `lender_unparsed_name` | `DEAL/PARTIES/PARTY/LEGAL_ENTITY/LEGAL_ENTITY_DETAIL/FullName` where `ROLES/ROLE/ROLE_DETAIL/PartyRoleType = "NotePayTo"` | | `note_pay_to_street_address` | `DEAL/PARTIES/PARTY/ADDRESSES/ADDRESS/AddressLineText` where `PartyRoleType = "NotePayTo"` | | `note_pay_to_city` | `DEAL/PARTIES/PARTY/ADDRESSES/ADDRESS/CityName` where `PartyRoleType = "NotePayTo"` | | `note_pay_to_state` | `DEAL/PARTIES/PARTY/ADDRESSES/ADDRESS/StateCode` where `PartyRoleType = "NotePayTo"` | | `note_pay_to_postal_code` | `DEAL/PARTIES/PARTY/ADDRESSES/ADDRESS/PostalCode` where `PartyRoleType = "NotePayTo"` | ## Loan Originator / Lender | Snapdocs API Field | MISMO v3.4 / v3.5 XML Path | | :----------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `loan_originator_unparsed_name` | `DEAL/PARTIES/PARTY/LEGAL_ENTITY/LEGAL_ENTITY_DETAIL/FullName` where `PartyRoleType = "LoanOriginator"` | | `loan_originator_nmls_id` | `DEAL/PARTIES/PARTY/LICENSES/LICENSE/LICENSE_DETAIL/LicenseIdentifier` where `PartyRoleType = "LoanOriginator"` and `LicenseAuthorityLevelType = "Federal"` (NMLS) | | `loan_originator_individual_unparsed_name` | `DEAL/PARTIES/PARTY/INDIVIDUAL/NAME/FullName` where `PartyRoleType = "LoanOriginatorContact"` *(individual loan officer)* | | `loan_originator_individual_nmls_id` | `DEAL/PARTIES/PARTY/LICENSES/LICENSE/LICENSE_DETAIL/LicenseIdentifier` where `PartyRoleType = "LoanOriginatorContact"` and `LicenseAuthorityLevelType = "Federal"` (NMLS) | ## Broker | Snapdocs API Field | MISMO v3.4 / v3.5 XML Path | | :----------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `broker_name` | `DEAL/PARTIES/PARTY/LEGAL_ENTITY/LEGAL_ENTITY_DETAIL/FullName` where `PartyRoleType = "MortgageBroker"` | | `broker_nmls_id` | `DEAL/PARTIES/PARTY/LICENSES/LICENSE/LICENSE_DETAIL/LicenseIdentifier` where `PartyRoleType = "MortgageBroker"` and `LicenseAuthorityLevelType = "Federal"` (NMLS) | ## ARM (Adjustable Rate Mortgage) Fields These fields are only applicable when the eNote is for an adjustable-rate loan. | Snapdocs API Field | MISMO v3.4 / v3.5 XML Path | | :------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `first_rate_adjustment_date` | `DEAL/LOANS/LOAN/ADJUSTMENT/INTEREST_RATE_ADJUSTMENT/INTEREST_RATE_PER_CHANGE_ADJUSTMENT_RULES/INTEREST_RATE_PER_CHANGE_ADJUSTMENT_RULE/PerChangeRateAdjustmentEffectiveDate` where `AdjustmentRuleType = "First"` | | `adjustment_frequency_months` | `DEAL/LOANS/LOAN/ADJUSTMENT/INTEREST_RATE_ADJUSTMENT/INTEREST_RATE_PER_CHANGE_ADJUSTMENT_RULES/INTEREST_RATE_PER_CHANGE_ADJUSTMENT_RULE/PerChangeRateAdjustmentFrequencyMonthsCount` | | `first_rate_adjustment_max_percent` | `DEAL/LOANS/LOAN/ADJUSTMENT/INTEREST_RATE_ADJUSTMENT/INTEREST_RATE_PER_CHANGE_ADJUSTMENT_RULES/INTEREST_RATE_PER_CHANGE_ADJUSTMENT_RULE/PerChangeMaximumIncreaseRatePercent` where `AdjustmentRuleType = "First"` | | `first_rate_adjustment_min_percent` | `DEAL/LOANS/LOAN/ADJUSTMENT/INTEREST_RATE_ADJUSTMENT/INTEREST_RATE_PER_CHANGE_ADJUSTMENT_RULES/INTEREST_RATE_PER_CHANGE_ADJUSTMENT_RULE/PerChangeMaximumDecreaseRatePercent` where `AdjustmentRuleType = "First"` | | `subsequent_rate_adjustment_percent` | `DEAL/LOANS/LOAN/ADJUSTMENT/INTEREST_RATE_ADJUSTMENT/INTEREST_RATE_PER_CHANGE_ADJUSTMENT_RULES/INTEREST_RATE_PER_CHANGE_ADJUSTMENT_RULE/PerChangeMaximumIncreaseRatePercent` where `AdjustmentRuleType = "Subsequent"` | | `lifetime_rate_adjustment_max_percent` | `DEAL/LOANS/LOAN/ADJUSTMENT/INTEREST_RATE_ADJUSTMENT/INTEREST_RATE_LIFETIME_ADJUSTMENT_RULE/CeilingRatePercent` | | `lifetime_rate_adjustment_min_percent` | `DEAL/LOANS/LOAN/ADJUSTMENT/INTEREST_RATE_ADJUSTMENT/INTEREST_RATE_LIFETIME_ADJUSTMENT_RULE/FloorRatePercent` | | `margin_rate_percent` | `DEAL/LOANS/LOAN/ADJUSTMENT/INTEREST_RATE_ADJUSTMENT/INTEREST_RATE_LIFETIME_ADJUSTMENT_RULE/MarginRatePercent` | ## Late Charge | Snapdocs API Field | MISMO v3.4 / v3.5 XML Path | | :------------------------------ | :---------------------------------------------------------------------------------- | | `late_charge_grace_period_days` | `DEAL/LOANS/LOAN/LATE_CHARGE_RULES/LATE_CHARGE_RULE/LateChargeGracePeriodDaysCount` | | `late_charge_rate_percent` | `DEAL/LOANS/LOAN/LATE_CHARGE_RULES/LATE_CHARGE_RULE/LateChargeRatePercent` | | `late_charge_maximum_amount` | `DEAL/LOANS/LOAN/LATE_CHARGE_RULES/LATE_CHARGE_RULE/LateChargeMaximumAmount` | | `late_charge_minimum_amount` | `DEAL/LOANS/LOAN/LATE_CHARGE_RULES/LATE_CHARGE_RULE/LateChargeMinimumAmount` | --- ### Closing User Roles Mapping # Closing User Roles Mapping Ensure correct lender team member permissions ## ⚠️ Important: Map LOS Roles to Snapdocs When creating or updating closings via the Snapdocs Connect API, it is important that you properly map the role from your Loan Origination System (LOS) to the `closing_users.roles` or `company_team_member_sub_roles` field in the API payload. **Failure to map these roles correctly will result in:** * ❌ Snapdocs emails not being sent * ❌ UI elements not displaying correctly for lender team members * ❌ Incorrect permissions and access controls within the Snapdocs platform * ❌ Poor user experience for your lender team members ## Affected API Endpoints This requirement applies to the following API endpoints: 1. **POST /api/v1/closings** - Create a new closing 2. **PATCH /api/v1/closings/{closing_uuid}** - Full redraw/update of an existing closing ## Example Mappings When creating a closing, map the LOS role to the `roles` array field within each `closing_users` object: ```json { "closing_users": [ { "first_name": "Jane", "last_name": "Doe", "email": "jane.doe@lender.com", "phone": "555-0123", "roles": ["closer"] // ← Map from your LOS role } ] } ``` ## Snapdocs Role Values The following role values are accepted: | API Value | Your LOS Role | Description | | -------------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------- | | `closer` | Closer, Closing Agent | Closing specialist responsible for finalizing the transaction | | `funder` | Funder, Funding Specialist | Funding specialist who handles the funding of the loan, important for FQC product | | `loan_coordinator` | Coordinator, Processor, Loan Coordinator | Coordinator who manages the loan process | | `loan_officer` | LO, Loan Officer, Officer | Loan officer who originates and manages the loan, important for Loan Officer signing feature | | `broker` | Broker, Mortgage Broker | Mortgage broker handling the loan | | `quality_controller` | QC, Quality Control | Quality control specialist who reviews the closing, important for FQC for Post Close workflows | ## Common Mistakes to Avoid ### ❌ DON'T: Send closings without roles ```json { "closing_users": [ { "first_name": "Jane", "last_name": "Doe", "email": "jane.doe@lender.com" // Missing roles field! } ] } ``` ### ❌ DON'T: Use custom role values not in the enum ```json { "closing_users": [ { "first_name": "Jane", "last_name": "Doe", "email": "jane.doe@lender.com", "roles": ["processor"] // Invalid - not in the accepted enum } ] } ``` ### ✅ DO: Always map and include roles ```json { "closing_users": [ { "first_name": "Jane", "last_name": "Doe", "email": "jane.doe@lender.com", "roles": ["loan_officer"] // Correctly mapped from LOS } ] } ``` --- ### Download Signed Documents # Download Signed Documents Snapdocs Connect allows the broadcast of the event of signed documents being available to the lender through subscriptions and webhooks. Snapdocs sends webhooks to programmatically inform you about the progress of your closings, such as closing status, eSigning status, etc. Before starting, you will need to identify the approach you would like to take: # Option 1 (Recommended) ### Download the signed “completed” package per settings In this approach our webhooks can notify you exactly when you should download the “completed” package. You will need to notify your Snapdocs representative of when you would like to get notified of the signed documents based on your specific trigger and delivery strategy noted below. They will configure your Pushback Settings on our end, which gives the appropriate webhook event when your criteria are met. 1. Trigger Strategy 1. Upon eSign Completion. 2. Upon signing appointment completion. 3. Upon eSign and signing appointment completion. 2. Delivery Strategy 1. Send one combined document and then incremental documents. 2. Send a combined document every time. 3. eSign Tamper Sealed Package (y/n) 1. It is recommended to download and store the eSign tamper sealed package. DocuSign uses cryptographic hashing to create a unique digital "fingerprint" of the eSigned document at the time it's completed. Storing this PDF can assist internal and external auditors to verify the validity of transactions. #### Setup Overview Once Snapdocs has configured your specified trigger and delivery strategy, you can then subscribe to the event `closing.signed_document_available` and download the corresponding documents that will align to your selections. Note that the same event will continue to get sent per the delivery strategy listed above. The eSign tamper sealed package can be captured by listening for the `closing.signed_document_available` event, having enabled the feature in pushback settings. Your integration would have different actions for the document type `signed esign documents`. > 📘 > > See [Documents](https://developers.snapdocs.com/eclose/guides/connect-reference/documents) for more information about document types. # Option 2 (Alternative approach) ### Always download the most recent signed package available In this approach, your system will get notified every time any signing action takes place and allows you to store the latest signed package. Note that with this approach, your system will have PDFs of partially executed packages as closings are in progress. As the closing completes, you will eventually receive a fully executed package. Integrators have found that they build more business logic in the integration if they leverage this option. #### Setup Overview Subscribe to the `document.created` event and listen for the `signed complete package` doc type. Once notified, always pull/replace the most current version of this PDF on your side. This will allow you to obtain the current completed package that may still be in progress. (ex. If only eSigning was completed and wet signing is in progress, you will have the executed eSigned documents available to download). Configure your logic as it relates all the signed [Document Types](https://developers.snapdocs.com/eclose/guides/connect-reference/documents). # Configuration Details ### Option 1 **Step One:** Create a webhook listener Use your existing Http endpoints that are listening for Snapdocs events, or create a [webhook listener](https://developers.snapdocs.com/platform/guides/webhooks/subscriptions_api) to receive the events from Snapdocs Connect. You’ll use your full endpoint URL for the listener `webhook_url` in the next step. **Step Two:** Create a subscription to the event Make a POST request to the [Create a subscription](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateSubscription) endpoint to register your webhook URL and the `closing.signed_document_available` event. With this subscription, after the signed documents have been uploaded to Snapdocs, we will send a notification to the webhook listener. **Step Three:** Handle the payload event Below is an example of a payload. You will use the document\_uuid to download that document in the next step. ```json { "event_id":"ec5ea44c-363d-468f-a98b-a92063eecadd", "subscription_id":"fa7f57fa-11bc-40e8-af26-3891f338822e", "closing_uuid":"2496d7ba-24c6-46b4-ad12-342bc0a304fb", "event_name":"closing.signed_document_available", "signing_method":"hybrid", "created_at":1756844620, "payload":{ "external_identifiers":[ { "external_system":"other_los", "external_type":"file_number", "value":"12345" } ] }, "document_uuid":"73b72a56-eb32-9745-73e3-34856ad9d8e3", "document_type":"signed complete package" } ``` **Step Four:** Download signed document(s) 1. Enable your integration to download and store signed document files. 2. Make a GET request to the [Download a document ](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/DownloadDocument)endpoint to download the signed documents using the document\_uuid from your event. 3. Forward the documents to the appropriate post-close process and system to continue the loan on its journey to completion. Consider alerting to ensure no delays for the next person to pick up the signed documents. Here’s an example of client application code can check the `document_type` and trigger various workflows. ```python if event_body.get('event_name') == 'closing.signed_document_available': if event_body.get('document_type') == 'signed esign documents': download_esign_document(event_body.get('closing_uuid'), event_body.get('document_uuid')) elif event_body.get('document_type') == 'signed complete package': doc_id = download_full_pkg(event_body.get('closing_uuid'), event_body.get('document_uuid')) notify_post_close_workflow(doc_id) else: pass ``` ### Option 2 Same general steps as option 1 configuration, but with the following tweaks. * Use `document.created`event * Build logic to ensure you retrieve the document(s) you want out of [signed document types](https://developers.snapdocs.com/eclose/guides/connect-reference/documents) * Can also leverage the [Get List of Documents ](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetDocuments)endpoint for all documents on a closing --- ### Check Closing Statuses # Check Closing Statuses As the closing progresses, it will go through several closing statuses. To help you keep track of these milestones, we provide two ways to see the status of a closing: * *Asynchronous*: Leverage a webhook subscription that listens for the `status.changed` subscription event. When your closing changes status, you will get a notification from the listener subscribed to the event. * *Synchronous*: Use the [Get closing status](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetStatus) endpoint that returns the current status of the closing at any time. The following diagram describes how to create a subscription and receive status updates: Each Snapdocs closing includes these different status categories: * Closing status * Document status * Documents preview status * eSign status * Signing appointment status # Closing status For all closing types, the closing status shows the high-level state of a closing. During most of the closing it will be `in_progress`. | Status | Value | Description | | :-------------------- | :-------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------- | | `in_progress` | Closing is in progress. | The closing has been created. The settlement agent is collaborating with the borrower to get all documents signed and notarized. | | `signing_complete` | Closing signing has been completed. | All documents have been signed and notarized. | | `closed` | Closing is closed. | The closing is complete and closed. | | `canceled` | Closing is canceled. | The closing has been canceled. | | `canceled_for_redraw` | Closing is canceled due to full redraw. | The closing has been canceled due to a full redraw. | # Document status For all closing types, the document status shows the current condition of closing documents. | Status | Value | Description | | :--------------------- | :-------------------------------------------- | :--------------------------------------------------------------------------- | | `docs_uploading` | Documents are currently uploading to closing. | Snapdocs is waiting for documents to be uploaded. | | `docs_processing` | Documents attached to closing are processing. | Snapdocs is processing the uploaded documents. | | `final_docs_available` | Final documents are available. | Documents have been processed by Snapdocs and final documents are available. | | `awaiting_signatures` | Documents are awaiting signature. | The borrowers have not signed all of the documents. | | `signed` | Documents have been signed. | All documents have been signed and notarized. | | `canceled` | Closing is canceled. | The closing has been canceled. | # Documents preview status For all closing types, we offer the borrower a preview of their documents before their signing appointment. This field lets you track where the borrower is in their preview journey. | Status | Value | Description | | :-------------------- | :------------------------------- | :--------------------------------------------------------------------------- | | `awaiting_final_docs` | Awaiting final documents. | Awaiting final documents from Document Processing. | | `ready_for_preview` | Documents are ready for preview. | Closing documents are fully processed and ready for the borrowers to review. | | `previewed` | Documents have been previewed. | All borrowers have reviewed the documents. | | `canceled` | Closing is canceled. | The closing has been canceled. | # eSign Status In hybrid and full eClosing transactions, the closing has an eSign package. The borrower eSigns this package prior to attending the signing with a signing agent, whether in-person or Remote Online Notarization (RON). The eSign status tracks the release of the eSign package, and if all borrowers have eSigned. | Status | Value | Description | | :----------------------- | :------------------------------------------------- | :-------------------------------------------------------------------------------------- | | `awaiting_final_docs` | Awaiting final documents from Document Processing. | Awaiting final documents from Document Processing. | | `awaiting_esign_release` | Awaiting eSign release. | The eSign package has not yet been released due to eSign constraints set by the lender. | | `ready_for_esign` | Closing is ready for eSign. | The eSign package has been sent to the borrowers. | | `completed_esign` | eSign is completed. | All borrowers have finished eSigning the documents. | | `canceled_esign` | eSign is canceled. | The eSigning has been canceled due to the closing type changing. | | `not_applicable` | Status is not applicable to this closing. | No eSigning is offered on this closing. | # Signing appointment status For all closing types, there is a signing appointment. For hybrid and wet closings, there is an in-person appointment. For full eClosings, there is a Remote Online Notarization (RON) appointment. This status tracks the progress of such appointments and the return of the wet-sign package (if applicable). | Status | Value | Description | | :-------------------- | :-------------------------------- | :-------------------------------------------------------------- | | `awaiting_final_docs` | Awaiting final documents. | Awaiting final documents from Document Processing. | | `waiting_for_signing` | Waiting for signing appointment. | The signing appointment is upcoming and has not been completed. | | `completed` | Signing appointment is completed. | The signing appointment has been completed. | | `canceled` | Closing is canceled. | The signing appointment has been canceled. | # eNote status For hybrid or RON transactions with eNotes, there is an eNote which goes through its own flow and status. This status tracks the progress of the eNote in the eVault (if applicable). | Status | Value | Description | | :------------------ | :------------------------------------------------- | :----------------------------------------------------------------------------------------------- | | `preparing` | Preparing eNote. | Awaiting final eNote Document to be placed in the eVault during Document Processing. | | `ready_for_signing` | Waiting for electronic signing of the eNote. | The document is ready and waiting for electronic borrower signatures. | | `redrawn` | eNote has been recreated, as is ready for signing. | The document is ready and waiting for electronic borrower signatures, after having been updated. | | `fully_signed` | eNote has been fully signed. | The electronic signing includes the eNote with all borrower signature. | | `registered` | eNote is registered on MERS. | The eNote has been registered on the MERS eregistry. | | `unregistered` | eNote is unregistered on MERS. | The eNote which had been registered on the MERS eregistry has been unregistered. | | `consent_declined` | eNote has been declined. | The borrower has declined eSign consent for eNote, will need to close via paper note. | | `canceled_enote` | eNote is canceled. | The eNote has been canceled. | | `not_applicable` | eNote does not apply. | The closing does not include an eNote | # How to retrieve the closing\_uuid from your LOS id You can use the [Get closing uuid by external identifiers](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetUuidByExternalReferenceId) to retrieve the closing\_uuid based on the external identifiers you provided when you created the closing. For example, if your LOS is Encompass, you will send the below data: ```json [ { "external_system": "encompass", "external_type": "loan_guid", "value": 1234567 } ] ``` Note that the above is an array of objects, so that you can store multiple identifiers as necessary. --- ### Submit a Document Redraw # Submit a Document Redraw # Introduction As a lender user, you can easily request a document redraw (partial or full) without leaving your LOS. This guide walks you through the two different options for completing a redraw and how to utilize them. # Full redraw Full redraw is a Snapdocs feature that enables lenders to send a completely updated closing package and closing information to Snapdocs directly from their LOS via Snapdocs Connect. Snapdocs will then cancel the original closing, create a new closing with the new info/docs, and send intelligent communications to the settlement agent and borrower(s) to alert them of the updates. The example below illustrates the typical full redraw workflow. ## How does full redraw work? 1. An original closing exists and has a closing package. 2. A new complete package is ordered/prepared from your LOS. 3. A new closing is submitted to the [Submit a full redraw for the current closing](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/SubmitFullRedraw) endpoint utilizing the original closing’s unique identifier (UUID) as a path parameter.\ a. `/api/v1/closings/{ORIGINAL_CLOSING_UUID}/full_redraw` 4. Snapdocs matches the supplied UUID to the original closing. 5. Snapdocs cancels the original closing and places a note and audit trail on it to denote that it was cancelled as part of a full redraw. 6. A new closing is created using the closing info received in the [Submit a full redraw for the current closing](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/SubmitFullRedraw) Request and is noted in the audit trail to have been created as part of a full redraw. 7. Documents are uploaded to Snapdocs Connect via the [Upload a new document](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/UploadDocument) endpoint with the new closing’s UUID. 8. The settlement agent/notary is notified of an update to the documents when the new closing has finished processing 9. The borrower is notified they have updated documents when the new closing has finished processing. ## Other important details about full redraw * When submitting a full redraw request, the UUID of the existing closing must be supplied to the full redraw request to link the closings. * If there is no matching UUID found in Snapdocs, a not found error will be returned. * After the full redraw closing has been created, utilize this new closing’s UUID in subsequent requests to Snapdocs Connect. ## Endpoints * [Snapdocs Connect - Submit a full redraw for the current closing](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/SubmitFullRedraw) * [Snapdocs Connect - Upload a new document](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/UploadDocument) # Partial redraw Partial redraw is a Snapdocs feature that enables lenders to send a few redrawn documents to Snapdocs and have the original (outdated) documents removed and replaced. This guide walks you through how to set up the workflow, how it works, and how to use it. The below example demonstrates a typical flow of partial redraw (replace a document): ## How does partial redraw work? 1. An original closing exists and has a closing package. 2. Redrawn documents are ordered/prepared from your LOS. 3. Documents are uploaded to the Snapdocs Connect via the [Upload a new document](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/UploadDocument) endpoint with a request URL that includes the query parameter `document_type` specified as “redraw\_documents” as well as the required query parameter `document_name`. Snapdocs matches the supplied closing UUID provided to the existing closing. 4. Snapdocs classifies each redrawn document.\ a. Wet sign documents are added to the wet sign package and originals are removed if that document type was provided in the original doc package.\ b. If no borrowers have eSigned, eSign documents are added to the eSign package and originals are removed if that document type was provided in the original doc package.\ c. If any borrowers have eSigned, eSign documents are added to the wet sign package to be signed at the signing appointment. 5. Snapdocs annotates any new eSign documents. 6. The settlement agent/notary is notified if the wet sign package was updated. 7. The borrower’s package is updated if eSign documents were updated. ## Other important details about partial redraw * Currently, we cannot replace eNotes on closings that have an eNote. Instead, we will create a paper note and the eNote and have both executed. * The existing closing must match the following requirements to receive the redrawn documents properly. If any of these criteria are not met, we will reach out to the redraw sender to verify the desired outcome: * Must match the UUID sent in the "Upload a new document" request * Closing must be in an open state (not closed or canceled). * Our system will remove all documents that match the document type you sent for the redraw. For example, if you send an updated 1003 via partial redraw, our system will remove all 1003s from the original package and replace them with the new 1003(s) that you sent in the redraw package. Please ensure you send all documents of that type when you send them to Snapdocs. ## Endpoint * [Snapdocs Connect - Upload a new document](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/UploadDocument) --- ### Compliance Downloads # Compliance Downloads # Introduction Snapdocs recognizes that lenders have multiple departments with various needs once documents have been fully signed through Snapdocs. This guide describes how risk and compliance teams can download compliance documents that they must store, such as sealed electronic documents, certificates, audit trail logs. This ensures the loan has all supporting evidence it would need in case validity is questioned at some later time. ## Suggested Trigger Snapdocs supports the ability for automated retrieval of any original tamper sealed documents, eSign certificates, as well as our audit trail. By [creating a subscription](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateSubscription), you can either download each tamper-sealed document as it is made available (on `document.created`), or download them all after the closing is complete in Snapdocs (on `closing.completed`). Snapdocs strongly recommends hooking into existing Post Closing milestones to automate the below actions after the signing has completed, and the loan has progressed far enough to know there would not be follow on signing actions. * Identify a post-closing event in the LOS that fires only when the completed closing has been fully confirmed. * [Get a list of documents](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetDocuments) - to list all available documents, including tamper sealed * [Download a document](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/DownloadDocument) - repeat this for any original tamper sealed documents, certificates, or signed document set desired * [Complete closing](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CompleteClosing) - mark the Closing as completed * [Get audit trail events for the current closing](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetAudit) - store all the logged activity for future reference. ## Download eSign originals that have tamper seals / certificates Regardless of when your integration downloads the Snapdocs compliance files, use the endpoints in this section, [the documents list API](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetDocuments) to get the list of available documents. The list indicates each document's type and the URL to use for download via [the download API](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/DownloadDocument). Compliance can download and store as many documents as needed, however the following is the list of tamper-sealed documents. | Document Types | | --- | | signed esign documents | | signed enote documents | | enote audit certificate | | signed ron documents | ## Complete the Closing with the PUT call Mark closing as complete with [Complete closing](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CompleteClosing). ## Download the audit trail Snapdocs maintains a detailed audit log of events for each closing as to present a clear history from closing creation all the way to closing completion. Crucial information such as event timestamp, user name and event type are included. We also include information like user IP, browser info, and notes. The tracked event types include, but are not limited to: | | | | --- | --- | | closing.autocomplete closing.canceled closing.create closing.create\_full\_redraw closing.opt\_out closing.reopened closing.signing\_completed closing.signing\_reopened closing.show closing.updated
closing\_user.add closing\_user.remove
comment.created comment.updated | consumer\_confirmation.available
consumer\_confirmation.sent
consumer\_confirmation.unavailable
consumer\_esigned\_docusign
consumer\_preview\.closed
consumer\_preview\.finished
consumer\_preview\.opened
documents.removed
esigning.opened
esignable.title\_docs.skipped
mobile\_notary\_order.canceled
mobile\_notary\_order.created | To support the lender's auditing requirements, Snapdocs provides an API to download the entire audit trail log for a closing. Lenders can access the [Closing Audit endpoint](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetAudit) at any point during a closing's lifetime, but we expect this call to happen after the closing's signed documents have been returned. --- ### Closing Quality Control # Closing Quality Control Closing Quality Control helps lenders ensure that closing packages are complete and error-free. By detecting missing documents, pages, initials, stamps, dates, and signatures, Closing Quality Control enables lenders to automatically identify and fix issues to deliver a great borrower experience and a faster closing, all while reducing risk and operational costs. ## Subscription Events Subscribe to `quality_control` subscription events for Closing Quality Control (CQC).\ Please see [Create a subscription](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateSubscription) for the complete list of subscribable events. For example:\ `quality_control.status_changed` allows to subscribe to closing level status. | Status | Description | | :---------------------- | :---------------------------- | | `none` | CQC unavailable. | | `in_progress` | CQC in progress. | | `passed` | CQC completed without errors. | | `errors` | CQC completed with errors. | | `waiting_for_scanbacks` | CQC is waiting for scanbacks. | | `canceled` | CQC is canceled. | ## API [Closing Quality Control API](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetQualityControl) allows to retrieve document level status. --- ## Borrower Engagement (POS) Integration ### Introduction # Introduction You can keep your borrowers and customers up to date on closings running through Snapdocs in your Point of Sale (POS) system. Snapdocs refers to this as the Borrower Engagement workflow to support those who use off the shelf POS system(s) and homegrown experiences. Using Snapdocs Connect endpoints, you can integrate Snapdocs with your POS to: * Notify consumers through your POS about important events, like when it's time for them to review, eSign, and download their signed documents. * Keep consumers up to date about the notary signing agent who they will work with. * Show changes to the closing in your POS, whether it's canceled, the signing type changes, or when documents were added or replaced. * Facilitate communication by integrating with Snapdocs messaging and reminders. The guides in this section walk you through some integration use cases. Developers can work through these guides along with the details in the [API Reference](https://developers.snapdocs.com/eclose/reference) section to build a similar integration using the language of their choice. Non-technical readers, like business analysts or product managers, can review common use cases as they define what capabilities make sense in their POS. ## How Closings Work without a POS Integration Borrowers use your POS to apply for a loan, which creates a record in the lender’s LOS. After it's approved and cleared to close, the lender creates a closing in Snapdocs. After Snapdocs classifies the documents, your POS can leverage the Snapdocs Connect APIs to embed the borrower's digital closing experience in your POS. ![4248](../images/For_POS_Documentation.png "For POS Documentation.png") ## How Closings Can Work with a POS Integration You can leverage webhook listeners to check for various subscription closing events on Snapdocs. As the closing moves through different statuses, events occur. Events can include the closing is ready for preview, ready for eSign, or the signed documents are available for download. Use the webhooks that you build to check for these events. When they happen, enable a button in your POS, send an email from the POS, or otherwise update the borrower.\ Here’s an example: 1. The POS creates webhook listeners to check for subscription events at Snapdocs. 2. Snapdocs Connect broadcasts closing events, and the webhook listeners handle the events. 3. The POS calls Snapdocs Connect to retrieve more information about the closing. 4. The POS uses the information to notify the borrower via email or SMS about the closing tasks for them to complete. 5. The POS also uses the information to display closing borrower tasks within the POS system. 6. After the borrower completes the tasks, Snapdocs Connect broadcasts events to let the webhook listeners integrated with the POS know which actions occurred so they can notify the borrower and update the application. ![4180](../images/For_POS_Documentation_1.png "For POS Documentation (1).png") --- ### API Workflows # API Workflows Borrower engagement systems workflow
# Borrower Engagement Workflows The following diagrams outline the orchestration of data and actions across our Borrower Engagement integration. To ensure a seamless experience for the end consumer, we have mapped the events and expected actions in order to give the Borrower the same experience through closing that they've had since applicaction and underwriting. --- ### Technical Setup Guide # Technical Setup Guide Setting up a communication between your POS and Snapdocs Connect will enable this seamless experience. Reference the [eClose API reference](https://developers.snapdocs.com/eclose/reference). We also want to call out that most integrations will start by connecting with keys in our demo environments listed below: | API | URL | | --- | --- | | Token API | `https://login.demo-eks.snpd.io/oauth/token` | | Snapdocs Connect API | `https://api.cs-demo0.snpd.io/` | | Audience | `https://api.*.snpd.io` | To ensure a trouble-free experience when testing the integration in our demo environment, we will require whitelisting of the IP addresses that will be used to visit the above domains. This guide is not meant to replace the API details in the documentation. It serves as a setup plan for implementing the Snapdocs Embedded POS Integration, which includes steps required to complete the integration and information needed from your company. ## Borrower SSO Instructions (OAuth or SAML 2.0) If your company plans on using the POS login for authentication, please take a look at the following guides. Please follow the instructions on the following pages * [Borrower SSO Instructions (OAuth)](https://developers.snapdocs.com/eclose/guides/security/borrower_sso_instructions_oauth_2) * [Borrower SSO Instructions (SAML 2.0)](https://developers.snapdocs.com/eclose/guides/security/borrower_sso_instructions_saml_20) ## POS Keys Handling multiple lender Keys for your POS connections is important if you have plans to integrate with multiple lenders. If your integration is for your singular POS, the below best practice suggestions can still apply. We will provide you a new key and secret for each lender that will be using the POS integration. We will specify if this is a production key, or if it works with the demo environment mentioned above. We recommend having some sort of lender Keys storage in the POS listener, such that your API calls will authenticate based on the lender of the webhook from Snapdocs. The SSO and POS Key implementation is expected to be done per lender for the POS integration. ## Create Subscriptions Using an authenticated session you will [Create a subscription](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateSubscription) to the events you want to listen to via webhooks. This will allow you to receive real-time updates on closings so your integration can automatically trigger interactions for the borrower. --- ### Integrate with Borrower Preview Events # Integrate with Borrower Preview Events When documents for a closing are ready for borrowers to preview, Snapdocs Connect broadcasts a message to the webhook listener that you set up for those events. After receiving the message, you can call our APIs to retrieve the borrower information and the secure token that you can use to construct and document preview link to provide to the borrower. Snapdocs Connect will send a subsequent webhook notification to inform you that the preview has been completed after the borrower previews the document. ## Borrower Preview Subscription Events | Subscription Event | Subscription Event Description | | :---------------------------------- | :--------------------------------------------------------- | | borrower.preview\_available | Closing documents are available for a borrower to preview. | | borrower.preview\_complete | A borrower has previewed closing documents. | | borrower.redraw\_preview\_available | Redraw documents are available for a borrower to preview. | **Step 1: Create a webhook listener**\ Create a webhook listener (or HTTP API) to receive the `borrower.preview_available` and `borrower.preview_complete` events from Snapdocs Connect. You’ll use the URL as the listener `webhook_url` in the next step. Note: Make sure to configure the webhook to respond to events with a 200 response. Otherwise, Snapdocs will attempt to redeliver the webhook event. See [Subscriptions and Webhooks](https://developers.snapdocs.com/platform/guides/webhooks/subscriptions_api) for more information. **Step 2: Subscribe to the borrower preview events**\ Make a POST request to the [Create a subscription](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateSubscription) endpoint to register the webhook URL and the `borrower.preview_available` and `borrower.preview_complete` events.\ A notification will be sent to the webhook listener using this subscription when the uploaded documents for the closing are ready for borrowers to preview or when the borrower has previewed. **Step 3: Handle the event payload**\ Write custom application code to process the response to receiving the `borrower.preview_available` event, which is triggered when closing documents are ready to be previewed. For example, enable a button in the POS to allow the borrowers to access the documents for preview. Here’s an example of a `borrower.preview_available` webhook message from Snapdocs Connect: ```json { "event_id": "48a2cbcb-a88b-4e8c-a867-07fb6bd5aled", "closing_uuid": "9262a37e-85b9-27d8-8622-da463e58b49b", "event_name": "borrower.preview_available", "created_at": 1638416525, "payload": { "external identifiers": [{ "external_system": "other_los", "external_type": "loan_guid", "value": "1234" }], "borrower_uuid": "767542da-3b5e-628e-b9bd-284d97a3b6e9" } } ``` After the borrower previews the document, you will receive another notification that the `borrower.preview_completed` event occurred. ## Multiple Borrowers When multiple borrowers are present, Snapdocs notifies you about each borrower’s preview activity. You can identify the borrower in question using the provided `borrower_uuid` in the message. This enables you to provide relevant updates to each borrower so they can proceed to their next steps. ## Constructing the Document Preview Access Link Call the [Get a list of Borrower Document Statuses](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetBorrowers) endpoint to retrieve a unique `access_token` to construct a URL that directs the borrower to preview their document. After retrieving the `access_token`, plug it into the URLs below to create a preview link. **Demo Environment**\ `https://app.cs-demo0.snpd.io/secure_access?secure_token=&act=preview&redirect_url=` **Production Environment**\ `https://app.snapdocs.com/secure_access?secure_token=&act=preview&redirect_url=` **Redirect the Borrower to your Dashboard**\ The `&redirect_url=` at the end of the URL brings the borrower back to your dashboard, or any other desired page upon completion of their previewing of the documents. Clicking the back button in the upper left hand corner of the preview screen will send them to the `redirect_url` provided and log them out of Snapdocs. --- ### Integrate with Borrower eSign Events # Integrate with Borrower eSign Events When documents for a closing are ready for borrowers to esign, Snapdocs Connect broadcasts a message to the webhook listener that you set up for those events. After receiving the message, you can call our APIs to retrieve the borrower information, including the secure token that you can use to construct an eSign link to provide the borrower. After the borrower esigns the document, Snapdocs Connect sends a subsequent webhook notification to inform you that the esign has been completed. | Subscription Events | Subscription Event Description | | --- | --- | | borrower.esigning\_available | Closing documents are available for a borrower to eSign. | | borrower.esigning\_complete | All borrowers have eSigned the closing package. | | borrower.esign\_reminder | Borrower is reminded to eSign. | | borrower.redraw\_esigning\_available | Redraw documents are available for a borrower to eSign. | ## How to subscribe to Borrower eSign Events **Step 1: Use a webhook listener**\ Create a webhook listener (or HTTPS API) to receive the `borrower.esigning_available` and `borrower.esigning_complete` events from Snapdocs Connect. You’ll use the URL as the listener `webhook_url` in the next step. Note: Make sure to configure the webhook to respond to events with a 200 response. Otherwise, Snapdocs will attempt to redeliver the webhook event. See [Subscriptions and Webhooks](https://developers.snapdocs.com/platform/guides/webhooks/subscriptions_api#respond-then-process) for more information. **Step 2: Subscribe to the borrower eSign events**\ Make a POST request to the [Create a subscription](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateSubscription) endpoint to register the webhook URL and the `borrower.esigning_available` and `borrower.esigning_complete` events.\ With this subscription, when the uploaded documents for the closing are ready for borrowers to eSign or when the borrowers has completed the esigning, Snapdocs sends a notification to the webhook listener. **Step 3: Handle the event payload**\ Write custom application code to process the response to receiving the `borrower.esigning_available` event, which is triggered when closing documents are ready to be eSigned. Here’s an example of a `borrower.esigning_available` webhook notification from Snapdocs Connect: ```json { "event_id": "48a2pfid-a88b-4e8c-a867-07fb6bd5aled", "closing_uuid": "7262a37e-85b9-27d8-8622-da463e58b49b", "event_name": "borrower.esigning_available", "created_at": 1638416525, "payload": { "external identifiers": [{ "external_system": "other_los", "external_type": "loan_guid", "value": "1234" }], "borrower_uuid": "767542da-3b5e-628e-b9bd-284d97a3b6e9" } } ``` After the borrower esigns the document, you will receive another notification that the `borrower.esigning_completed` event occurred. ## Multiple Borrowers When multiple borrowers are present, Snapdocs notifies you about each borrower’s eSigning activity. You can identify the borrower in question using the provided `borrower_uuid` in the message. This enables you to provide relevant updates to each borrower so they can proceed to their next steps. > 📘 The `borrower.esigning_completed` event does not have the 'borrower\_uuid' in the message since it is broadcasted after all borrower's have esigned. ## Esigning Reminders Subscribe to the `borrower.esign_reminder` event so you are informed when you need to notify the borrower to complete their eSigning. This occurs in the following cases: * The borrower has yet to eSign and their notary appointment is 3 hours way * Someone, for example, a Loan Officer, clicks the “remind borrower” button on the Snapdocs interface to send a reminder notification to the borrower to complete their eSigning ## Constructing the Esign Access Link Call the [Get a list of Borrower Document Statuses](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetBorrowers) to retrieve a unique `access_token` to construct a URL that directs the borrower to eSign their documents. After retrieving the `access_token`, plug it into the URLs below to create an eSigning link. **Demo Environment**\ `https://app.cs-demo0.snpd.io/secure_access?secure_token=&act=preview&redirect_url=` **Production Environment**\ `https://app.snapdocs.com/secure_access?secure_token=&act=preview&redirect_url=` **Redirect the Borrower to your Dashboard**\ The `&redirect_url=` at the end of the URL brings the borrower back to your dashboard, or any other desired page upon completing their eSigning. Clicking the back button in the upper left hand corner of the eSigning screen will send them to the `redirect_url` provided and log them out of Snapdocs. --- ### Integrate with Notary Events # Integrate with Notary Events When a notary is requested to notarize a closing, Snapdocs Connect broadcasts a message to the webhook listener that you set up for notary events. These events cover all steps of the notarization process. After receiving a message from Snapdocs Connect regarding the notary appointment, you can call our [Get Notary](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetNotary) endpoint to retrieve additional notary information pertaining to the closing. **Notary Subscription Events** | Subscription Events | Subscription Event Description | | --- | --- | | notary.order\_created | A notary order has been created | | notary.assigned | A notary has been assigned | | notary.appointment\_confirmed | A notary appointment has been confirmed | | notary.order\_completed | A notary order has been completed | | notary.order\_did\_not\_sign | A notary order was not signed | | notary.order\_canceled | A notary order has been canceled | | notary.appointment\_confirmation\_status\_changed | A notary appointment confirmation status changed | **Step 1: Use a webhook listener**\ Create an HTTPS webhook listener to receive the notary events from Snapdocs Connect. You’ll use the URL as the listener `webhook_url` in the next step. Note: If the webhook arrives successfully, please respond with a HTTP 200 response. Please use a separate HTTP status code if the webhook does not arrive successfully. See [webhook responses](https://developers.snapdocs.com/platform/guides/webhooks/subscriptions_api#respond-then-process). **Step 2: Subscribe to the notary events**\ Make a POST request to the [Create a subscription](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateSubscription) endpoint to register the webhook URL and the notary subscription events. With this subscription, we will send you a notification to the webhook listener when notary changes occur on the closing. **Step 3: Handle the event payload**\ Write custom application code to process the response to receiving the notary subscription event. --- ### Integrate with Other Events # Integrate with Other Events Here’s a collection of additional Subscription Events we strongly recommend you subscribe to in order to support the full closing workflow in your POS system. ## Closing Events If there are changes to the closing, you can subscribe to the following events to be notified of these changes. **Closing Subscription Events** | Subscription Events | Subscription Event Description | | --- | --- | | closing.completed | Closing has been completed | | closing.canceled | Closing has been canceled | | closing.type\_converted | Closing type was converted | | closing.canceled\_from\_redraw | Closing was canceled from full redraw | | closing.created\_from\_redraw | Closing is created from a full redraw | | closing.appointment\_details\_changed | Closing appointment details have changed | ## Opt Out/Opt In to eSign In the event that a borrower wants to opt out of eSigning from your dashboard, use the Borrower Opt In/Out endpoint to inform us of that change. Conversely, we will broadcast a webhook notification containing either the `borrower.opted_in` or `borrower.opted_out` events to inform you if the borrower changes their status on our end. **Borrower Opt In/Out Subscription Events** | Subscription Events | Subscription Event Description | | --- | --- | | borrower.opted\_out | Borrower opted out of eSigning | | borrower.opted\_in | Borrower opted back into eSigning | ## Document Events You can subscribe to be notified when signed documents have been generated for the borrower to review or download. > 📘 Document download capabilities can be limited by Lender. If the partnering Lender does not allow for borrowers to download their documents, the POS will not be able to download the document either. **Document Subscription Events** | Subscription Events | Subscription Event Description | | --- | --- | | document.created | A closing document has been generated | # Redraw These events are broadcasted in the event of a closing [redraw](https://developers.snapdocs.com/eclose/guides/lender-integration/redraw_guide). **Redraw Subscription Events** | Subscription Events | Subscription Event Description | | --- | --- | | borrower.redraw\_preview\_available | Redraw documents are available for a Borrower to preview | | borrower.redraw\_esigning\_available | Redraw documents are available for a borrower to eSign | | closing.canceled\_from\_redraw | Closing was canceled from full redraw | | closing.created\_from\_redraw | Closing is created from a full redraw | # Comments **Comment Subscription Events**\ Subscribe to the following to be notified when a comment has been added to a closing. | Subscription Events | Subscription Event Description | | --- | --- | | closing.comment\_created | Comment added to a closing. | --- ## Snapdocs Connect Reference ### Overview/FAQ Welcome to **Snapdocs Connect**, a solution for your organization to integrate your technology stack with Snapdocs for creating, tracking and updating transactions. Our API is organized around REST. It contains predictable resource-oriented URLs, accepts form-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs. # Overview/FAQ **Q: My company would like to adopt Snapdocs Connect, how can we do that?** To adopt Snapdocs Connect, reach out to your Snapdocs customer success manager to procure the Authentication details, which includes Client ID, Client Secret and Scopes. The Authentication details will be shared with you via the Gmail Confidential Mode. **Q: What are Client ID, Client Secret and Scopes for?** These unique info will allow Snapdocs to authenticate your company anytime a POST request is made to [Generate-JWT-Token endpoint](https://developers.snapdocs.com/eclose/reference/authentication/operations/generateToken) . Once the call is made, the response will specify how long the bearer token is valid for. We recommend reusing the bearer token until it is expired, then make another call to generate a new token. After you retrieve the token, the next step would be to create the actual closing. This can be done by making a request to [Create-New-Closing endpoint](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateClosing) . **Q: How do I upload documents to the closing created by Snapdocs Connect?** To upload documents, make a request to [Upload-New-Document endpoint](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/UploadDocument). You can upload one or more documents at the same time. There is no limit on how many documents can be uploaded to a closing. **Q: How do I retrieve documents from a closing?** Make a request to [List-Documents endpoint](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetDocuments). After the call is authenticated, the system will return a list of documents available for the closing, as well as the closing URL. Use this closing URL to [Download-Document endpoint](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/DownloadDocument) the documents from the closing. **Q: How does Snapdocs know when to start processing the documents?** After you have uploaded all the documents to the closing, make a request to the [Submit documents](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/SubmitDocuments). The call signifies that all the documents associated with the closing have been uploaded, and Snapdocs’s Doc Processing can begin. **Q: What if the system does not recognize the API call to the endpoint /mark_finished_uploading_docs?** In this case, the system will return a 500 Error status code. If the error still occurred after multiple attempts, contact your Snapdocs Customer Success Manager for assistance. **Q: Why did I get the error code 401 when making an API call?** The 401 Unauthorized Error is an HTTP response status code indicating that the request sent from you could not be authenticated. When this happens, check your Client ID, Client Secret and Scopes included in the header of the API call to ensure they are correct. If the error still occurred after multiple attempts, contact your Snapdocs Customer Success Manager for assistance. **Q: Why did I get the error code 403 when making an API call?** The 403 Forbidden Error is an HTTP response status code indicating that you are trying to access a closing that was not created by your company. When this happens, check the reference_id of the closing you are trying to access to ensure it is your company’s closing. **Q: Why did I get the error code 500 when making an API call?** If the error still occurred after multiple attempts, contact your Snapdocs Customer Success Manager for assistance. **Q: What is closing_uuid?** The unique identifier for a closing. **Q: Is there a scenario where we would need to re-upload everything?** This could possibly happen in a redraw situation where some documents need to be replaced. We’re working on simplifying this process. **Q: Are Snapdocs webhooks secure?** Our webhooks are signed with HMAC hash-based message authentication code SHA an contains three headers: `'X-Authorization-Digest'` `'X-Authorization-Timestamp'` `'X-Authorization-Signature'` When a subscription is created, we return an HMAC key in the body of the response. This HMAC key can be used to decode the signature by utilizing the digest algorithm for decryption. The decoded signature contains the timestamp and payload at the time of creation. This allows the user to verify that the payload in the message was not tampered with during transmission. **Q: Do I want to set up the webhook for my company?** Webhooks provide a powerful method to track the state of transactions and to take actions within your Snapdocs account. Review these best practices to ensure your webhooks remain secure and function seamlessly with Snapdocs Connect. * Event type -- Your webhook endpoints should be configured to receive only the types of events required by your integration. Listening for extra events (or all events) will put undue strain on your server and is not recommended. * Handle duplicate events -- Webhook endpoints might occasionally receive the same event more than once. We advise you to guard against duplicated event receipts by making your event processing idempotent. * Verify events are sent from Snapdocs -- Use webhook signatures to verify if the events are sent from Snapdocs. **Q: Should we send a response after receiving a webhook, if so in what format?** We recommend you to respond with status code 200. You can see examples of Success/Failure responses [here](https://developers.snapdocs.com/platform/guides/webhooks/subscriptions_api) --- ### Closings As a Snapdocs user, you can create a closing yourself! All closings created by Snapdocs users will have the user’s company branding. When creating a closing you will have a couple of different signing methods to choose from. To know what signing methods are currently supported for closings created via Snapdocs Connect, please reach out to your Snapdocs Customer Success Manager. You may also request additional information regarding the key benefits of each closing type. --- ### Documents Once you have created the closing and uploaded the closing documents, Snapdocs will make sure all participants are notified of the closing and documents are made available. > 📘 Document upload file size limit > > The max file size for uploads through the API is limited to 60MB Our world-class Doc Classifier is capable of programmatically identifying the document classification of each page of a closing documents, then splits those documents into different PDFs according to their contents and intended use. ## Possible Document Types | Document Type | | :-------------------------------------- | | original documents | | original combined documents | | unsigned wet package with cover page | | signed wet documents | | signed esign documents | | signed enote documents | | enote audit certificate | | signed ron documents | | signed complete package | | redraw documents | | rush documents | | unsigned wet documents | | unsigned esign documents | | unsigned enote documents | | dual borrower signed esign documents | | trailing combined documents | | individual signed documents | | individual incremental signed documents | | individual trailing documents | | qc review reports | --- ## Authentication ### Closings Scopes control which eClose endpoints a token can call. Your Customer Success Manager provides the scope list your credentials carry; [OAuth 2.0 client credentials](https://developers.snapdocs.com/platform/guides/authentication/oauth2_client_credentials) covers how scopes ride the token request. ### Lenders | Scope | Endpoint | | :--- | :--- | | `closings:create` | [Create a new closing](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateClosing)
[Submit a full redraw for the current closing](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/SubmitFullRedraw) | | `closings:show` | [Get a single closing](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetClosing) | | `closings:mark_finished_uploading_docs` | [Signify documents uploading for a closing is complete](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/MarkFinishedUploadingDocs) | | `documents:create` | [Upload a new document](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/UploadDocument) | | `documents:index` | [Get a list of documents](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetDocuments) | | `documents:show` | [Download a document](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/DownloadDocument) | | `documents:submit` | [Submit documents](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/SubmitDocuments) | | `subscriptions:create` | [Create a subscription](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/CreateSubscription) | | `subscriptions:index` | [Get all the subscriptions](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetSubscriptions) | | `subscriptions:destroy` | [Delete a subscription](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/DeleteSubscription) | ### Point of Sale | Scope | Endpoint | | :--- | :--- | | `closings:external_look_up` | [Fetch closing uuid by external identifiers](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetUuidByExternalReferenceId) | | `borrowers:index` | [Get a list of Borrower Document Statuses](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetBorrowers) | ### Reporting | Scope | Endpoint | | :--- | :--- | | `borrower_activities:index` | [Get borrower activities](https://developers.snapdocs.com/eclose/reference/reporting/operations/BorrowerActivitiesIndex) | | `transaction_statuses:index` | [Get transaction statuses](https://developers.snapdocs.com/eclose/reference/reporting/operations/TransactionStatusesIndex) | | `users:index` | [Get users](https://developers.snapdocs.com/eclose/reference/reporting/operations/UsersIndex) | ### Scope families Tokens may also carry scopes in the `closings:` family form, a space-delimited list such as: ```ruby # Closings closings:read:closings closings:write:closings # Documents closings:read:documents closings:write:documents # Borrowers closings:read:borrowers # Esign closings:write:esign # Notary closings:read:notary # Appointment closings:read:appointment closings:write:appointment # Subscriptions closings:read:subscriptions closings:write:subscriptions # Comments closings:read:comments closings:write:comments ``` --- ### Reporting Scopes Possible Reporting scopes include: `borrower_activities:index` `users:index` `transaction_statuses:index` --- ## Webhooks ### Subscriptions You can configure subscriptions via the API to be notified about events regarding your Snapdocs company or connected accounts. --- ### Subscribable events # Subscribable events [block:callout] { "type": "warning", "body": "If you require extra contextual information or wish to subscribe to webhook notifications on behalf of multiple Snapdocs companies, our recommendation is to include this extra information within the **webhook_url**.\n\nFor example, if ‘xyzpos.com’ wishes to subscribe to closings events from two companies that it identifies as lender-X and bank-z , you would supply the following URLs to Snapdocs when subscribing to the events:\n\n- https://xyzpos.com/snapdocs-listener-endpoint/lender-X-intentifier/closing-event\n- https://xyzpos.com/snapdocs-listener-endpoint/bank-Z-intentifier/closing-event", "title": "" } [/block] [block:parameters] { "data": { "h-0": "Subscription Events", "0-0": "**borrower.esigning_available**", "1-0": "**borrower.esigning_complete**", "2-0": "**borrower.preview_available**", "3-0": "**borrower.preview_complete**", "4-0": "**borrower.redraw_preview_available**", "5-0": "**borrower.redraw_esigning_available**", "6-0": "**borrower.opted_out**", "7-0": "**borrower.opted_in**", "8-0": "**borrower.esign_reminder**", "9-0": "**borrower.ron_kba_passed**", "10-0": "**borrower.ron_kba_failed**", "11-0": "**borrower.ron_idv_passed**", "12-0": "**borrower.ron_idv_failed**", "13-0": "**borrower.ron_signing_completed**", "14-0": "**closing.created**", "15-0": "**closing.completed**", "16-0": "**closing.canceled**", "17-0": "**closing.canceled_from_redraw**", "18-0": "**closing.created_from_redraw**", "19-0": "**closing.type_converted**", "20-0": "**closing.appointment_details_changed**", "21-0": "**document.created**", "22-0": "**notary.order_created**", "23-0": "**notary.order_canceled**", "24-0": "**notary.appointment_confirmed**", "25-0": "**notary.order_completed**", "26-0": "**notary.order_did_not_sign**", "27-0": "**notary.assigned**", "28-0": "**notary.attachment_delivery_status_changed**", "29-0": "**notary.appointment_confirmation_status_changed**", "30-0": "**quality_control.status_changed**", "31-0": "**status.changed**", "32-0": "**closing.ron_signing_available**", "33-0": "**closing.ron_signing_started**", "34-0": "**closing.ron_signing_canceled**", "35-0": "**closing.ron_signing_did_not_sign**", "36-0": "**closing.enote_ready_for_signing**", "37-0": "**borrower.enote_signing_available**", "38-0": "**closing.enote_signed**", "h-1": "Event Description", "0-1": "Closing documents are available for a Borrower to eSign.", "1-1": "A Borrower has eSigned a closing package.", "2-1": "Closing documents are available for a Borrower to preview.", "3-1": "A Borrower has previewed closing documents.", "4-1": "Redraw documents are available for a Borrower to preview.", "5-1": "Redraw documents are available for a borrower to eSign", "6-1": "Borrower opted out of esigning.", "7-1": "Borrower opted back into esigning.", "8-1": "Borrower is reminded to esign.", "9-1": "A Borrower passed knowledge-based authentication for a remote online notarization.", "10-1": "A Borrower failed knowledge-based authentication for a remote online notarization.", "11-1": "A Borrower passed identity verification for a remote online notarization.", "12-1": "A Borrower failed identity verification for a remote online notarization.", "13-1": "A Borrower finished signing their remote online notarization session.", "14-1": "Closing created.", "15-1": "Closing has been completed.", "16-1": "Closing canceled.", "17-1": "Closing was canceled from full redraw.", "18-1": "Closing is created from a full redraw.", "19-1": "Closing type was converted", "20-1": "Closing appointment details have changed", "21-1": "A signed closing document has been generated.", "22-1": "A notary order has been created.", "23-1": "A notary order has been canceled.", "24-1": "A notary appointment has been confirmed.", "25-1": "A notary order has been completed.", "26-1": "A notary order was not signed.", "27-1": "A notary has been assigned.", "28-1": "A notary order's attachment delivery status changed.", "29-1": "A notary appointment confirmation status changed.", "30-1": "Closing quality control status changed.", "31-1": "Closing status changed.", "32-1": "The remote online notarization is available for the borrowers to schedule or join. Fires whether the package was scheduled or pre-assigned.", "33-1": "A remote online notarization session has started. Fires once per session, so a closing whose session is split sees it more than once.", "34-1": "The remote online notarization was canceled before the session started.", "35-1": "The remote online notarization session started but was not signed.", "36-1": "The eNote is ready to be signed.", "37-1": "The eNote is available for a Borrower to sign.", "38-1": "The eNote has been signed by all signers." }, "cols": 2, "rows": 39 } [/block] --- ### The Webhook Event Object # The Webhook Event Object | Key | Type | Description | | ------ | ------ |------ | | `event_id` | String | A unique identifier for the event object. | | `closing_uuid` | String | The internal unique identifier for a Snapdocs closing. | | `event_name` | String | The name of the event being broadcast via the webhook. | | `created_at` | Integer | The Unix timestamp for when the event was generated. | | `payload` | Object | An object containing additional information of the event. | | `external_identifiers` | Object | A map of `external_identifiers` to correlate those identifiers to the event. | ```json Example Webhook Event Object { "event_id": "572f592a-fbec-49d9-a28a-88d8e38175be", "closing_uuid": "d679e2ad-278d-e547-9756-84639ba3865b", "event_name": "borrower.preview_available", "created_at": 1618936005, "payload": { "external_identifiers": [{ "external_system": "other_los", "external_type": "file_number", "value": "1234" }] } } ``` **How can we verify a webhook's integrity and authenticity?** Every webhook is signed with a hash-based message authentication code (HMAC) carried in three `X-Authorization-*` headers. The HMAC key is returned in the body of the response when a subscription is created, and is also available from the [Get Subscriptions endpoint](https://developers.snapdocs.com/eclose/reference/snapdocs-connect/operations/GetSubscriptions). Verification steps and code samples in four languages are on [Webhook security](https://developers.snapdocs.com/platform/guides/webhooks/webhook_security). **Should we send a response after receiving a webhook, and in what format?** Respond with HTTP 200 to indicate the webhook was received; use an appropriate error status otherwise. ```json Success HTTP/1.1 200 OK Content-Type: application/json { "status": "OK", "code": 200, "message": "webhook received successfully" } ``` ```json Failure HTTP/1.1 400 Bad Request Content-Type: application/json { "status": "Bad Request", "code": 400, "message": "[reason for failure]" } ``` --- ## Reporting ### Introduction Welcome to **Snapdocs Data API**, a solution for your organization to integrate your LOS with Snapdocs for data about your closings. Our API is organized around REST. It contains predictable resource-oriented URLs, accepts form-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs. --- ### Transaction Statuses Get the current statuses of a given closing. --- ### The Transaction Statuses Object # The Transaction Statuses Object | Key | Type | Description | | ------ | ------ |------ | | data | Array | The array storing storing individual transaction status results. | | appointment_date_time | String | The original appointment date and time sent by the Lender for closing creation. If there are changes in the appointment date and time, this field will be populated accordingly. | | closing_created_at | String | The timestamp when the closing was created in Snapdocs system. | | closing_type | String | The closing type sent by the Lender associated with each closing. | | esign_status | String | The current status of eSigning. | | esigning_completed_date_time | String | The timestamp when the Borrower has completed eSigning. There will be a row for each Borrower. | | file_number | String | The file number / loan number which was sent to Snapdocs for each closing. | | id | Integer | The internal ClosingID. | | last_modified_date_time | String | The timestamp when any of the above fields are updated in the target table. This will be the timestamp used in query to find incremental updates. | property_state | String | This field will be used in the near future. | settlement_office_email_address | String | The email address of the Settlement office handling the closing. | settlement_office_name | String | The name of the Settlement office handling the closing. | signer_first_name | String | The Borrower's first name of this closing. There will be a row for each Borrower. | signer_last_name | String | The Borrower's last name of this closing. There will be a row for each Borrower. | status | String | The current status of the closing in Snapdocs system. | status_change_date_time | String | The latest timestamp when the transaction status was updated to either `Close`, `Canceled` or `Reopen`. | wet_sign_status | String | The current status of the Wet sign. | meta | Object | The object storing metadata about the returned transaction status results. | current_page | Integer | The current page of the paginated results. | next_page | Integer | The next page number of the paginated results. | page_size | Integer | The number of results per page. | total_count | Integer | The total number of results. | total_pages | Integer | The total number of pages of paginated results. --- ### Borrower Activities Get all analytics measurement data associated with all the Borrower activities of a particular closing. --- ### The Borrower Activities Object ## The Borrower Activities Object | Key | Type | Description | | ------ | ------ |------ | | data | Array | The array storing individual Borrower activities results. | | id | Integer | The internal unique identifier for a Snapdocs Closing. | | appointment_date_time | String | The new timestamp if the Settlement Agent made changes to the original appointment date time sent in for Closing creation. | | appointment_original_date_time | String | The original appointment date and time sent by the Lender for Closing creation. If there are changes in the appointment date and time, this field will be populated accordingly. | | closing_created_date_time | String | The timestamp when the Closing was created in Snapdocs system | | closing_type | String | The closing type sent by the Lender associated with each Closing. | | doc_preview_available_date_time | String | The timestamp when the document was sent to the Borrower for review. There will be a row for each Borrower. | | doc_preview_completed_date_time | String | The timestamp when the Borrower has reviewed the available document. There will be a row for each Borrower. | | esign_status | String | The current status of eSigning for each Borrower. | | esigning_completed_date_time| String | The timestamp when the Borrower has completed eSigning. There will be a row for each Borrower. | | esigning_start_date_time | String | The timestamp when the Borrower starts the eSigning process. There will be a row for each Borrower. | | file_number | String | The file number / loan number which was sent to Snapdocs for each Closing. | | last_modified_date_time | String | The timestamp when any of the above fields are updated in the target table. This will be the timestamp used in query to find incremental updates.| | property_state | String | *This field will be used in the near future.*| | settlement_office_email_address | String | The email address of the Settlement office handling the Closing. | | settlement_office_name | String | The name of the Settlement office handling the Closing. | | signer_email_address | String | The Borrower's email of this Closing. There will be a row for each Borrower. | | signer_first_name | String | The Borrower's first name of this closing. There will be a row for each Borrower. | | signer_id| String | The unique UserID for each Borrower. | |signer_last_name | String | The Borrower's last name of this Closing. There will be a row for each Borrower. | | signer_removed_date_time | String | The timestamp when the Borrower was deactivated in the Snapdocs system and a new Borrower was created. | | status | String | The current status of the Closing in Snapdocs system. | | status_change_date_time | String | The latest timestamp when the transaction status was updated to either `Close`, `Canceled` or `Reopen`. | | wet_sign_status | String | The current status of the Wet sign. | | meta | Object | The object storing metadata about the returned Borrower activities results. | | current_page | Integer | The current page of the paginated results. | | next_page | Integer | The next page number of the paginated results.| | page_size | Integer | The number of results per page.| | total_count| Integer | The total number of results.| | total_pages | Integer | The total number of pages of the paginated results.| --- ### Users Get all recorded users activities related to your organization. --- ### The Users Object # The Users Object | Key | Type | Description | | ------ | ------ |------ | |data| Array | The array storing individual user results. | |first_name| String | The first name of the Lender user who logged into Snapdocs system. | |last_name| String | The last name of the Lender user who logged into Snapdocs system. | |email_address| String | The email address of the Lender user who logged into Snapdocs system. | |role| String | The role of the Lender user logging in (e.g., Closure, Admin, Loan Officer, etc.) | |isactive| Boolean | The current status of the Lender user. Display `True` if it's an active user. Display `False` if it's an Inactive users. | |last_action_date_time| String | The last time this Lender user logged into the platform. This timestamp will be used to filter query using Start and End Timestamp in the API request. | |meta| Object | The object storing metadata about the returned user results. | |current_page| Integer | The current page of the paginated results. | |next_page| Integer | The next page number of the paginated results. | |page_size| Integer | The number of results per page. | |total_count| Integer | The total number of results. | |total_pages| Integer | The total number of pages of paginated results. | ---