Documents
Compliance documents (NDAs, IP assignment forms, equipment return acknowledgements, and similar exit paperwork) are stored per-offboarding in the compliance_documents table. There are two ways to create one - upload a file directly, or register a record that points at a file you've already stored elsewhere - and a separate set of endpoints for sending them out for e-signature.
Like the checklist endpoints, these are session-authenticated app routes, not part of /api/v1.
Upload a document
POST /api/upload/compliance/:offboardingId
Content-Type: multipart/form-data
| Field | Type | Description |
|---|---|---|
file | file | PDF, DOC, DOCX, PNG, or JPG - max 10MB |
docType | string | Document category (defaults to Other) |
name | string | Display name (defaults to the uploaded filename) |
The upload is validated against the file's actual magic bytes, not just its extension, and stored in your organization's GCS bucket. Requires the fileUploads plan feature.
Response 201 Created
{
"id": "doc_01HQ3",
"offboarding_id": "e3b0c442-...",
"name": "exit-nda.pdf",
"doc_type": "NDA",
"status": "pending",
"file_url": "compliance/org_123/e3b0c442-.../a1b2c3....pdf",
"created_at": "2024-06-01T10:00:00.000Z"
}file_url is the internal storage key, not a public link - fetch a temporary signed URL via GET /api/upload/files/* when you need to display or download the file.
Register a document by reference
POST /api/employees/:id/compliance
Use this instead of the upload endpoint when the file already lives somewhere else (e.g. generated by the document templates endpoint, or hosted externally).
Request body
{
"name": "Exit NDA",
"docType": "NDA",
"fileUrl": "https://storage.example.com/nda.pdf"
}| Field | Required | Description |
|---|---|---|
name | Yes | Document name |
docType | No | Defaults to Other |
fileUrl | No | Must be a public HTTPS URL - private/internal/loopback hosts are rejected |
Response 200 OK - the created compliance_documents row, with status: "pending".
Update a document
PATCH /api/employees/compliance/:docId/status
Request body
| Field | Description |
|---|---|
status | New status |
signed_by | Who signed it |
signed_at | Signing timestamp |
expires_on | Expiry date, for documents that need periodic renewal |
Response 200 OK - the updated document row.
Delete a document
DELETE /api/employees/compliance/:docId
Deletes the database record and, if a file is attached, removes it from storage too.
Response 200 OK
{ "success": true }Generate from a template
POST /api/document-templates/:id/generate
Renders a saved document template (with merge fields like {{employee_name}} and {{exit_date}} filled in from the offboarding record) into an HTML file and creates a compliance_documents row for it.
Request body
{ "offboardingId": "e3b0c442-..." }Response 201 Created - the created document, plus a short-lived signed_url for immediate viewing.
E-signature
E-signature is a separate feature, routed under /api/esignature, and works against a document's id from compliance_documents.
Request a signature
POST /api/esignature/request/:documentId
Request body
{ "provider": "docusign" }provider is optional - docusign, adobe_sign, or dropbox_sign. If omitted, PurpletGo uses whichever provider your organization has connected under Integrations, falling back to Dropbox Sign if one is globally configured. Fails with 400 if no provider is available or the document has no file attached, and 409 if a request is already pending.
Response 200 OK
{ "success": true, "requestId": "abc123", "signingUrl": "https://...", "provider": "docusign" }Check signature status
GET /api/esignature/status/:documentId
Returns the document's current esignature_status, esignature_provider, and esignature_request_id.
Cancel a signature request
POST /api/esignature/cancel/:documentId
Cancels a pending request with the provider and sets esignature_status back to cancelled.