Download Testimony
Returns a short-lived download link for the final testimony PDF.
HTTP Request
GET /api/v1/testimonies/{testimonyId}/download
Response
302 Found
The Location header points to a presigned object-storage URL valid for 5 minutes. That URL requires no authentication and serves the file with Content-Type: application/pdf and Content-Disposition: attachment; filename="testimony-{testimonyId}.pdf".
Frontend integration
The API request itself needs the Authorization: Bearer header, so a plain <a href> or window.open() pointing at the API URL fails with 401. Use fetch and let it follow the redirect:
const response = await fetch(`/api/v1/testimonies/${testimonyId}/download`, {
headers: { Authorization: `Bearer ${accessToken}` },
redirect: 'follow',
});
const blob = await response.blob();
window.open(URL.createObjectURL(blob)); // or trigger a downloadThe browser drops the Authorization header on the cross-origin hop to the storage host (the presigned URL is self-authenticating). The storage bucket has to allow your origin via CORS for fetch to read the file — the local RustFS setup allows every origin. redirect: 'manual' is not an option in browsers: it yields an opaque response without the Location header.
Authentication
Requires authentication via Bearer token and a verified email. Only the testimony's client or the assigned expert may download the document (403 Forbidden otherwise).
401 Unauthorized
{
"message": "Unauthenticated."
}Error Handling
404 Not Found — the testimony has no document yet (it is not completed):
{
"message": "Testimony file not found."
}In production the message is the generic Not Found (see Error Responses).