DevelopersAPI referenceProjects

Project files API

REST endpoints for project files in ServFlo: 6 operations with parameters, request and response fields, permissions and curl examples.

Base URL: https://app.servflo.ai/api. Every call needs Authorization: Bearer sfk_… (Authentication); {organizationId} ($ORGANIZATION_ID in the examples) is your business's id.

OperationEndpointRisk
A project's filesGET /organizations/{organizationId}/projects/{projectId}/filesread
Start uploading a project filePOST /organizations/{organizationId}/projects/{projectId}/fileswrite
Finish uploading a project filePOST /organizations/{organizationId}/projects/{projectId}/files/{projectFileId}/confirmwrite
Add a project file (content in the request)POST /organizations/{organizationId}/projects/{projectId}/files/contentwrite
Share a project file or change its categoryPATCH /organizations/{organizationId}/projects/{projectId}/files/{projectFileId}sensitive
Delete a project fileDELETE /organizations/{organizationId}/projects/{projectId}/files/{projectFileId}sensitive

A project's files

GET /organizations/{organizationId}/projects/{projectId}/files

Plans, permits, contracts, photos and lien waivers with who they are shared with and 10-minute URLs. Technicians see those shared with the crew. Read-only.

Permissionprojects.read (Owner, Admin, Dispatcher, Technician, Member)
Riskread, OAuth scope servflo.read. Read: reads only.
MCP toolprojectFiles_list (toolset projects)

Parameters

NameInTypeRequiredDescription
projectIdpathstringYesThe project (GET /projects).
categoryqueryenumNoOne of PLAN, PERMIT, CONTRACT, PHOTO, SELECTION, LIEN_WAIVER, OTHER.
dailyLogIdquerystringNo
phaseIdquerystringNo

Example

curl "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/projects/{projectId}/files" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields

An array of objects:

FieldTypeDescription
idstring
categoryenumOne of PLAN, PERMIT, CONTRACT, PHOTO, SELECTION, LIEN_WAIVER, OTHER.
fileNamestring
contentTypestring
sharedWithCrewboolean
sharedWithSubsboolean
sharedWithCustomerboolean
urlstringA 10-minute download URL.

Start uploading a project file

POST /organizations/{organizationId}/projects/{projectId}/files

Step 1 of a browser upload: records the file and returns a signed URL to PUT it to (5 minutes, same Content-Type), then POST …/files/{projectFileId}/confirm. Up to 25 MB. Sharing defaults by category (plans: everyone; photos: the crew). API keys and AI apps use POST …/files/content.

Permissionprojects.field (Owner, Admin, Dispatcher, Technician)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolprojectFiles_createUpload (toolset projects)

Parameters

NameInTypeRequiredDescription
projectIdpathstringYesThe project (GET /projects).

Request body

FieldTypeRequiredDescription
fileNamestringYesUp to 255 characters.
contentTypestringYesUp to 100 characters.
sizeBytesintegerYesAt least 1.
categoryenumNoPLAN, PERMIT, CONTRACT, PHOTO, SELECTION, LIEN_WAIVER or OTHER (the crew adds PHOTO or OTHER). One of PLAN, PERMIT, CONTRACT, PHOTO, SELECTION, LIEN_WAIVER, OTHER. Default OTHER.
phaseIdstring or nullNo
dailyLogIdstring or nullNoA photo of this daily log.
subPaymentIdstring or nullNoA lien waiver for this payment to a subcontractor.
sharedWithCrewbooleanNo
sharedWithSubsbooleanNo
sharedWithCustomerbooleanNo

Example

curl -X POST "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/projects/{projectId}/files" \
  -H "Authorization: Bearer $SERVFLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"fileName":"string","contentType":"string","sizeBytes":1}'

Response

201: the answer's fields
FieldTypeDescription
fileobject
file.idstring
file.fileNamestring
uploadUrlstring

Finish uploading a project file

POST /organizations/{organizationId}/projects/{projectId}/files/{projectFileId}/confirm

Step 2: the PUT finished; the file is listed from now on.

Permissionprojects.field (Owner, Admin, Dispatcher, Technician)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolprojectFiles_confirm (toolset projects)

Parameters

NameInTypeRequiredDescription
projectIdpathstringYesThe project (GET /projects).
projectFileIdpathstringYes

Example

curl -X POST "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/projects/{projectId}/files/{projectFileId}/confirm" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
idstring
categoryenumOne of PLAN, PERMIT, CONTRACT, PHOTO, SELECTION, LIEN_WAIVER, OTHER.
fileNamestring
contentTypestring
sharedWithCrewboolean
sharedWithSubsboolean
sharedWithCustomerboolean
urlstringA 10-minute download URL.

Add a project file (content in the request)

POST /organizations/{organizationId}/projects/{projectId}/files/content

Adds a plan, permit, contract, photo or lien waiver in one call: send contentBase64 or a public sourceUrl (up to 10 MB). Returns the file with a 10-minute URL.

Permissionprojects.field (Owner, Admin, Dispatcher, Technician)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolprojectFiles_upload (toolset projects)

Parameters

NameInTypeRequiredDescription
projectIdpathstringYesThe project (GET /projects).

Request body

FieldTypeRequiredDescription
categoryenumNoPLAN, PERMIT, CONTRACT, PHOTO, SELECTION, LIEN_WAIVER or OTHER (the crew adds PHOTO or OTHER). One of PLAN, PERMIT, CONTRACT, PHOTO, SELECTION, LIEN_WAIVER, OTHER. Default OTHER.
phaseIdstring or nullNo
dailyLogIdstring or nullNoA photo of this daily log.
subPaymentIdstring or nullNoA lien waiver for this payment to a subcontractor.
sharedWithCrewbooleanNo
sharedWithSubsbooleanNo
sharedWithCustomerbooleanNo
fileNamestringNoThe file's name, e.g. receipt.jpg (default: from the URL, else 'file'). Up to 500 characters.
contentTypestringNoMIME type, e.g. image/jpeg or application/pdf. Optional: taken from a data: URL, the URL's answer or the file's first bytes. Up to 200 characters.
contentBase64stringNoThe file's bytes as base64 (a data: URL is accepted too). Up to 10 MB. Give this or sourceUrl.
sourceUrlstring (uri)NoA public http(s) URL ServFlo downloads the file from (up to 10 MB, 20 s, 3 redirects; private and internal addresses are refused). Give this or contentBase64. Up to 2000 characters.

Example

curl -X POST "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/projects/{projectId}/files/content" \
  -H "Authorization: Bearer $SERVFLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"category":"OTHER","phaseId":"phase_id","dailyLogId":"dailyLog_id"}'

Response

201: the answer's fields
FieldTypeDescription
idstring
categoryenumOne of PLAN, PERMIT, CONTRACT, PHOTO, SELECTION, LIEN_WAIVER, OTHER.
fileNamestring
contentTypestring
sharedWithCrewboolean
sharedWithSubsboolean
sharedWithCustomerboolean
urlstringA 10-minute download URL.

Share a project file or change its category

PATCH /organizations/{organizationId}/projects/{projectId}/files/{projectFileId}

EXPOSES TO THE CUSTOMER OR SUBS when switched on: who the file is shared with (crew, subcontractors' links, the customer's portal), its category and phase.

Permissionprojects.write (Owner, Admin, Dispatcher)
Risksensitive, OAuth scope servflo.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP toolprojectFiles_update (toolset projects)
ApprovalOver MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in ServFlo). See Approvals.

Parameters

NameInTypeRequiredDescription
projectIdpathstringYesThe project (GET /projects).
projectFileIdpathstringYes

Request body

FieldTypeRequiredDescription
categoryenumNoOne of PLAN, PERMIT, CONTRACT, PHOTO, SELECTION, LIEN_WAIVER, OTHER.
phaseIdstring or nullNo
sharedWithCrewbooleanNo
sharedWithSubsbooleanNo
sharedWithCustomerbooleanNo

Example

curl -X PATCH "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/projects/{projectId}/files/{projectFileId}" \
  -H "Authorization: Bearer $SERVFLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"category":"PLAN","phaseId":"phase_id","sharedWithCrew":true}'

Response

200: the answer's fields
FieldTypeDescription
idstring
categoryenumOne of PLAN, PERMIT, CONTRACT, PHOTO, SELECTION, LIEN_WAIVER, OTHER.
fileNamestring
contentTypestring
sharedWithCrewboolean
sharedWithSubsboolean
sharedWithCustomerboolean
urlstringA 10-minute download URL.

Delete a project file

DELETE /organizations/{organizationId}/projects/{projectId}/files/{projectFileId}

Destructive: deletes the project file for everyone (crew, subs and the customer stop seeing it).

Permissionprojects.write (Owner, Admin, Dispatcher)
Risksensitive, OAuth scope servflo.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP toolprojectFiles_delete (toolset projects)
ApprovalOver MCP, this tool always waits for your approval in ServFlo. See Approvals.

Parameters

NameInTypeRequiredDescription
projectIdpathstringYesThe project (GET /projects).
projectFileIdpathstringYes

Example

curl -X DELETE "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/projects/{projectId}/files/{projectFileId}" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
oktrue

On this page