Get CMR document in PDF format
GET/company/cmr/:service_code
Retrieve the CMR document (Digital Consignment Note / eCMR) in PDF format associated with a specific transport service. The CMR is the mandatory legal document for the international road transport of goods under the CMR Convention.
Objective
Enable companies to download the official eCMR document in PDF format for archiving, printing, or sharing with customers and authorities. The document is generated by the specialized ecmr_back service and delivered as a binary file.
Use Cases
- A company needs to download the CMR for a shipment that has just been completed
- A customer requests the official CMR document for their accounting
- The CMR is required to be presented to customs authorities during a transport inspection
- The company needs to digitally archive the CMR due to legal requirements
Architecture Note
This endpoint acts as a proxy to the ecmr_back service (a microservice specialized in eCMR document management). The PDF is generated and delivered by ecmr_back, then transmitted as a binary stream to the client.
Preconditions:
- User must be authenticated and exist in database
- User must belong to a valid company
- A delivery with the given service_code must exist for the company
- The delivery must have an associated eCMR document
Error Codes:
USER_NOT_FOUND(401): Authenticated user does not exist in databaseAUTHORIZATION_TOKEN_REQUIRED(401): Token missing or invalid in request headersCOMPANY_NOT_FOUND(Internal): User has no associated company (rejected before API response)NOT_FOUND(404): Delivery not found for this company/service_codeFILE_NOT_AVAILABLE(404): CMR PDF file not available in ecmr_back service- Service error (503): ecmr_back service unavailable or timeout
Validation Flow:
flowchart TD
A[Receive Request] --> B\{User Authenticated?\}
B -->|No| C[401 USER_NOT_FOUND]
B -->|Yes| D\{Token Present?\}
D -->|No| E[401 AUTHORIZATION_TOKEN_REQUIRED]
D -->|Yes| F\{User Exists in DB?\}
F -->|No| G[401 USER_NOT_FOUND]
F -->|Yes| H\{Company Found?
<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>
<ParamsDetails
parameters={[{"name":"service_code","in":"path","required":true,"description":"Unique code of the transport service for which the CMR is requested.\nThis code is automatically generated when creating the delivery and allows for the unambiguous identification of the associated transport operation.\n**Typical format:** PREFIX-YEAR-NUMBER (example: TRANS-2023-0042)","schema":{"type":"string","minLength":5,"maxLength":50,"pattern":"^[A-Z0-9-]+$","example":"TRANS-2023-0042"}}]}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={undefined}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"CMR document in PDF format successfully downloaded.\nThe file is transmitted as a direct binary stream from the ecmr_back service.","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}},"headers":{"Content-Type":{"description":"File content type","schema":{"type":"string","example":"application/pdf"}},"Content-Disposition":{"description":"Indicates that the file should be downloaded as an attachment with the specified filename.\nFormat: attachment; filename={service_code}.pdf","schema":{"type":"string","example":"attachment; filename=\"TRANS-2023-0042.pdf\""}},"Content-Length":{"description":"PDF file size in bytes","schema":{"type":"integer","example":245632}},"Content-Encoding":{"description":"Encoding type (always identity for this endpoint)","schema":{"type":"string","example":"identity"}},"Cache-Control":{"description":"Cache directive to prevent transformations","schema":{"type":"string","example":"no-transform"}}}},"401":{"description":"Unauthorized - The user is not authenticated or the token is invalid.\n**Possible error codes:**\n- `USER_NOT_FOUND`: The authenticated user does not exist in the database\n- `AUTHORIZATION_TOKEN_REQUIRED`: The token is missing from the headers or is invalid","content":{"application/json":{"schema":{"type":"object","required":["status","message"],"properties":{"status":{"type":"integer","description":"HTTP status code","minimum":400,"maximum":599,"example":400},"message":{"type":"string","description":"Error code from the system.\n\nCommon error codes (see listado_errores_http.txt for complete list):\n- NO_TOKEN (401): JWT token not provided\n- TOKEN_NOT_VALID (401): JWT token is invalid or expired\n- NO_ADMIN_ROLE (401): User does not have admin privileges\n- INVALID_PARAMETERS (400): Request parameters are invalid\n- NOT_FOUND (404): Requested resource not found\n- ALREADY_EXIST (401): Resource with same identifier already exists\n- UTC_VALIDATION_FAILED (400): UTC timestamp validation failed\n- INTERNAL_ERROR (500): Unexpected server error occurred\n\nThe message is resolved by `handlerError.getErrorMessage(error)`.","example":"INVALID_PARAMETERS"}},"description":"Standard error response format used across all API endpoints.\n\nAll errors follow the pattern `{status: number, message: string}`.\nThe status code is repeated in both the HTTP response and the body.\n\nError messages are constants defined in the codebase and should be\nhandled on the client side with appropriate user-facing messages.","example":{"status":400,"message":"INVALID_PARAMETERS"},"title":"ErrorResponse"},"examples":{"userNotFound":{"summary":"User not found in database","value":{"message":"USER_NOT_FOUND"}},"tokenRequired":{"summary":"Missing or invalid token","value":{"message":"AUTHORIZATION_TOKEN_REQUIRED"}}}}}},"404":{"description":"Not found - No CMR is available for the provided service_code.\n**Possible causes:**\n- The service code is incorrect or does not belong to this company\n- The delivery exists but the CMR has not been generated yet\n- The CMR file was deleted or is not available in ecmr_back\n**Error codes:**\n- `NOT_FOUND`: The delivery does not exist for this company\n- `FILE_NOT_AVAILABLE`: The CMR is not available in ecmr_back","content":{"application/json":{"schema":{"type":"object","required":["status","message"],"properties":{"status":{"type":"integer","description":"HTTP status code","minimum":400,"maximum":599,"example":400},"message":{"type":"string","description":"Error code from the system.\n\nCommon error codes (see listado_errores_http.txt for complete list):\n- NO_TOKEN (401): JWT token not provided\n- TOKEN_NOT_VALID (401): JWT token is invalid or expired\n- NO_ADMIN_ROLE (401): User does not have admin privileges\n- INVALID_PARAMETERS (400): Request parameters are invalid\n- NOT_FOUND (404): Requested resource not found\n- ALREADY_EXIST (401): Resource with same identifier already exists\n- UTC_VALIDATION_FAILED (400): UTC timestamp validation failed\n- INTERNAL_ERROR (500): Unexpected server error occurred\n\nThe message is resolved by `handlerError.getErrorMessage(error)`.","example":"INVALID_PARAMETERS"}},"description":"Standard error response format used across all API endpoints.\n\nAll errors follow the pattern `{status: number, message: string}`.\nThe status code is repeated in both the HTTP response and the body.\n\nError messages are constants defined in the codebase and should be\nhandled on the client side with appropriate user-facing messages.","example":{"status":400,"message":"INVALID_PARAMETERS"},"title":"ErrorResponse"},"examples":{"notFound":{"summary":"Delivery not found","value":{"message":"NOT_FOUND"}},"fileNotAvailable":{"summary":"CMR file not available","value":{"message":"FILE_NOT_AVAILABLE"}}}}}},"503":{"description":"Service unavailable - Error communicating with the ecmr_back service or timeout during PDF generation. \n**Possible causes:** \n- The ecmr_back service is unavailable \n- Timeout waiting for PDF generation (maximum 30 seconds) \n- Internal error in the ecmr_back service","content":{"application/json":{"schema":{"type":"object","required":["status","message"],"properties":{"status":{"type":"integer","description":"HTTP status code","minimum":400,"maximum":599,"example":400},"message":{"type":"string","description":"Error code from the system.\n\nCommon error codes (see listado_errores_http.txt for complete list):\n- NO_TOKEN (401): JWT token not provided\n- TOKEN_NOT_VALID (401): JWT token is invalid or expired\n- NO_ADMIN_ROLE (401): User does not have admin privileges\n- INVALID_PARAMETERS (400): Request parameters are invalid\n- NOT_FOUND (404): Requested resource not found\n- ALREADY_EXIST (401): Resource with same identifier already exists\n- UTC_VALIDATION_FAILED (400): UTC timestamp validation failed\n- INTERNAL_ERROR (500): Unexpected server error occurred\n\nThe message is resolved by `handlerError.getErrorMessage(error)`.","example":"INVALID_PARAMETERS"}},"description":"Standard error response format used across all API endpoints.\n\nAll errors follow the pattern `{status: number, message: string}`.\nThe status code is repeated in both the HTTP response and the body.\n\nError messages are constants defined in the codebase and should be\nhandled on the client side with appropriate user-facing messages.","example":{"status":400,"message":"INVALID_PARAMETERS"},"title":"ErrorResponse"},"example":{"message":"Service error from ecmr_back"}}}}}}
>
</StatusCodes>