Skip to content

feat: add PDM API technical guide #330

Open
yoasyo25 wants to merge 1 commit intomainfrom
ya/DOCINT-1073/document-upload-technical-guide
Open

feat: add PDM API technical guide #330
yoasyo25 wants to merge 1 commit intomainfrom
ya/DOCINT-1073/document-upload-technical-guide

Conversation

@yoasyo25
Copy link
Contributor

@yoasyo25 yoasyo25 commented Feb 26, 2026

Jira Ticket:
🎫   DOCINT-1073

Adds a comprehensive step-by-step technical guide for API integrators building against the Procore Document Management V2 API.

Covers:

  • 8-step upload workflow (fetch requirements → create uploads → upload binary → update → retrieve event ID → submit as revision)
  • Three integration patterns (Scenario A/B/C) based on when metadata and binary files are available
  • Full request/response examples
  • Error reference with HTTP status codes and resolution steps for Steps 4 and 8, including item-level failures in the failures array
  • End-to-end example with annotated JSON

@yoasyo25 yoasyo25 self-assigned this Feb 26, 2026
@yoasyo25 yoasyo25 force-pushed the ya/DOCINT-1073/document-upload-technical-guide branch 6 times, most recently from 3869b08 to b229b82 Compare March 5, 2026 22:52
@yoasyo25 yoasyo25 force-pushed the ya/DOCINT-1073/document-upload-technical-guide branch 2 times, most recently from d7a6ec3 to 92d3b77 Compare March 9, 2026 15:51
@yoasyo25 yoasyo25 changed the title wip feat: add PDM API technical guide Mar 9, 2026
@yoasyo25 yoasyo25 marked this pull request as ready for review March 9, 2026 15:54
Copilot AI review requested due to automatic review settings March 9, 2026 15:54
@yoasyo25 yoasyo25 requested a review from a team March 9, 2026 15:56
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new end-to-end technical guide intended to help integrators implement the full Procore Document Management (PDM) V2 upload + revision submission workflow, with scenario-based sequencing and error-handling guidance.

Changes:

  • Replaces the placeholder technical guide with a detailed 8-step upload/submission workflow, integration patterns, examples, and an error reference.
  • Adds a new “Constructing the Fields Array for API Requests” section to the metadata details reference to standardize how integrators format metadata payloads.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.

File Description
document_management_integration/document_management_technical_guide.md Adds the comprehensive step-by-step PDM V2 upload/revision technical guide, including examples and error reference tables.
document_management_integration/document_management_metadata_details.md Adds guidance + a quick reference table for constructing fields arrays used in Document Uploads POST/PATCH payloads.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

"fields": [
{ "id": "01JDXMPK03FD0EF8R1HKTRM93X", "name": "discipline", "label": "Discipline", "type": "lov_entry" },
{ "id": "01JDXMPK04FD0DE7Q0GJSQK82Y", "name": "number", "label": "Number", "type": "string" },
{ "id": "01JDXMPK09FD0892J5BDMJD37D", "name": "type", "label": "Type", "type": "lov_entry" },
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Step 1 example response JSON has a trailing comma after the last object in the naming_standard.fields array, which makes the example invalid JSON. Please remove the trailing comma so copy/paste parsing works.

Suggested change
{ "id": "01JDXMPK09FD0892J5BDMJD37D", "name": "type", "label": "Type", "type": "lov_entry" },
{ "id": "01JDXMPK09FD0892J5BDMJD37D", "name": "type", "label": "Type", "type": "lov_entry" }

Copilot uses AI. Check for mistakes.
Comment on lines +529 to +535
"success": [
{
"id": "01JDXMPK0MTP0H41D4PYZ62R6R"
},
{
"id": "01JDXMPK0OTP0F32D2PWV40N4U"
}
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the Step 6 partial-success example response, the success array includes an upload id (01JDXMPK0OTP0F32D2PWV40N4U) that does not appear in the preceding request example. This makes it unclear how to correlate request items to success/failed; please update the example IDs so they match the request payload.

Copilot uses AI. Check for mistakes.
| `file_name` | string | Yes | The filename of the document. Including the file extension is recommended. |
| `mime_type` | string | Yes | The MIME type of the file |
| `file_locked` | boolean | No | Whether to lock the file from edits. Default is `false`. |
| `file_upload_id` | string | No | UUID of a file already uploaded to Procore storage. Links the binary at creation time and automatically sets `upload_status` to `COMPLETED`. All uploads in the batch must either all include `file_upload_id` or none should; mixing is not allowed. |
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

file_upload_id is described as a "UUID", but the examples in this guide (and the Direct File Uploads guide) show IDs in a ULID-like format (e.g., 01JDX...). To avoid confusion, consider describing this as the opaque upload uuid returned by the Direct File Uploads API rather than a UUID.

Suggested change
| `file_upload_id` | string | No | UUID of a file already uploaded to Procore storage. Links the binary at creation time and automatically sets `upload_status` to `COMPLETED`. All uploads in the batch must either all include `file_upload_id` or none should; mixing is not allowed. |
| `file_upload_id` | string | No | Opaque upload `uuid` returned by the Direct File Uploads API for a file already uploaded to Procore storage. Links the binary at creation time and automatically sets `upload_status` to `COMPLETED`. All uploads in the batch must either all include `file_upload_id` or none should; mixing is not allowed. |

Copilot uses AI. Check for mistakes.
Comment on lines +603 to +616
}
],
"label_source": "manual",
"label": "Type",
"description": "The document type"
},
{
"id": "01JDXMPK0BFD0670G3Z9JFB15F",
"name": "revision",
"type": "string",
"values": [{ "label": "Rev A" }],
"label_source": "manual",
"label": "Revision",
"description": "The document revision identifier"
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example show response uses "label_source": "manual", but elsewhere in this repo’s Document Management docs label_source values are uppercase (e.g., MANUAL, SYSTEM, ML). To stay consistent (and avoid implying a different enum), please update these example values/casing.

Copilot uses AI. Check for mistakes.

- **Always wrap values in an array**, even for single-value fields.
- **Text-type fields** (`string` / `numeric` / `timestamp`): Use literal values directly.
- **Select-type fields** (`lov_entry` / `lov_entries`): You cannot pass literal text. You must use the value IDs retrieved from the [List Project Metadata Values](https://developers.procore.com/reference/rest/document-management-fields?version=2.0#list-document-management-project-field-values) endpoint.
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new section links "List Project Metadata Values" to rest/document-management-fields..., but the repo’s Document Management API Endpoints page points to rest/project-metadata-values for the same operation. Please update the link so it matches the canonical endpoint reference used elsewhere in the docs.

Suggested change
- **Select-type fields** (`lov_entry` / `lov_entries`): You cannot pass literal text. You must use the value IDs retrieved from the [List Project Metadata Values](https://developers.procore.com/reference/rest/document-management-fields?version=2.0#list-document-management-project-field-values) endpoint.
- **Select-type fields** (`lov_entry` / `lov_entries`): You cannot pass literal text. You must use the value IDs retrieved from the [List Project Metadata Values](https://developers.procore.com/reference/rest/project-metadata-values?version=2.0#list-project-metadata-values) endpoint.

Copilot uses AI. Check for mistakes.
@yoasyo25 yoasyo25 force-pushed the ya/DOCINT-1073/document-upload-technical-guide branch from 92d3b77 to 9a2adf3 Compare March 9, 2026 16:14
Comment on lines +374 to +375
| `file_upload_id` | string | No | UUID of a file already uploaded to Procore storage. Links the binary at creation time and automatically sets `upload_status` to `COMPLETED`. All uploads in the batch must either all include `file_upload_id` or none should; mixing is not allowed. |
| `fields` | array | No | Metadata fields that can be set at creation or update. See [Constructing the Fields Array for API Requests]({{ site.url }}{{ site.baseurl }}{% link document_management_integration/document_management_metadata_details.md %}#constructing-the-fields-array-for-api-requests) for the expected format. Any fields omitted from a subsequent update are preserved. |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The v2.0 Bulk Create Document Uploads doesn't accept file_upload_id nor fields.

| 400 | `INVALID_INPUT` | Invalid field or workflow configuration on the upload. | Check that all field values are valid (correct IDs, active values). |
| 400 | `HAS_ERRORS` | The upload has workflow validation errors. | Review workflow configuration and resolve any assignment issues. |
| 400 | `DUPLICATE_REVISION` | The revision value already exists in the target container and duplicate revisions are not allowed. | Change the `revision` field value to a unique value, or verify `allow_duplicate_revisions` in upload requirements. |
| 400 | `WORKFLOW_CONFLICT` | Existing revisions in the target container have active workflows. | Provide `termination_reason` and `terminated_revision_status_id` to resolve. See [Handling Workflow Conflicts](#handling-workflow-conflicts). |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this error returns a 422


**Quick Reference: How to Structure Field Values**

| Field Type | From: List Fields | From: List Field Values | Fields Array Entry Example |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth mentioning the reference field type in this table

"failed": [
{
"id": "01JDXMPK0NTP0G50E3NYY51Q5S",
"code": "FILE_KEY_MISMATCH",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code field in the failed array is a number (HTTP status code from the File Access Service), not a string reason code. The service passes through FASGetBulkFileError.code which is typed as number (file-access-service.sdk.ts L107), and the handler defaults to 0 when absent (update-document-upload-batch.service.ts L1055).

This example should show something like "code": 404 instead of "code": "FILE_KEY_MISMATCH". The message field is the human-readable string.

* Structure Your Metadata Fields: All scenarios require you to submit metadata, whether it is during the initial creation or a subsequent update. For exact JSON payload examples and rules on formatting this data, see [Constructing the Fields Array for API Requests]({{ site.url }}{{ site.baseurl }}{% link document_management_integration/document_management_metadata_details.md %}#constructing-the-fields-array-for-api-requests).


### Scenario A — Asynchronous Metadata
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like this is the only supported scenario. Both B and C depend on submitting fields in a POST, which isn't supported. Should we remove them and leave A?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants