ShipX provides a manner to upload a document. 


Authentication is performed by including the following HTTP header:


The JWT must be signed using your provided secret or private key, and the payload must contain the following fields described in step 2 below. Here is an example digram of how it's broken down. 


Endpoint:

POST https://api.shipx.cc/booking/upload-document // For Production
POST https://uat-api.shipx.cc/booking/upload-document // For UAT
POST https://staging-api.shipx.cc/booking/upload-document // For Staging


Headers:

  1. Authorization: Bearer <JWT_TOKEN>


JWT Generation

  1. Generate fileHash:
    1. const crypto = require('crypto');
      const fileHash = crypto.createHash('sha256').update(fileBuffer).digest('hex');
  2. Create a serialized body by adding fileHash into an object with the rest of the payload except for the file:
    1. const payload = {
        uuid: "12345678-1234-1234-1234-123456789012", // bookingUuid
        type: "docType",
        file: (Binary)
      };
      
      const serialized = {
        uuid: "12345678-1234-1234-1234-123456789012",
        type: "docType",
        fileHash: "abc123"
      };
  3. Generate payloadHash:
    1. Hash the serialized request body (as a string) using the algorithm specified (e.g., sha256).
    2. Example (Node.js):
      1. const payloadHash = crypto.createHash('sha256').update(serialized).digest('hex');
    3. Example (VB)
      1. See document here.
  4. JWT Payload Fields:
    • iat: Issued at time (Unix timestamp, seconds).
    • exp: Expiration time (Unix timestamp, seconds). Should be within 10 minutes of iat.
    • portalCompanyUuid: Your portal company UUID.
    • baseCompanyUuid: Your base company UUID.
    • payloadHash: The hash from step 1.
    • Example:
      • {
          "iat": 1714300000,
          "exp": 1714300600,
          "portalCompanyUuid": "your-portal-company-uuid",
          "baseCompanyUuid": "your-base-company-uuid",
          "payloadHash": "abcdef1234567890..."
        }
        
        
  5. Sign the JWT
    1. Use your provided secret or private key. To learn how to generate a key pair, see here. Ensure to paste the public key where you replace the end line character with \n. 
    2. Example (Node.js, using jsonwebtoken)
      1. const jwt = require('jsonwebtoken');
        const token = jwt.sign(jwtPayload, secretOrPrivateKey);
  6. Include JWT in the Authorization Header:
    1. Authorization: Bearer <token>



Example Request

POST https://shipx.cc/booking/upload-document
Authorization: Bearer <token>


type: cmoDocument                          // Type defined by BookingType/JobType
uuid: 78ebdfab-1b2b-4bf6-90ea-4cb540c9c433 // bookingUuid of newly created booking.
files: (binary)


Example Response


{
  "uuid": "289bc7b2-45e9-4860-ac98-73e27b906d23",
  "document": {
    "uuid": "6f5bd7b6-24bd-41c6-85f9-555d940079c2",
    "status": "ACTIVATED",
    "path": "uploads/3236c249d38bca17ab6e3ec6631fc1db",
    "size": 448,
    "key": "4b0a0c48-5c74-4903-a77f-43465853b2bf",
    "eTag": "\"2601d27375af91a74656e7e887ea8ff3\"",
    "location": "https://s3.ap-southeast-1.amazonaws.com/stag.shipx.cc/4b0a0c48-5c74-4903-a77f-43465853b2bf",
    "name": "clock-three-svgrepo-com.svg",
    "type": "image/svg+xml",
    "updatedAt": "2025-06-12T01:10:44.446Z",
    "createdAt": "2025-06-12T01:10:44.446Z"
  },
  "type": "hlgPodDoc",
  "reference": null,
  "remarks": null,
  "jobUuid": null,
  "tripUuid": null,
  "tags": [
    "IS_DRIVER_UPLOADED"
  ],
  "status": "UPLOADED",
  "createdByUuid": "00a7d37c-59f2-4ea5-b553-7f691cc9e141",
  "updatedAt": "2025-06-12T01:10:44.443Z",
  "createdAt": "2025-06-12T01:10:44.443Z",
  "documentUuid": "6f5bd7b6-24bd-41c6-85f9-555d940079c2",
  "location": null,
  "verifiedByUuid": null,
  "requestUuid": null,
  "voucherUuid": null,
  "url": "https://staging-api.shipx.cc/booking/document/6f5bd7b6-24bd-41c6-85f9-555d940079c2"
}



Notes:

  • The JWT must be generated for each request, as the payloadHash must match the body.
  • iat and exp are required and should be set to the current time and current time + 10 minutes, respectively.
  • If the JWT is invalid or expired, the request will be rejected.
  • The body in the request should be the payload object, not serialized
  • Documents not linked to a booking will be purged within a week.