Get File Metadata
GET
/api/v1/users/me/files/:id/metadataReturns metadata for a single attachment. The 404 response is uniform across not-found, soft-deleted, wrong-owner, and wrong-tenant cases (no enumeration).
Bearer accessToken
Production
https://api.care360-next.carevalidate.com/api/v1/users/me/files/{id}/metadataStaging
https://api-staging.care360-next.carevalidate.com/api/v1/users/me/files/{id}/metadataHeaders
Headers
AuthorizationstringrequiredBearer access token from /verify-otp.
Example:
Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9...Path Parameters
Path Parameters
idstringrequiredAttachment UUID.
Example:
550e8400-e29b-41d4-a716-446655440000Behavior
The handler returns 404 VALIDATION_ERROR "File not found" if any of the following is true:
- The attachment does not exist.
isDeleted === true.case.submitterId !== req.patientUser.id(not the patient's case).case.organizationId !== req.patientOrganization.id(wrong tenant).
The 404 is deliberately uniform — clients cannot tell which condition fired.
A signed viewUrl is minted for the attachment. If the underlying GCS object is missing for an orphaned DB record, viewUrl and viewUrlExpiresIn are null in the response rather than failing the request. Other storage errors (e.g. a temporary outage) return an error response instead of null.
Response Shape
Example Request
- cURL
- JavaScript
- Python
curl -X GET '<BASE_URL>/api/v1/users/me/files/<id>/metadata' \
-H 'Authorization: Bearer <accessToken>'
const response = await fetch(
'<BASE_URL>/api/v1/users/me/files/<id>/metadata',
{
method: 'GET',
headers: {
'Authorization': 'Bearer <accessToken>',
},
}
);
const data = await response.json();
console.log(data);
import requests
response = requests.get(
'<BASE_URL>/api/v1/users/me/files/<id>/metadata',
headers={
'Authorization': 'Bearer <accessToken>',
},
)
print(response.json())
Responses
▶200Success
{
"status": 200,
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"fileName": "lab-result.pdf",
"isPHI": true,
"isRestricted": false,
"caseId": "550e8400-e29b-41d4-a716-446655440111",
"uploadedBy": {
"id": "550e8400-e29b-41d4-a716-446655440222",
"firstName": "Jane",
"lastName": "Doe"
},
"createdAt": "2026-04-15T12:34:56.000Z",
"viewUrl": "https://storage.googleapis.com/...?GoogleAccessId=<serviceAccount>&Expires=<unixTimestamp>&Signature=<sig>&response-content-disposition=inline",
"viewUrlExpiresIn": 3600
}
}
▶400Validation errorid is not a UUID.
{
"status": 400,
"success": false,
"error": "Validation failed",
"code": "VALIDATION_ERROR"
}
▶401Authentication failure
{
"status": 401,
"success": false,
"error": "Invalid or expired token",
"code": "VALIDATION_ERROR"
}
▶404File not foundUniform across not-found, soft-deleted, wrong-owner, wrong-tenant.
{
"status": 404,
"success": false,
"error": "File not found",
"code": "VALIDATION_ERROR"
}
▶429Rate limit exceededMore than 100 requests per minute from this organization on this endpoint.
{
"status": 429,
"success": false,
"error": "Rate limit exceeded",
"message": "Maximum 100 requests per 60 seconds exceeded",
"retryAfter": 60,
"code": "CASE_ERROR"
}
Try It Out
Try itAPI Playground
▶