openapi: 3.2.0 info: title: Loopio Projects API description: Loopio's Public API termsOfService: http://loopio.com/termsOfService contact: email: support@loopio.com license: name: Apache 2.0 url: http://www.apache.org/licenses/LICENSE-2.0.html version: 1.0.0 servers: - url: https://api.loopio.com/data/v2 description: Production server for the American datacenter - url: https://api.eu.loopio.com/data/v2 description: Production server for the European datacenter tags: - name: Projects description: Create and manage Projects paths: /projects/{projectId}/complianceSets: parameters: - name: projectId in: path required: true schema: type: integer get: tags: - Projects summary: Get the Compliance Sets for a Project description: "Note: Confidential projects are currently not supported via API.\n\n Note: We are making terminology updates in Loopio - Compliance Sets shall be referred to as Answer Sets. The API will be updated to reflect this change at a later time." operationId: getProjectComplianceSets responses: '200': description: OK content: application/json: schema: type: array items: $ref: '#/components/schemas/ComplianceSet' '400': $ref: '#/components/responses/400' '403': $ref: '#/components/responses/403' post: tags: - Projects summary: Create a Compliance Set for a Project description: "Note: Confidential projects are currently not supported via API.\n\n Note: We are making terminology updates in Loopio - Compliance Sets shall be referred to as Answer Sets. The API will be updated to reflect this change at a later time." operationId: createComplianceSet requestBody: required: true content: application/json: schema: type: object properties: label: type: string maxLength: 255 options: description: The list of options must be unique. Option labels will have their whitespace trimmed. type: array items: $ref: '#/components/schemas/ComplianceOption' required: - options responses: '201': description: CREATED content: application/json: schema: $ref: '#/components/schemas/ComplianceSet' '400': $ref: '#/components/responses/400' '403': $ref: '#/components/responses/403' /projects/{projectId}/complianceSets/{complianceSetId}: parameters: - name: projectId in: path required: true schema: type: integer - name: complianceSetId in: path required: true schema: type: integer get: tags: - Projects summary: Get a Compliance Set for a Project description: "Note: Confidential projects are currently not supported via API.\n\n Note: We are making terminology updates in Loopio - Compliance Sets shall be referred to as Answer Sets. The API will be updated to reflect this change at a later time." operationId: getProjectComplianceSet responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/ComplianceSet' '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' put: tags: - Projects summary: Update a Compliance Set for a Project description: "Note: Confidential projects are currently not supported via API.\n\n Note: We are making terminology updates in Loopio - Compliance Sets shall be referred to as Answer Sets. The API will be updated to reflect this change at a later time." operationId: updateProjectComplianceSet requestBody: required: true content: application/json: schema: type: object properties: label: type: string maxLength: 255 options: description: The list of options must be unique. Option labels will have their whitespace trimmed. type: array minLength: 1 items: $ref: '#/components/schemas/ComplianceOption' required: - label - options responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/ComplianceSet' '400': $ref: '#/components/responses/400' '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' delete: tags: - Projects summary: Delete a Compliance Set for a Project description: "Note: Confidential projects are currently not supported via API.\n\n Note: We are making terminology updates in Loopio - Compliance Sets shall be referred to as Answer Sets. The API will be updated to reflect this change at a later time." operationId: deleteProjectComplianceSet responses: '204': $ref: '#/components/responses/204' '403': $ref: '#/components/responses/403' /projects: get: parameters: - $ref: '#/components/parameters/Page' - $ref: '#/components/parameters/PageSize' - $ref: '#/components/parameters/RfxTypes' - $ref: '#/components/parameters/Owners' tags: - Projects summary: List projects you can interact with description: 'Note: Confidential projects are currently not supported via API.' operationId: listProjects responses: '200': description: OK content: application/json: schema: type: object properties: totalItems: type: integer totalPages: type: integer items: type: array items: $ref: '#/components/schemas/Project' required: - totalItems - totalPages - items '400': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/Error' example: name: VALIDATION_ERROR message: Array has invalid values or Value is not an integer debugId: 0fas3 '403': $ref: '#/components/responses/403' security: - loopio_auth: - project:read post: tags: - Projects summary: Create a project operationId: createProject requestBody: description: Project to create content: application/json: schema: $ref: '#/components/schemas/CreateProjectRequestBody' required: true responses: '201': description: CREATED content: application/json: schema: $ref: '#/components/schemas/Project' '400': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/Error' example: name: VALIDATION_ERROR message: You must provide a valid owner for the Project debugId: 0fas3 '403': $ref: '#/components/responses/403' security: - loopio_auth: - project:write /projects/{projectId}: parameters: - name: projectId in: path required: true schema: type: integer get: tags: - Projects summary: Get a Project's data description: 'Note: Confidential projects are currently not supported via API.' parameters: - name: fields in: query required: false schema: type: string enum: - '@narrow' - '@wide' default: '@narrow' operationId: getProject responses: '200': description: OK content: application/json: schema: anyOf: - $ref: '#/components/schemas/Project' - $ref: '#/components/schemas/ProjectWide' examples: '@narrow': $ref: '#/components/examples/ProjectNarrow' '@wide': $ref: '#/components/examples/ProjectWide' '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' '500': description: Fatal Error content: application/json: schema: $ref: '#/components/schemas/Error' security: - loopio_auth: - project:read put: tags: - Projects summary: Update a Project's status description: 'Note: Confidential projects are currently not supported via API.' operationId: updateProject requestBody: content: application/json: schema: type: object properties: status: type: string enum: - ACTIVE - WON - LOST - DONE - STOPPED required: true responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Project' example: value: id: 9 name: Project status: ACTIVE companyName: Company createdDate: '2020-01-01T00:00:00Z' dueDate: '2020-01-01T00:00:00Z' owner: id: 100 name: John Doe creator: id: 101 name: Jane Doe description: An example project '400': $ref: '#/components/responses/400' '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' security: - loopio_auth: - project:write delete: tags: - Projects summary: Delete a Project and its data description: 'Note: Confidential projects are currently not supported via API.' operationId: deleteProject responses: '204': description: No Content '400': $ref: '#/components/responses/400' '403': $ref: '#/components/responses/403' security: - loopio_auth: - project:delete /projects/{projectId}/customProjectFields: parameters: - name: projectId in: path required: true schema: type: integer get: tags: - Projects summary: Get Custom Project Field values for a given Project description: 'Note: Confidential projects are currently not supported via API.' operationId: getCustomProjectFieldValuesForProject responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/CustomProjectFieldValuesMap' '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' security: - loopio_auth: - project:read patch: tags: - Projects summary: Edit Custom Project Field values for a given Project description: 'Note: Confidential projects are currently not supported via API.' operationId: setCustomProjectFieldValuesForProject requestBody: description: '**Notes:** - Unlike most PATCH operations in this API, this operation does not use the JSON-Patch format. The request body must take the form of a basic key-value update object, where key is the name of the Custom Project Field. The value of a Custom Project Field cannot be updated to null. - When setting a value for a date type Custom Project Field, the value is accepted as a string. To ensure consistent display and reporting, pass dates in ISO 8601 format (e.g., 2026-04-06T15:30:45+05:30). Format validation is not enforced at the API level. ' content: application/json: schema: $ref: '#/components/schemas/CustomProjectFieldPatchValuesMap' responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/CustomProjectFieldValuesMap' '400': $ref: '#/components/responses/400' '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' '422': $ref: '#/components/responses/422' security: - loopio_auth: - project:write /projects/{projectId}/mergeVariables: parameters: - name: projectId in: path required: true schema: type: integer get: tags: - Projects summary: Get Project Merge Variable values for a Project description: 'Note: Confidential projects are currently not supported via API.' operationId: getMergeVariableValuesForProject responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/MergeVariableProjectValuesMap' '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' security: - loopio_auth: - project:read - mergeVariable:read patch: tags: - Projects summary: Edit the values of Project Merge Variables for a Project description: 'Note: Confidential projects are currently not supported via API.' operationId: setMergeVariableValuesForProject requestBody: description: '**Note**: Unlike most PATCH operations in this API, this operation does not use the JSON-Patch format. The request body must take the form of a basic key-value update object' content: application/json: schema: $ref: '#/components/schemas/MergeVariableProjectValuesMap' responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/MergeVariableProjectValuesMap' '400': $ref: '#/components/responses/InvalidJSONPatchDocument' '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' '422': $ref: '#/components/responses/UnprocessableJSONPatchRequest' security: - loopio_auth: - project:write - mergeVariable:write /projects/{projectId}/summary: parameters: - name: projectId in: path required: true schema: type: integer get: tags: - Projects summary: Get the status summary of a Project description: 'Note: Confidential projects are currently not supported via API.' operationId: getProjectSummary responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/ProjectSummary' '403': $ref: '#/components/responses/403' '404': description: Resource not found content: application/json: schema: $ref: '#/components/schemas/Error' example: name: RESOURCE_NOT_FOUND message: Resource not found debugId: 0fas3 '500': description: Fatal Error content: application/json: schema: $ref: '#/components/schemas/Error' security: - loopio_auth: - project:read /projects/summary: parameters: - name: lastUpdatedDateGt in: query required: true schema: type: string get: tags: - Projects summary: Get the status summary list of Projects filtered by date last synced description: 'Note: Confidential projects are currently not supported via API.' operationId: getProjectSummaryList responses: '200': description: OK content: application/json: schema: type: object properties: totalItems: type: integer items: type: array items: $ref: '#/components/schemas/ProjectSummary' '400': $ref: '#/components/responses/400' '403': $ref: '#/components/responses/403' '500': description: Fatal Error content: application/json: schema: $ref: '#/components/schemas/Error' security: - loopio_auth: - project:read /projects/{projectId}/sourceDocuments: parameters: - name: projectId in: path required: true schema: type: integer post: tags: - Projects summary: Attach a source document to a Loopio Project description: 'Note: Confidential projects are currently not supported via API.' operationId: addProjectSourceDocument requestBody: content: multipart/form-data: schema: properties: document: type: string description: The file to upload. format: binary required: true responses: '201': description: Created content: application/json: schema: type: object properties: fileId: type: integer resourceURI: type: string example: /data/v2/files/0 required: - fileId - resourceURI '400': $ref: '#/components/responses/400' '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' '503': description: Could not save file content: application/json: schema: type: object security: - loopio_auth: - project:write get: tags: - Projects summary: View basic information on a Project's source files description: 'Note: Confidential projects are currently not supported via API.' operationId: listProjectSourceDocuments responses: '200': description: OK content: application/json: schema: type: object properties: totalItems: type: integer totalPages: type: integer items: type: array items: $ref: '#/components/schemas/ProjectSourceFile' required: - totalItems - totalPages - items '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' security: - loopio_auth: - project:read /projects/{projectId}/opportunityLink: parameters: - name: projectId in: path required: true schema: type: integer post: tags: - Projects summary: Link a Loopio Project and CRM Opportunity description: 'Note: Confidential projects are currently not supported via API.' operationId: createOpportunityLink requestBody: content: application/json: schema: required: - type - opportunityId type: object properties: opportunityId: description: Accepts a 15 or 18 digit Salesforce ID or a Dynamics UUID oneOf: - type: string pattern: '[a-zA-Z0-9]{18}|[a-zA-Z0-9]{15}' - type: string format: uuid example: - 123e4567-e89b-12d3-a456-426652340000 - 0063J000002e7A8QAI type: type: string enum: - SALESFORCE - MS_DYNAMICS examples: Salesforce: value: type: SALESFORCE opportunityId: 0063J000002e7A8QAI summary: Salesforce opportunity IDs are 15 or 18 character alphanumeric strings Dynamics: value: type: MS_DYNAMICS opportunityId: 123e4567-e89b-12d3-a456-426652340000 summary: Microsoft Dynamics opportunity IDs use the UUID format required: true responses: '201': description: Created content: application/json: schema: type: object properties: projectId: type: integer opportunityId: type: string examples: Salesforce: value: projectId: 123 opportunityId: 0063J000002e7A8QAI Dynamics: value: projectId: 123 opportunityId: 123e4567-e89b-12d3-a456-426652340000 '400': description: Invalid Opportunity content: application/json: schema: type: object '403': $ref: '#/components/responses/403' '422': $ref: '#/components/responses/422' security: - loopio_auth: - crm:write /projects/{projectId}/participants: parameters: - name: projectId in: path required: true schema: type: integer get: tags: - Projects summary: Get the participants for a Project description: 'Note: Confidential projects are currently not supported via API.' operationId: getProjectParticipants responses: '200': description: OK content: application/json: schema: type: array items: $ref: '#/components/schemas/ParticipantReference' '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' security: - loopio_auth: - project.participant:read put: tags: - Projects summary: Update the participants for a Project description: 'Note: Confidential projects are currently not supported via API.' operationId: updateProjectParticipants requestBody: required: true content: application/json: schema: type: array items: $ref: '#/components/schemas/ParticipantReference' responses: '200': description: UPDATED content: application/json: schema: type: array items: $ref: '#/components/schemas/ParticipantReference' '400': $ref: '#/components/responses/400' '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' '422': $ref: '#/components/responses/422' security: - loopio_auth: - project.participant:write /projectTemplates/{projectTemplateId}/projects: parameters: - name: projectTemplateId in: path required: true schema: type: integer post: tags: - Projects summary: Create a project using a template (This creates an async task to execute this operation) description: Returns a taskId and a projectId. Make a GET request to /asyncTasks/{taskId}/projectTemplateCopy to find the status of the task. operationId: createProjectFromTemplate requestBody: description: Project to create content: application/json: schema: $ref: '#/components/schemas/CreateProjectRequestBody' required: true responses: '202': description: 'ACCEPTED **Note**: Although **projectId** is provided in the response, any interaction with the project (e.g. attaching documents, adding entries, adding sections, and any other action that alters its structure or content) is not guaranteed to work properly until the task is completed. The status of the task can be verified [here.](https://developer.loopio.com/docs/loopio-api/704e4445340fc-get-the-status-of-a-create-project-from-template-async-task)' content: application/json: schema: type: object properties: taskId: type: integer projectId: type: integer required: - taskId - projectId '400': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/Error' example: name: VALIDATION_ERROR message: You must provide a valid owner for the Project debugId: 0fas3 '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' security: - loopio_auth: - project:write /projectEntries: get: parameters: - $ref: '#/components/parameters/RequiredProjectId' - $ref: '#/components/parameters/QueryParamSectionId' - $ref: '#/components/parameters/QueryParamSubSectionId' - $ref: '#/components/parameters/QueryParamInlineOptions' - $ref: '#/components/parameters/Page' - $ref: '#/components/parameters/PageSize' tags: - Projects summary: List your Project Entries description: 'Note: Confidential projects are currently not supported via API.' operationId: listProjectEntries responses: '200': description: OK content: application/json: schema: type: object properties: totalItems: type: integer example: 100 totalPages: type: integer example: 10 items: type: array items: $ref: '#/components/schemas/Entry' required: - totalItems - totalPages - items '400': $ref: '#/components/responses/400' '403': $ref: '#/components/responses/403' security: - loopio_auth: - project:read post: tags: - Projects summary: Create a new Project Entry description: 'Create a new Project Entry. In addition to the projectId, one of either the sectionId or subSectionId must be provided, but not both. Note: Confidential projects are currently not supported via API.' operationId: createProjectEntry requestBody: required: true content: application/json: schema: allOf: - type: object properties: projectId: type: integer description: 'Project Id in which entry is created ' question: type: - string - 'null' answer: type: object properties: text: type: - string - 'null' complianceAnswers: description: 'Project Compliance Sets are unique per project. Use the /projects/{projectId}/complianceSets API to retrieve a list of available Compliance Sets. The complianceSetId must match one of the Compliance Sets in the given Project, and option must match one of the option labels in the given Compliance Set. Note: we are making terminology updates in Loopio - Compliance Sets shall be referred to as Answer Sets. The API will be updated to reflect this change at a later time. ' type: array items: type: object properties: complianceSetId: type: integer option: type: - string - 'null' required: - complianceSetId - option required: - text required: - projectId - question - answer - oneOf: - properties: sectionId: type: integer required: - sectionId - properties: subSectionId: type: integer required: - subSectionId responses: '201': description: CREATED content: application/json: schema: $ref: '#/components/schemas/Entry' '400': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/Error' example: name: VALIDATION_ERROR message: Invalid sectionId debug: 0fas5 '403': $ref: '#/components/responses/403' security: - loopio_auth: - project:write /projectEntries/{projectEntryId}: parameters: - $ref: '#/components/parameters/ProjectEntryId' - $ref: '#/components/parameters/QueryParamInlineOptions' get: tags: - Projects summary: Retrieve a specific Project Entry description: 'Note: Confidential projects are currently not supported via API.' operationId: getProjectEntry responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Entry' '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' security: - loopio_auth: - project:read put: tags: - Projects summary: Update a specific Project Entry description: 'Note: Confidential projects are currently not supported via API.' operationId: updateProjectEntry requestBody: required: true content: application/json: schema: type: object properties: question: type: - string - 'null' minLength: 1 answer: type: object properties: text: type: - string - 'null' minLength: 1 complianceAnswers: $ref: '#/components/schemas/EntryComplianceAnswerCollection' responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Entry' '400': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/Error' example: name: VALIDATION_ERROR message: Invalid sectionId debugId: 0fas5 '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' security: - loopio_auth: - project:write delete: tags: - Projects summary: Delete a specific Project Entry description: 'Note: Confidential projects are currently not supported via API.' operationId: deleteProjectEntry responses: '204': $ref: '#/components/responses/204' '403': $ref: '#/components/responses/403' security: - loopio_auth: - project:write /projectEntries/{entryId}/attachments: parameters: - name: entryId in: path description: Project Entry ID required: true schema: type: integer get: tags: - Projects summary: List attachments for a Project Entry description: 'Note: Confidential projects are currently not supported via API.' operationId: getProjectEntryAttachments responses: '200': description: OK content: application/json: schema: type: object properties: items: type: array items: $ref: '#/components/schemas/ProjectEntryAttachment' required: - items '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' security: - loopio_auth: - project:read /projectEntries/{entryId}/attachments/upload: parameters: - name: entryId in: path description: Project Entry ID required: true schema: type: integer post: tags: - Projects summary: Upload an attachment to a Project Entry description: 'Note: Confidential projects are currently not supported via API.' operationId: uploadProjectEntryAttachment requestBody: required: true content: multipart/form-data: schema: properties: file: type: string format: binary description: 'Maximum allowed file size: - Image: 5 MB - Document: 35 MB ' required: - file responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/ProjectEntryAttachmentUploadResponse' '400': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/Error' example: name: VALIDATION_ERROR message: 'Error at ''filename'': Invalid file type. The following file extensions are valid: .doc, .docx, .pdf, .xls, .xlsx, .ppt, .pptx, .png, .jpg, .jpeg, .gif, .vsd, .vsdx, .vdx, .vss, .vsx, .vst, .vtx, .graffle, .indd, .indt, .idml, .ai, .eps, .zip' debugId: 0fas5 '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' security: - loopio_auth: - project:write /projectEntries/{entryId}/attachments/{fileVersionId}/replace: parameters: - name: entryId in: path description: Project Entry ID required: true schema: type: integer - name: fileVersionId in: path description: File version ID of the attachment to replace required: true schema: type: integer post: tags: - Projects summary: Replace an attachment on a Project Entry description: 'Replaces an existing attachment with a new file. The `fileVersionId` must belong to the specified Project Entry. Image attachments can only be replaced with images, and non-image attachments can only be replaced with non-image files. Note: Confidential projects are currently not supported via API. ' operationId: replaceProjectEntryAttachment requestBody: required: true content: multipart/form-data: schema: properties: file: type: string format: binary description: 'Maximum allowed file size: - Image: 5 MB - Document: 35 MB ' required: - file responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/ProjectEntryAttachmentUploadResponse' '400': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/Error' example: name: VALIDATION_ERROR message: 'Error at ''file'': Image Attachments cannot be replaced with Document Attachments.' debugId: 0fas5 '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' security: - loopio_auth: - project:write /projectEntries/{entryId}/attachments/{fileVersionId}: parameters: - name: entryId in: path description: Project Entry ID required: true schema: type: integer - name: fileVersionId in: path description: File version ID of the attachment to delete required: true schema: type: integer delete: tags: - Projects summary: Delete an attachment from a Project Entry description: 'Deletes an attachment from a specific Project Entry. The `fileVersionId` must belong to the specified entry; otherwise a `404` is returned. Note: Confidential projects are currently not supported via API. ' operationId: deleteProjectEntryAttachment responses: '204': $ref: '#/components/responses/204' '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' security: - loopio_auth: - project:write /sections: get: parameters: - $ref: '#/components/parameters/RequiredProjectId' - $ref: '#/components/parameters/Page' - $ref: '#/components/parameters/PageSize' tags: - Projects summary: List your Project sections description: 'Note: Confidential projects are currently not supported via API.' operationId: listProjectSections responses: '200': description: OK content: application/json: schema: type: object properties: totalItems: type: integer example: 100 totalPages: type: integer example: 10 items: type: array items: $ref: '#/components/schemas/Section' required: - totalItems - totalPages - items '400': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/Error' example: name: VALIDATION_ERROR message: Invalid projectId debugId: 0fas5 '403': $ref: '#/components/responses/403' security: - loopio_auth: - project:read post: tags: - Projects summary: Create a new Project section description: "Create a new Project section.\n\n Note: Confidential projects are currently not supported via API." operationId: createProjectSection requestBody: required: true content: application/json: schema: type: object properties: projectId: type: integer name: type: - string - 'null' required: - projectId - name responses: '201': description: CREATED content: application/json: schema: $ref: '#/components/schemas/Section' '400': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/Error' example: name: VALIDATION_ERROR message: Invalid projectId debugId: 0fas5 '403': $ref: '#/components/responses/403' security: - loopio_auth: - project:write /sections/{sectionId}: get: parameters: - $ref: '#/components/parameters/SectionId' tags: - Projects summary: Retrieve a specific Project section description: 'Note: Confidential projects are currently not supported via API.' operationId: getProjectSection responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Section' '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' security: - loopio_auth: - project:read put: parameters: - $ref: '#/components/parameters/SectionId' tags: - Projects summary: Update a specific Project section description: 'Note: Confidential projects are currently not supported via API.' operationId: updateProjectSection requestBody: required: true content: application/json: schema: type: object properties: name: type: - string - 'null' responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Section' '400': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/Error' example: name: VALIDATION_ERROR message: 'Invalid name: Expected string or null' debugId: 0fas5 '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' security: - loopio_auth: - project:write delete: parameters: - $ref: '#/components/parameters/SectionId' tags: - Projects summary: Delete a Project section and its content description: 'Note: Confidential projects are currently not supported via API.' operationId: deleteProjectSection responses: '204': $ref: '#/components/responses/204' '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' security: - loopio_auth: - project:write /subSections: get: parameters: - $ref: '#/components/parameters/RequiredProjectId' - $ref: '#/components/parameters/QueryParamSectionId' - $ref: '#/components/parameters/Page' - $ref: '#/components/parameters/PageSize' tags: - Projects summary: List your Project subSections description: 'Note: Confidential projects are currently not supported via API.' operationId: listProjectSubSections responses: '200': description: OK content: application/json: schema: type: object properties: totalItems: type: integer example: 100 totalPages: type: integer example: 10 items: type: array items: $ref: '#/components/schemas/SubSection' required: - totalItems - totalPages - items '400': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/Error' example: name: VALIDATION_ERROR message: The project does not exist or has been deleted debugId: 0fas5 '403': $ref: '#/components/responses/403' security: - loopio_auth: - project:read post: tags: - Projects summary: Create a new Project subSection description: "Create a new Project subSection.\n\n Note: Confidential projects are currently not supported via API." operationId: createProjectSubSection requestBody: required: true content: application/json: schema: type: object properties: sectionId: type: integer name: type: - string - 'null' required: - sectionId - name responses: '201': description: CREATED content: application/json: schema: $ref: '#/components/schemas/SubSection' '400': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/Error' example: name: VALIDATION_ERROR message: Invalid sectionId debugId: 0fas5 '403': $ref: '#/components/responses/403' security: - loopio_auth: - project:write /subSections/{subSectionId}: get: parameters: - $ref: '#/components/parameters/SubSectionId' tags: - Projects summary: Retrieve a specific Project subSection description: 'Note: Confidential projects are currently not supported via API.' operationId: getProjectSubQuestion responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/SubSection' '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' security: - loopio_auth: - project:read put: parameters: - $ref: '#/components/parameters/SubSectionId' tags: - Projects summary: Update a specific Project subSection description: 'Note: Confidential projects are currently not supported via API.' operationId: updateProjectSubSection requestBody: required: true content: application/json: schema: type: object properties: name: type: - string - 'null' responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/SubSection' '400': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/Error' example: name: VALIDATION_ERROR message: 'Invalid name: Expected string or null' debugId: 0fas5 '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' security: - loopio_auth: - project:write delete: parameters: - $ref: '#/components/parameters/SubSectionId' tags: - Projects summary: Delete a Project subSection and its content description: 'Note: Confidential projects are currently not supported via API.' operationId: deleteProjectSubSection responses: '204': $ref: '#/components/responses/204' '403': $ref: '#/components/responses/403' security: - loopio_auth: - project:write /asyncTasks/{taskId}/projectTemplateCopy: parameters: - name: taskId in: path required: true schema: type: integer get: tags: - Projects summary: Get the status of a create project from template async task operationId: getProjectTemplateCopyAsyncStatus responses: '200': description: Status of a create project from template async task content: application/json: schema: oneOf: - title: Pending type: object properties: status: type: string enum: - PENDING required: - status - title: Error type: object properties: status: type: string enum: - ERROR result: type: string required: - status - result - title: Success type: object properties: status: type: string enum: - COMPLETE result: $ref: '#/components/schemas/Project' required: - status - result '404': $ref: '#/components/responses/404' components: schemas: ComplianceOption: type: object description: 'Note: we are making terminology updates in Loopio - Compliance Sets shall be referred to as Answer Sets. The API will be updated to reflect this change at a later time.' properties: label: type: string minLength: 1 maxLength: 65535 required: - label UserOrTeamReference: type: object properties: type: type: string enum: - USER - TEAM example: USER id: type: integer example: 1 name: type: string example: name email: type: - string - 'null' format: email example: user@example.com description: Email address when type=USER; null/omitted for TEAM. CustomProjectFieldValuesMap: description: A map from Custom Project Field names to values type: object additionalProperties: x-additionalPropertiesName: '{Custom Project Field name}' type: - string - 'null' maxLength: 100 example: Opportunity Url: https://example.com/CRM/opportunity/abc123 Uninitialized field: null Amount: '1000' Completed Date: '2026-04-06T15:30:45+05:30' ProjectEntryAttachmentUploadResponse: type: object properties: id: type: integer description: The file version ID of the attachment. example: 12607774 filename: type: string description: The full filename including extension. example: blank.pdf required: - id - filename ProjectWide: allOf: - $ref: '#/components/schemas/Project' - type: object properties: documents: type: array items: $ref: '#/components/schemas/ProjectDocument' sections: type: array items: $ref: '#/components/schemas/ProjectSectionWide' required: - documents - sections Project: type: object properties: id: type: integer name: type: string projectType: type: - string - 'null' enum: - RFP - RFI - DDQ - SQ - PP - OTHER - null status: type: string enum: - ACTIVE - COMPLETE - DELETED - STOPPED - DONE - WON - LOST companyName: type: string createdDate: type: string format: date-time dueDate: type: string format: date-time owner: $ref: '#/components/schemas/ReferenceLabel' creator: $ref: '#/components/schemas/ReferenceLabel' description: type: string ProjectSectionWide: type: object properties: id: type: integer name: type: string subSections: type: array items: $ref: '#/components/schemas/ProjectSubSectionWide' questions: type: array items: $ref: '#/components/schemas/EntryNoProjectId' required: - id - name - subSections - questions MergeVariableProjectValuesMap: description: A map from Merge Variable names to values type: object additionalProperties: x-additionalPropertiesName: '{Merge Variable name | not ''Client Name''}' type: - string - 'null' maxLength: 128 example: Deal Size: $100000000000000 Uninitialized variable: null File: type: object properties: id: type: integer filename: type: string fileExtension: type: string example: pdf status: type: string enum: - AVAILABLE - UPLOADING - DELETED size: type: integer creator: $ref: '#/components/schemas/ReferenceLabel' createdDate: type: string format: date-time example: '2019-05-23T15:32:00Z' guid: type: string description: A file's generated unique guid example: 2e7a3fd2928111e3adb1a5bcbc7a2f7b url: type: string description: A file's generated unique signed s3 url (This link expires after 10 minutes) example: https://www.signedUrl.com lastUpdated: type: string format: date-time deprecated: true lastUpdatedDate: type: string format: date-time example: '2019-05-23T15:32:00Z' required: - filename - status - size EntryNoProjectId: type: object properties: id: type: integer question: type: - string - 'null' minLength: 1 maxLength: 65535 answer: type: - object - 'null' properties: text: type: - string - 'null' minLength: 1 maxLength: 65535 complianceAnswers: description: 'Note: we are making terminology updates in Loopio - Compliance Sets shall be referred to as Answer Sets. The API will be updated to reflect this change at a later time.' type: array items: type: object properties: id: type: integer label: type: string option: type: - string - 'null' required: - id - label - option required: - text - complianceAnswers required: - id - question - answer ParticipantReference: type: object properties: type: type: string enum: - USER - TEAM example: USER id: type: integer example: 1 role: type: string enum: - ADMIN - COLLABORATOR - ASSIGNEE example: ADMIN email: type: - string - 'null' format: email example: user@example.com description: Email address when type=USER; null/omitted for TEAM. name: type: string example: John Doe description: User's full name when type=USER; team name when type=TEAM. SubSection: type: object properties: id: type: integer project: type: object properties: id: type: integer required: - id section: type: object properties: id: type: integer required: - id name: type: - string - 'null' required: - id - project - section - name ComplianceSet: type: object description: 'Note: we are making terminology updates in Loopio - Compliance Sets shall be referred to as Answer Sets. The API will be updated to reflect this change at a later time.' properties: id: type: integer project: type: object properties: id: type: integer required: - id label: type: string shortName: type: string minLength: 1 options: type: array minItems: 1 items: type: object properties: label: type: string minLength: 1 required: - label required: - id - project - label - shortName - options Entry: allOf: - $ref: '#/components/schemas/EntryNoProjectId' - properties: inlineImages: type: array items: type: string project: type: object properties: id: type: integer required: - id section: type: object properties: id: type: integer required: - id subSection: type: object properties: id: type: - integer - 'null' required: - id assignee: $ref: '#/components/schemas/UserOrTeamReference' reviewer: $ref: '#/components/schemas/UserOrTeamReference' required: - project CreateProjectRequestBody: type: object properties: name: type: string maxLength: 255 example: Project ABC projectType: $ref: '#/components/schemas/ProjectType' description: type: - string - 'null' companyName: type: string maxLength: 255 dueDate: type: string format: date-time example: '2020-06-08T15:39:04Z' description: The input datetime will be converted to UTC and then pushed to end of day. createdType: type: string enum: - BLANK - TEMPLATE - COPY_OUTLINE - CHROME_EXTENSION - SALESFORCE - MS_DYNAMICS - MS_EXCEL_ADDIN owner: type: object properties: id: type: integer required: - id description: The owner of the Project. If not specified, the user creating the project will be the owner. customProjectFieldValues: description: A value map for any Custom Project Fields. Missing fields will be set to null. Only fields with "project" as their information source can be set. type: object additionalProperties: x-additionalPropertiesName: '{Custom Project Field name}' type: - string - 'null' maxLength: 100 mergeVariableValues: description: A value map for any existing Project Merge Variables. Missing variables will be set to null. type: object additionalProperties: x-additionalPropertiesName: '{Merge Variable name}' type: string maxLength: 128 default: {} example: Client Name: Acme Co. Deal Size: $100000000000000 required: - name - companyName - dueDate - projectType CustomProjectFieldPatchValuesMap: description: A map from Custom Project Field names to values for the patch endpoint request body type: object additionalProperties: x-additionalPropertiesName: '{Custom Project Field name}' type: string maxLength: 100 example: Opportunity Url: https://example.com/CRM/opportunity/abc123 Amount: '1000' Completed Date: '2026-04-06T15:30:45+05:30' Section: type: object properties: id: type: integer project: type: object properties: id: type: integer name: type: - string - 'null' required: - id - project - name ProjectSourceFile: allOf: - $ref: '#/components/schemas/File' - type: object properties: isImportDocument: type: boolean default: false required: - isImportDocument EntryComplianceAnswerCollection: description: 'If provided, the `complianceAnswers` object will replace the current Compliance Answers. Project Compliance Sets are unique per project. Use the /projects/{projectId}/complianceSets API to retrieve a list of available Compliance Sets. The complianceSetId must match one of the Compliance Sets in the given Project, and option must match one of the option labels in the given Compliance Set. Note: we are making terminology updates in Loopio - Compliance Sets shall be referred to as Answer Sets. The API will be updated to reflect this change at a later time. ' type: array items: type: object properties: complianceSetId: type: integer option: type: - string - 'null' ReferenceLabel: type: object properties: id: type: integer example: 1 name: type: string example: name Error: type: object properties: name: type: string enum: - FATAL_ERROR - FORBIDDEN - INVALID_REQUEST - NO_PERMISSION - RESOURCE_NOT_FOUND - UNPROCESSABLE_REQUEST - VALIDATION_ERROR message: type: string debugId: type: string ProjectSummary: type: object properties: id: type: integer description: Project Id name: type: string description: Project Name status: type: string description: Project Status enum: - ACTIVE - DONE - DELETED - STOPPED - WON - LOST companyName: type: string description: Company Name dueDate: type: string format: date-time example: '2019-05-23T15:32:00Z' completedDate: type: - string - 'null' format: date-time example: '2019-05-23T15:32:00Z' owner: type: object description: Project Owner properties: id: type: integer description: User Id name: type: string description: User Name description: type: string description: Project Description projectType: type: - string - 'null' description: Project Type enum: - RFP - RFI - DDQ - SQ - PP - OTHER - null isComplete: type: boolean description: flag to indicate work is done questions: type: object properties: unassigned: type: integer description: Number of unassigned Project Questions assigned: type: integer description: Number of assigned Project Questions review: type: integer description: Number of Project Questions in review complete: type: integer description: Number of completed Project Questions total: type: integer description: Total number of Project Questions workdays: type: object properties: total: type: integer description: Number of workdays from project creation to project due date. elapsed: type: integer description: Number of workdays elapsed since creation of project. left: type: integer description: Number of workdays left since the start of the project. If project work pass due data this number will be negative to indicate overdue days. example: id: 1 name: Project 1 status: ACTIVE companyName: Company 1 dueDate: '2019-05-23T15:32:00Z' owner: id: 1 name: User 1 description: Project Description projectType: RFP isComplete: false questions: unassigned: 3 assigned: 3 review: 2 complete: 1 total: 9 workdays: total: 10 left: -2 elapsed: 12 ProjectType: type: string enum: - RFP - RFI - DDQ - SQ - PP - OTHER ProjectEntryAttachment: type: object properties: id: type: integer description: The file version id (fileVersionId) of the attachment. Use this value when replacing or deleting the attachment. example: 12607774 filename: type: string example: blank.pdf status: type: string enum: - AVAILABLE size: type: integer description: File size in bytes example: 4911 fileExtension: type: string example: pdf guid: type: string description: A file's generated unique guid example: b6ab11b9deffabdd45dec8ae322e04d8 url: type: string description: A file's generated unique signed s3 url (This link expires after 10 minutes) example: https://www.signedUrl.com creator: $ref: '#/components/schemas/ReferenceLabel' lastUpdated: type: string format: date-time example: '2026-04-28T07:08:00+00:00' required: - id - filename - status - size - fileExtension - guid - url - creator - lastUpdated ProjectDocument: type: object properties: file: $ref: '#/components/schemas/ReferenceLabel' sections: type: array items: $ref: '#/components/schemas/ProjectSectionWide' required: - file - sections ProjectSubSectionWide: type: object properties: id: type: integer name: type: string questions: type: array items: $ref: '#/components/schemas/EntryNoProjectId' required: - id - name - questions parameters: RfxTypes: name: rfxTypes in: query schema: type: array items: type: string enum: - RFP - RFI - DDQ - SQ - PP - OTHER description: This will accept multiple project types values to filter the result required: false QueryParamSectionId: name: sectionId in: query description: Section Id required: false schema: type: integer example: 1 PageSize: name: pageSize in: query description: The numbers of items to return schema: type: integer minimum: 1 example: 10 default: 10 required: false ProjectEntryId: name: projectEntryId in: path required: true schema: type: integer Owners: name: owners in: query schema: type: array items: type: integer description: This will accept multiple owners PK to filter the result required: false Page: name: page in: query description: Page number schema: type: integer minimum: 1 example: 5 default: 1 required: false QueryParamSubSectionId: name: subSectionId in: query description: SubSection Id required: false schema: type: integer example: 1 RequiredProjectId: name: projectId in: query schema: type: integer required: true QueryParamInlineOptions: name: inline[] in: query required: false description: '@imagePlaceholders will substitute relative URLs in img src attributes with placeholders that contain the corresponding file ID. (e.g. __INLINE_IMAGE_SOURCE__123456)' schema: type: array items: type: string enum: - '@imagePlaceholders' style: form explode: true SubSectionId: name: subSectionId in: path required: true schema: type: integer SectionId: name: sectionId in: path required: true schema: type: integer responses: '204': description: No Content '400': description: Invalid Request content: application/json: schema: $ref: '#/components/schemas/Error' example: name: INVALID_REQUEST message: Bad request debugId: 0fas3 '422': description: Unprocessable Request content: application/json: schema: $ref: '#/components/schemas/Error' example: name: UNPROCESSABLE_REQUEST message: Unable to process request debugId: 0fas3 UnprocessableJSONPatchRequest: description: Unprocessable Request content: application/json: schema: $ref: '#/components/schemas/Error' example: name: UNPROCESSABLE_REQUEST message: Invalid operation on path /some/path debugId: 0fas3 InvalidJSONPatchDocument: description: Invalid JSON-Patch document content: application/json: schema: $ref: '#/components/schemas/Error' example: name: INVALID_REQUEST message: Invalid JSON-Patch document debugId: 0fas3 '404': description: Resource Not Found content: application/json: schema: $ref: '#/components/schemas/Error' example: name: RESOURCE_NOT_FOUND message: Resource not found debugId: 0fas3 '403': description: No Permission content: application/json: schema: $ref: '#/components/schemas/Error' example: name: NO_PERMISSION message: No permission to access the resource debugId: 0fas3 examples: ProjectNarrow: value: id: 9 name: Project status: ACTIVE companyName: Company createdDate: '2020-01-01T00:00:00Z' dueDate: '2020-01-01T00:00:00Z' owner: id: 100 name: John Doe creator: id: 101 name: Jane Doe description: An example project ProjectWide: value: id: 9 name: Project status: ACTIVE companyName: Company createdDate: '2020-01-01T00:00:00.000Z' dueDate: '2020-01-01T00:00:00.000Z' owner: id: 100 name: John Doe creator: id: 101 name: Jane Doe description: An example project documents: - file: id: 1 name: Document 1 sections: - id: 1 name: Section 1 questions: - id: 1 question: Why'd the chicken cross the road? answer: null subSections: - id: 1 name: SubSection 1.1 questions: - id: 2 question: Why'd the chicken cross the road? answer: - text:
Because he could
- complianceAnswers: - id: 1 label: Label 1 option: 'Yes' - id: 2 label: Label 2 option: A - id: 2 name: Section 2 questions: [] - id: 2 name: Document 2 sections: [] sections: - id: 3 name: Section A subSections: - id: 1 name: SubSection A.1 questions: - id: 3 question: Why'd the chicken cross the road? answer: null - id: 2 name: SubSection A.2 questions: [] questions: [] - id: 4 name: Section 4 subSections: [] questions: - id: 4 question: Why was 6 afraid of 7? answer: null securitySchemes: loopio_auth: type: oauth2 flows: authorizationCode: authorizationUrl: /oauth2/authorize tokenUrl: /oauth2/access_token scopes: mergeVariable:read: View Merge Variables mergeVariable:write: Create/Edit Merge Variables mergeVariable:delete: Delete Merge Variables crm:read: List CRM opportunities linked to projects crm:write: Link CRM opportunities to projects customer.info:read: View customer information file:read: Download files and view file information file:delete: Delete files library:read: List Library Entries and stacks, view Library Entries and Entry data library:write: Create and update Library Entries and Entry data library:delete: Delete Library Entries project:read: List Projects, view Project data and source documents project:write: Create and update Projects, Project data, and source documents project:delete: Delete a Project project.participant:read: List participants of a project project.participant:write: Update participant information role:read: List user assignable roles user:read: List users, view user information user:write: Update user information webhook:read: View webhook subscriptions webhook:write: Create & edit webhook subscriptions webhook:delete: Delete webhook subscriptions clientCredentials: tokenUrl: /oauth2/access_token scopes: mergeVariable:read: View Merge Variables mergeVariable:write: Create/Edit Merge Variables mergeVariable:delete: Delete Merge Variables crm:read: List CRM opportunities linked to projects crm:write: Link CRM opportunities to projects customer.info:read: View customer information file:read: Download files and view file information file:delete: Delete files library:read: List Library Entries and stacks, view Library Entries and Entry data library:write: Create and update Library Entries and Entry data library:delete: Delete Library Entries project:read: List Projects, view Project data and source documents project:write: Create and update Projects, Project data, and source documents project:delete: Delete a Project project.participant:read: List participants of a project project.participant:write: Update participant information role:read: List user assignable roles user:read: List users, view user information user:write: Update user information webhook:read: View webhook subscriptions webhook:write: Create & edit webhook subscriptions webhook:delete: Delete webhook subscriptions