Kenal Stamps Docs

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}/status

Status Response

Both endpoints return the same response shape:

FieldDescription
contractIdKenal Stamps UUID
externalReferenceIdYour reference ID
statusCurrent status (see lifecycle below)
contractTypee.g. Employment, General
timestampsObject with createdAt, confirmedAt, processingAt, stampedAt, failedAt
dutyObject with calculatedDuty, actualDutyPaid, dutyPaymentStatus, dutyType
certificateObject with adjudicationNumber (LHDN reference)

Contract Lifecycle

StatusDescription
QueuedIn the extraction queue
PendingUploaded, awaiting confirmation
ConfirmedWallet charged, awaiting processing
ProcessingBeing submitted to LHDN
CompletedCertificate available for download
FailedProcessing failed — check error details
ArchivedArchived for record-keeping

Download Stamp Certificate

Once a contract reaches Completed status, download the stamp certificate PDF:

GET /api/integration/contracts/{contractId}/certificate

The response is a binary PDF stream with Content-Disposition: attachment header.

StatusDescription
200Certificate PDF file
404Contract not found, not yet completed, or no certificate on record
502Upstream 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.