Skip to content

Client & Authentication ​

MyInvoisClient.create(options) ​

Preferred factory. Options:

OptionTypeNotes
clientId / clientSecretstringFrom the MyInvois portal
environment'sandbox' | 'production'Preprod vs live base URL
certificatePem / privateKeyPemstringSigning credentials (validated as a pair)
onBehalfOf?stringIntermediary access: TIN or TIN:ROB — see Intermediaries
debug?booleanVerbose logging (defaults to MYINVOIS_DEBUG === 'true')
rateLimitStore?RateLimitStoreShared limiter backend — see Rate Limiting
tokenStore?TokenStoreShared token cache
retryOn429?false | { maxRetries?, maxDelayMs? }Automatic Retry-After back-off (default { maxRetries: 2, maxDelayMs: 60000 })

MyInvoisClient.fromP12(clientId, clientSecret, environment, p12Input, passphrase, onBehalfOf?, debug?) ​

Creates a client from a PKCS#12 bundle (path or Buffer) — extracts the certificate and private key for you.

new MyInvoisClient(...) ​

Positional constructor, kept stable for existing callers: (clientId, clientSecret, environment, certificatePem, privateKeyPem, onBehalfOf?, debug?, advanced?).

Authentication ​

There is no explicit login call. The client logs in lazily before the first API request, per the official OAuth2 client-credentials flow:

Tokens are cached (per represented taxpayer) and refreshed 60 seconds before expiry; concurrent calls share one in-flight login; logins are rate-limited to the official 12/min per client ID.

updateOnBehalfOf(onBehalfOf) ​

Switches the represented taxpayer (intermediary access) and logs in for them. Accepts a TIN ('C1234567890') or TIN:ROB ('C1234567890:201901234567'). Tokens are cached per represented taxpayer, so switching back reuses a still valid token.

typescript
await client.updateOnBehalfOf('C9876543210:201901234567')

getTaxpayerIdentity() ​

Returns the taxpayer the client's token acts for, { tin, name?, isIntermediary }, read from LHDN's TaxpayerTIN claim. It reuses the cached token.

typescript
const { tin } = await client.getTaxpayerIdentity()

getTaxpayerIdentity({ clientId, clientSecret, environment }) ​

The standalone version, which needs no certificate. It logs in once as a taxpayer system and returns whose credentials they are. The token is not cached. See Proving TIN ownership.

decodeTaxpayerIdentity(token) does the same for a token you already hold. It throws when the token carries no TaxpayerTIN.

buildSignedDocuments(documents) ​

Signs and encodes documents locally without submitting — returns SignedDocumentPayload[] with the exact wire bytes (document, base64), the submission hash (documentHash, SHA-256 hex) and a parsed preview (signedDocument). Store the payload and pass it to submitDocument later for byte-identical submission. See Signing & Submission.