Update Lab Visit (v1)
Method & Path
PATCH /api/v1/workspace/:workspaceId/labs/visits/:labVisitId
Actual backend path: /v1/workspace/:workspaceId/labs/visits/:labVisitId
Description
Update an existing lab visit. Certain status transitions may be rejected (e.g., updating invoiced/cancelled visits).
Authentication
Required: JWT token in Authorization header
Persona Access:
- Admin: Not applicable (workspace-scoped endpoint)
- Workspace Owner: Allowed
- Staff: Allowed (role-based)
- Customer: Not allowed
Required Permissions:
labs.run
Headers
| Header | Type | Required | Description |
|---|---|---|---|
Authorization | string | Yes | Bearer token: Bearer <token> |
Content-Type | string | Yes | application/json |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
workspaceId | string | Yes | Workspace identifier (MongoDB ObjectId) |
labVisitId | string | Yes | Lab visit identifier (MongoDB ObjectId) |
Request Body
{
"labVisitStatus": "in-progress",
"referralId": "507f1f77bcf86cd799439099",
"labVisitNotes": "Sample collected",
"labVisitSubtotal": 50,
"labCouponCode": null
}
| Field | Type | Required | Description |
|---|---|---|---|
labVisitStatus | string | No | pending, in-progress, results-entered, invoiced, cancelled, ready |
labVisitType | string | No | in-lab or at-home |
referralId | string | null | No | Referral identifier (MongoDB ObjectId). Set to null to clear |
labTestIds | number[] | No | Replace the test set for the visit (numeric test IDs) |
labVisitDate | string | No | ISO datetime |
labVisitNotes | string | null | No | Notes (max 2000 chars) |
labVisitSubtotal | number | null | No | Manual subtotal override. Set to null to reset to auto-calculated subtotal from test prices |
labCouponCode | string | null | No | Coupon code to apply (or null to clear) |
Test removal behavior
When updating labTestIds and removing a test from the visit, the backend will also delete any saved results for the removed test(s).
Response 200 OK
{
"labVisit": {
"id": "507f1f77bcf86cd799439011",
"workspaceId": "507f1f77bcf86cd799439012",
"clientId": "507f1f77bcf86cd799439013",
"referralId": "507f1f77bcf86cd799439099",
"labVisitType": "in-lab",
"labVisitStatus": "in-progress",
"labTestIds": [101],
"labTestSnapshots": [
{ "test": { "testId": 101, "testTitle": "CBC" }, "designTest": null }
],
"labTestResults": [],
"labVisitDate": "2026-01-10T12:00:00.000Z",
"labVisitNotes": "Sample collected",
"labVisitPricing": {
"labVisitSubtotal": 30,
"labCouponId": null,
"labCouponCode": null,
"labVisitDiscountAmount": 0,
"labVisitTotal": 30
},
"deletedAt": null,
"createdAt": "2026-01-10T12:00:00.000Z",
"updatedAt": "2026-01-11T08:00:00.000Z"
}
}
Common Errors
400 Bad Request: Empty update payload or invalid request body
401 Unauthorized: Missing or invalid authentication token
403 Forbidden: Insufficient permissions (labs.run required)
404 Not Found: Workspace or lab visit not found
422 Validation Error: Invalid IDs, invalid coupon, missing tests, or forbidden update (e.g., invoiced/cancelled)