# JPMC-PDP Documentation from https://developer.payments.jpmorgan.com # Upload documents During the onboarding verification process, you may need to provide additional documents, such as proof of identity, on behalf of your clients. To provide these documents, you need to: 1. Check if a document has been requested with a GET request to /onboarding/v1/clients/{id} or /onboarding/v1/parties/{id}. If so, the client status changes from REVIEW_IN_PROGRESS to INFORMATION_REQUESTED. If you use webhooks, you can also get this information from your [notification subscription](/docs/commerce/optimization-protection/capabilities/notifications/notification-types#digital-onboarding-events). 2. Identify and display the requested documents with a GET request to /onboarding/v1/document-requests/{id}. 3. Upload documents in a POST request to /onboarding/v1/documents. 4. Submit the uploaded documents for review with a POST request to /onboarding/v1/document-requests/{documentRequestId}/submit. Each step in this process must be conveyed clearly to your clients, including specific wording that must be displayed. ## Check if a document has been requested Documents may be requested at both the client and party level in the onboarding process. If you subscribe to onboarding notifications, you receive a notification when information is requested. ```json { "eventId": "905", "eventType": "CLIENT_ONBOARDING", "resourceType": "CLIENTS", "resource": "{\"id\":\"3000005555\",\"status\":\"INFORMATION_REQUESTED\",\"hasOutstandingInformation\":true,\"customerIdentityStatus\":\"INFORMATION_REQUESTED\"}" } ``` You can then check if documents are required by sending a `GET` request to one or both of these endpoints: - /onboarding/v1/clients/{id} - in the response, you can see document requests on your client by inspecting the client's outstanding.documentRequestIds field. - /onboarding/v1/parties/{id} - in the response, you can see document requests for your party by inspecting the party's validationResponse field. In this sample, you can see that the client must provide documents using the `documentRequestId` 30700. ```json { "id": "{clientId}", "outstanding": { "documentRequestIds": [ "30700" ] } } ``` Here, you can see that a party must provide documents that correspond to the `documentsRequestId` 57777: ```json { "id": "{partyId}", "validationResponse": [ { "validationType": "ENTITY_VALIDATION", "validationStatus": "NEEDS_INFO", "documentRequestIds": [ "57777" ] } ] } ``` ### About the document request ID The document request ID is used as the identifier for all documents required in the request. For example, the ID 57777 may contain a request for multiple documents and types, such as a passport and a utility bill. The `documentRequestId` is used multiple times throughout this process. ## Identify and display the requested documents To get the document request details to view what types of documents are required, send a `GET` request to `/onboarding/v1/document-requests/{id}` using the document request ID from `documentRequestIds` in the path. ```curl curl --request GET \ --url https://api-mock.payments.jpmorgan.com/onboarding/v1/document-requests/57777 \ --header 'Accept: application/json' \ --header 'token: {authenticationToken}' ``` Sample response: ```json { "id": "57777", "createdAt": "2025-11-18T12:28:11.232Z", "description": "To verify your identity, please provide one or more of the following documents. Documents must be unexpired and show Full legal Name, Address and Date of Birth. If address on your identification document is not current, please additionally provide a Utility Bill or Bank Statement dated within last 6 months.\nDrivers license\nPassport\nGovernment issued identity card", "partyId": "2000000555", "status": "ACTIVE", "requirements": [ { "documentTypes": [ "PASSPORT", "DRIVERS_LICENSE", "GOV_ISSUED_ID_CARD" ], "minRequired": 1 }, { "documentTypes": [ "UTILITY_BILL", "BANK_STATEMENT" ], "minRequired": 0 } ], "outstanding": { "documentTypes": [ "PASSPORT", "BANK_STATEMENT", "DRIVERS_LICENSE", "UTILITY_BILL", "GOV_ISSUED_ID_CARD" ], "requirements": [ { "documentTypes": [ "PASSPORT", "DRIVERS_LICENSE", "GOV_ISSUED_ID_CARD" ], "missing": 1 }, { "documentTypes": [ "PASSPORT", "DRIVERS_LICENSE", "GOV_ISSUED_ID_CARD" ], "missing": 1 }, { "documentTypes": [ "UTILITY_BILL", "BANK_STATEMENT" ], "missing": 1 } ] }, "validForDays": 120 } ``` In the response, you can see the following information about the documents requested about an **individual**: - description - a description of the documents that are requested. You should display this text exactly as it is written to your end user. Where you see \n this indicates a new line is needed in your display. - requirements - lists the document that have been requested. - documentTypes - lists the accepted document types for each requested document. For example, a passport or a utility bill. - minRequired - the number of documents that must be returned. For example, a party might be required to provide a passport or driving license and a utility bill, giving a minRequested count of 2. - outstanding - shows the remaining document types and requirements based on the types of the documents that have already been uploaded against the document request. - outstanding.documentTypes - lists all the document types are required but have not yet been uploaded. - missing - shows how many document types must still be added. ### Sample response for an organization Your client may be asked to provide documents in support of an onboarding request for an organization. You can see in the sample here the document types relevant for a corporation in the United States. ```json { "id": "57777", "createdAt": "2025-11-18T12:28:11.232Z", "description": "To verify the identity of the business, please provide one or more of the following documents to validate EIN, Name and Address. \n\nArticles of Incorporation\nCertificate of Good Standing\nCertificate of Incumbency\nMemorandum/Articles of Association\nConstitutional document\nLLC Agreement\nFiling receipt from state of organization\nOperating Agreement", "partyId": "2000000556", "status": "ACTIVE", "requirements": [ { "documentTypes": [ "ARTICLES_OF_INCORPORATION", "CERTIFICATE_OF_GOOD_STANDING", "INCUMBENCY_CERTIFICATE", "ARTICLES_OF_ASSOCIATION", "CONSTITUTIONAL_DOCUMENT", "LLC_AGREEMENT", "FILING_RECEIPT", "OPERATING_AGREEMENT" ], "minRequired": 1 } ], "outstanding": { "documentTypes": [ "ARTICLES_OF_INCORPORATION", "CERTIFICATE_OF_GOOD_STANDING", "INCUMBENCY_CERTIFICATE", "ARTICLES_OF_ASSOCIATION", "CONSTITUTIONAL_DOCUMENT", "LLC_AGREEMENT", "FILING_RECEIPT", "OPERATING_AGREEMENT" ], "requirements": [ { "documentTypes": [ "ARTICLES_OF_INCORPORATION", "CERTIFICATE_OF_GOOD_STANDING", "INCUMBENCY_CERTIFICATE", "ARTICLES_OF_ASSOCIATION", "CONSTITUTIONAL_DOCUMENT", "LLC_AGREEMENT", "FILING_RECEIPT", "OPERATING_AGREEMENT" ], "missing": 1 } ] }, "validForDays": 120 } ``` ## Upload documents To upload a requested document: 1. Encode the file contents as a base64 encoded string. 2. Use the base64 content itself and omit headers like data:image/png;base64. 3. Send the document in a POST request to /onboarding/v1/documents. You must specify: - The documentRequestId for the upload in the documentMetadata.documentRequestId field. - A requestId - a unique reference number that you generate so the upload can be tracked. Must be unique, with a max of 32 characters. The supported file content types allowed are: - image/png - image/jpeg - application/pdf The maximum file size is 2MB. Sample upload request: ```json { "documentType": "DRIVERS_LICENSE", "documentName": "front.jpg", "documentContent": "/9j/4AAQSkZJRgABA...==", "requestId": "17600e741f3249148b8a582dd9108e18", "documentMetadata": { "documentRequestId": "57777" } } ``` ### Upload multiple files for a single document type To upload multiple files for a single document type, upload each file with a separate `POST` request to `/onboarding/v1/documents` and specify the same document type in each document upload. Sample requests: ```json { "documentType": "DRIVERS_LICENSE", "documentName": "front.jpg", "documentContent": "/9j/4AAQSkZJRgABA...==", "requestId": "17600e741f3249148b8a582dd9108e18", "documentMetadata": { "documentRequestId": "57777" } } ``` ```json { "documentType": "DRIVERS_LICENSE", "documentName": "back.jpg", "documentContent": "/9j/4AAQSkZJRgABA...==", "requestId": "558096b9ab2943d8a700b58261c490d3", "documentMetadata": { "documentRequestId": "57777" } } ``` ### Upload multiple document types for one document request To upload multiple document types for one document request, upload each document with a separate `POST` request to `/onboarding/v1/documents`, specifying the applicable document type in each document upload. Sample requests: ```json { "documentType": "PASSPORT", "documentName": "passport.jpg", "documentContent": "/9j/4AAQSkZJRgABA...==", "requestId": "cc138a78594a4b0cb5dbc9a3eed331dc", "documentMetadata": { "documentRequestId": "57777" } } ``` ```json { "documentType": "UTILITY_BILL", "documentName": "utility_bill.jpg", "documentContent": "/9j/4AAQSkZJRgABA...==", "requestId": "09287911c7af4ae195d95f609f9d4da3", "documentMetadata": { "documentRequestId": "57777" } } ``` ## Complete document requests and submit for review To submit the documents that have been collected, you need to send a `POST` request to `/onboarding/v1/document-requests/{id}/submit`. Upon successful submission of requested documents, the response is 202 Accepted with the acceptance timestamp in the response. ```json { "acceptedAt": "2025-01-20T10:00:00.000Z" } ``` ### Handling errors caused by outstanding requirements. If there are outstanding document types, your request returns a 400 Bad Request response. In that case: 1. Check for outstanding documents with a GET request to /onboarding/v1/document-requests/{id} 2. Upload additional documents to fulfill the outstanding requirements in a POST request to /onboarding/v1/documents. 3. Submit again with a POST request to /onboarding/v1/document-requests/{id}/submit. ### Confirm no more documents are requested After you have submitted your documents, you can check the status of your client with a `GET` request to `/onboarding/v1/clients/{id}` - you should see that the client status has changed from `INFORMATION_REQUESTED` to `REVIEW_IN_PROGRESS`. ## Document Request during Account Setup A document request can be made for a client or party during your payment account setup. Whereas `status` and `customerIdentityStatus` do not change, `outstanding` shows the document request ID until it is fulfilled. You can see the document request ID 107712 in the client `outstanding` block: ```json { "outstanding": { "attestationDocumentIds": [], "documentRequestIds": [ "107712" ], "questionIds": [], "partyRoles": [], "partyIds": [] }, "status": "NEW", "results": { "customerIdentityStatus": "NOT_STARTED" } } ``` Verification call successful: ```json { "acceptedAt": "2025-05-22T01:34:42.515136439Z" } ``` You can see that client verification has started even with a partner document request outstanding. The status of the client is `REVIEW_IN_PROGRESS` and the `customerIdentityStatus` is `REVIEW_IN_PROGRESS`. ```json { "outstanding": { "attestationDocumentIds": [], "documentRequestIds": [ "107712" ], "questionIds": [], "partyRoles": [], "partyIds": [] }, "status": "REVIEW_IN_PROGRESS", "results": { "customerIdentityStatus": "REVIEW_IN_PROGRESS" } } ``` ## Example API flow to complete a document request for an individual This API flow shows a request for verification documents from an individual, which is associated to a client via the document request's partyId. The description should be shown directly to the end user, so that they can follow its instructions on what documents to upload. Because no documents have been uploaded against this document request, the document types across all the requirements are displayed in outstanding.`documentTypes`. ```json { "id": "57777", "createdAt": "2025-11-18T12:28:11.232Z", "description": "To verify your identity, please provide one or more of the following documents. Documents must be unexpired and show Full legal Name, Address and Date of Birth. If address on your identification document is not current, please additionally provide a Utility Bill or Bank Statement dated within last 6 months.\nDrivers license\nPassport\nGovernment issued identity card", "partyId": "2000000555", "status": "ACTIVE", "requirements": [ { "documentTypes": [ "PASSPORT", "DRIVERS_LICENSE", "GOV_ISSUED_ID_CARD" ], "minRequired": 1 }, { "documentTypes": [ "UTILITY_BILL", "BANK_STATEMENT" ], "minRequired": 0 } ], "outstanding": { "documentTypes": [ "PASSPORT", "BANK_STATEMENT", "DRIVERS_LICENSE", "UTILITY_BILL", "GOV_ISSUED_ID_CARD" ], "requirements": [ { "documentTypes": [ "PASSPORT", "DRIVERS_LICENSE", "GOV_ISSUED_ID_CARD" ], "missing": 1 }, { "documentTypes": [ "PASSPORT", "DRIVERS_LICENSE", "GOV_ISSUED_ID_CARD" ], "missing": 1 }, { "documentTypes": [ "UTILITY_BILL", "BANK_STATEMENT" ], "missing": 1 } ] }, "validForDays": 120 } ``` Next, the user uploads a document with a type of `PASSPORT`. The document content is base-64 encoded and sent in the `documentContent` field. ```json { "documentContent": "/9j/4AAQSkZJRgABA...==", "documentName": "passport.jpg", "documentType": "PASSPORT", "documentMetadata": { "documentRequestId": "57777" }, "requestId": "35fd703490784c16bb596b292db9016c" } ``` Once the document of type `PASSPORT` is uploaded, you can see that it is removed from outstanding.`documentTypes` and the first requirement object is entirely removed from outstanding.`requirements`. This is because the minimum required document types from that requirement was 1, so it is fulfilled as long as at least one document is uploaded with one of its requested types. The `requirements` field itself never changes, and the response payload below shows that it indeed has not changed after the document upload. ```json { "id": "57777", "createdAt": "2025-11-18T12:28:11.232Z", "description": "To verify your identity, please provide one or more of the following documents. Documents must be unexpired and show Full legal Name, Address and Date of Birth. If address on your identification document is not current, please additionally provide a Utility Bill or Bank Statement dated within last 6 months.\nDrivers license\nPassport\nGovernment issued identity card", "partyId": "2000000555", "status": "ACTIVE", "requirements": [ { "documentTypes": [ "PASSPORT", "DRIVERS_LICENSE", "IDENTIFICATION_DOCUMENT" ], "minRequired": 1 }, { "documentTypes": [ "UTILITY_BILL", "BANK_STATEMENT" ], "minRequired": 0 } ], "outstanding": { "documentTypes": [ "PASSPORT", "BANK_STATEMENT", "DRIVERS_LICENSE", "UTILITY_BILL", "GOV_ISSUED_ID_CARD" ], "requirements": [ { "documentTypes": [ "PASSPORT", "DRIVERS_LICENSE", "GOV_ISSUED_ID_CARD" ], "missing": 1 }, { "documentTypes": [ "PASSPORT", "DRIVERS_LICENSE", "GOV_ISSUED_ID_CARD" ], "missing": 1 }, { "documentTypes": [ "UTILITY_BILL", "BANK_STATEMENT" ], "missing": 1 } ] }, "validForDays": 120 } ``` After uploading a passport, the user decides to upload a utility bill. Once again, the document content is base-64 encoded and sent in the `documentContent` field. ```json { "documentContent": "/9j/4AAQSkZJRgEBD...==", "documentName": "utility-bill.jpg", "documentType": "UTILITY_BILL", "documentMetadata": { "documentRequestId": "57777" }, "requestId": "01290633e1e54f41a4866e1597ff608b" } ``` The utility bill fulfills one of the types requested in the second requirement. With a `PASSPORT` document and `UTILITY_BILL` document uploaded, the second requirement has been completed. There is now nothing outstanding, as shown by the empty outstanding.`documentTypes` and outstanding.`requirements`. ```json { "id": "57777", "createdAt": "2025-11-18T12:28:11.232Z", "description": "Please provide documents with the following options: 1. Provide passport and driver's license,\nor 2. Provide either a passport or driver's license and one of the below:\n- Credit card statement\n- Bank statement\n- Loan account statement\n- Utility bill\n- Insurance document", "partyId": "2000000555", "status": "ACTIVE", "requirements": [ { "documentTypes": [ "PASSPORT", "DRIVERS_LICENSE" ], "minRequired": 1 }, { "documentTypes": [ "PASSPORT", "DRIVERS_LICENSE", "CREDIT_CARD_STATEMENT", "BANK_STATEMENT", "LOAN_ACCOUNT_STATEMENT", "UTILITY_BILL", "INSURANCE_DOCUMENT" ], "minRequired": 2 } ], "outstanding": { "documentTypes": [], "requirements": [] }, "validForDays": 120 } ``` Notice that the document request status is still active. Once the user has uploaded all the documents that they wanted to, submit the document request. ``` Response 202 { "acceptedAt": "2025-01-20T10:00:00.000Z" } ``` Check the document request again to confirm that the `status` is now `CLOSED`. The document request has now been completed. Note that the user can no longer upload documents for this request after it has been submitted. ```json { "id": "57777", "partyId": "2000000555", "status": "CLOSED" } ``` ## Example API flow to complete a document request for a US corporation This API flow shows a request for verification documents from a corporation, which is associated to a client via the document request's partyId. The description should be shown directly to the end user, so that they can follow its instructions on what documents to upload. Because no documents have been uploaded against this document request, the document types across all the requirements are displayed in outstanding.`documentTypes`. ```json { "id": "57778", "createdAt": "2025-11-18T12:28:11.232Z", "description": "To verify the identity of the business, please provide one or more of the following documents to validate EIN, Name and Address. \n\nArticles of Incorporation\nCertificate of Good Standing\nCertificate of Incumbency\nMemorandum/Articles of Association\nConstitutional document\nLLC Agreement\nFiling receipt from state of organization\nOperating Agreement", "partyId": "2000000556", "status": "ACTIVE", "requirements": [ { "documentTypes": [ "ARTICLES_OF_INCORPORATION", "CERTIFICATE_OF_GOOD_STANDING", "INCUMBENCY_CERTIFICATE", "ARTICLES_OF_ASSOCIATION", "CONSTITUTIONAL_DOCUMENT", "LLC_AGREEMENT", "FILING_RECEIPT", "OPERATING_AGREEMENT" ], "minRequired": 1 } ], "outstanding": { "documentTypes": [ "ARTICLES_OF_INCORPORATION", "CERTIFICATE_OF_GOOD_STANDING", "INCUMBENCY_CERTIFICATE", "ARTICLES_OF_ASSOCIATION", "CONSTITUTIONAL_DOCUMENT", "LLC_AGREEMENT", "FILING_RECEIPT", "OPERATING_AGREEMENT" ], "requirements": [ { "documentTypes": [ "ARTICLES_OF_INCORPORATION", "CERTIFICATE_OF_GOOD_STANDING", "INCUMBENCY_CERTIFICATE", "ARTICLES_OF_ASSOCIATION", "CONSTITUTIONAL_DOCUMENT", "LLC_AGREEMENT", "FILING_RECEIPT", "OPERATING_AGREEMENT" ], "missing": 1 } ] }, "validForDays": 120 } ``` Next, the user uploads a document with a type of `ARTICLES_OF_INCORPORATION`. The document content is base-64 encoded and sent in the `documentContent` field. ```json { "documentContent": "/9j/4AAQSkZJRgABA...==", "documentName": "passport.jpg", "documentType": "ARTICLES_OF_INCORPORATION", "documentMetadata": { "documentRequestId": "57778" }, "requestId": "35fd703490784c16bb596b292db9016c" } ``` Once the document of type `ARTICLES_OF_INCORPORATION` is uploaded, you can see that it is removed from outstanding.`documentTypes` and the first requirement object is entirely removed from outstanding.`requirements`. This is because the minimum required document types from that requirement was 1, so it is fulfilled as long as at least one document is uploaded with one of its requested types. The `requirements` field itself never changes, and the response payload below shows that it indeed has not changed after the document upload. There is now nothing outstanding, as shown by the empty outstanding.`documentTypes` and outstanding.`requirements`. ```json { "id": "57778", "createdAt": "2025-11-18T12:28:11.232Z", "description": "To verify the identity of the business, please provide one or more of the following documents to validate EIN, Name and Address. \n\nArticles of Incorporation\nCertificate of Good Standing\nCertificate of Incumbency\nMemorandum/Articles of Association\nConstitutional document\nLLC Agreement\nFiling receipt from state of organization\nOperating Agreement", "partyId": "2000000556", "status": "ACTIVE", "requirements": [ { "documentTypes": [ "ARTICLES_OF_INCORPORATION", "CERTIFICATE_OF_GOOD_STANDING", "INCUMBENCY_CERTIFICATE", "ARTICLES_OF_ASSOCIATION", "CONSTITUTIONAL_DOCUMENT", "LLC_AGREEMENT", "FILING_RECEIPT", "OPERATING_AGREEMENT" ], "minRequired": 1 } ], "outstanding": { "documentTypes": [], "requirements": [] }, "validForDays": 120 } ``` Notice that the document request status is still active. Once the user has uploaded all the documents that they wanted to, submit the document request. ```json { "acceptedAt": "2025-01-20T10:00:00.000Z" } ``` Check the document request again to confirm that the status is now `CLOSED`. The document request has now been completed. Note that the user can no longer upload documents for this request after it has been submitted. ```json { "id": "57778", "partyId": "2000000556", "status": "CLOSED" } ``` ## Related [Notification types](/docs/commerce/optimization-protection/capabilities/notifications/notification-types#digital-onboarding-events)