Contract Status API
Query contract status and download stamp certificates.
Query the status of submitted contracts and download completed stamp certificates.
For the full request/response schema, see the API Reference.
Query by External Reference ID
Look up a contract using your own externalReferenceId. Scoped to contracts belonging to your integration.
GET /api/integration/contracts/status?externalReferenceId={ref}Query by Contract ID
Look up a contract using the Kenal Stamps contract UUID (returned when you submitted the contract).
GET /api/integration/contracts/{contractId}/statusStatus Response
Both endpoints return the same response shape:
| Field | Description |
|---|---|
contractId | Kenal Stamps UUID |
externalReferenceId | Your reference ID |
status | Current status (see lifecycle below) |
contractType | e.g. Employment, General |
timestamps | Object with createdAt, confirmedAt, processingAt, stampedAt, failedAt |
duty | Object with calculatedDuty, actualDutyPaid, dutyPaymentStatus, dutyType |
certificate | Object with adjudicationNumber (LHDN reference) |
Contract Lifecycle
| Status | Description |
|---|---|
Queued | In the extraction queue |
Pending | Uploaded, awaiting confirmation |
Confirmed | Wallet charged, awaiting processing |
Processing | Being submitted to LHDN |
Completed | Certificate available for download |
Failed | Processing failed — check error details |
Archived | Archived for record-keeping |
Download Stamp Certificate
Once a contract reaches Completed status, download the stamp certificate PDF:
GET /api/integration/contracts/{contractId}/certificateThe response is a binary PDF stream with Content-Disposition: attachment header.
| Status | Description |
|---|---|
200 | Certificate PDF file |
404 | Contract not found, not yet completed, or no certificate on record |
502 | Upstream storage temporarily unavailable (check Retry-After header) |
Signing GET Requests
Remember: for GET requests, the body hash is computed over an empty string, and the path used for signing is the pathname only (no query parameters).
// Status by reference ID
const path = "/api/integration/contracts/status"; // NOT including ?externalReferenceId=...
const bodyHash = crypto.createHash("sha256").update("").digest("hex");
// Status by contract ID
const path = `/api/integration/contracts/${contractId}/status`;
// Certificate download
const path = `/api/integration/contracts/${contractId}/certificate`;See Authentication for the full signing guide.