All APIs
PPh 21 Tax Calculator
DJP · Finance · 1 endpoint
The employee income tax an employer withholds — the monthly TER rate straight off the PMK 168/2023 table, alongside the true annual computation it prepays.
Base URL
https://api.diraz.ae
1 requestsNo cache1 credit / request
Endpoint
GET/v1/tax/pph21
Snippet
Request — cURL
v1
curl https://api.diraz.ae/v1/tax/pph21 \
-H "Authorization: Bearer drz_live_…"Query parameters
- monthly_grossnumber · required
- Monthly gross pay, before any deduction.
- ptkp_statusstring · required
- `TK/0`-`TK/3` not married, `K/0`-`K/3` married; the number is dependants.
- months_workedinteger · optional
- Months worked this tax year, for the annual pro-rating.Default: 12
Example response
200 OK
v1
{
"data": {
"monthly": { "ter_category": "A", "ter_rate": 0.08, "withholding_idr": 1400000 },
"annual": {
"months_worked": 8,
"biaya_jabatan_idr": 4000000,
"net_income_idr": 136000000,
"annualised_income_idr": 204000000,
"ptkp_idr": 54000000,
"taxable_income_idr": 150000000,
"brackets": [
{ "rate": 0.05, "taxed_idr": 60000000, "tax_idr": 3000000 },
{ "rate": 0.15, "taxed_idr": 90000000, "tax_idr": 13500000 }
],
"tax_full_year_idr": 16500000,
"tax_prorated_idr": 11000000
}
},
"meta": {
"request_id": "req_7Q2fK4mZ"
}
}- monthly.ter_category / ter_rate
- `A`, `B`, or `C` per PTKP status, and the effective rate the table gives that gross.
- monthly.withholding_idr
- What the employer withholds this month under TER.
- annual.biaya_jabatan_idr / ptkp_idr / taxable_income_idr
- The annual path: 5% occupational deduction, PTKP, and taxable income after annualising.
- annual.brackets[]
- Pasal 17 progressive brackets with the amount taxed in each.
- annual.tax_prorated_idr
- The year's true liability for the months worked — what the TER monthly amounts reconcile to.
Errors
401 Unauthorized
v1
{
"error": {
"code": "UNAUTHORIZED",
"message": "The API key is invalid, expired, or revoked."
},
"meta": {
"request_id": "req_7Q2fK4mZ"
}
}Every failure carries a stable machine-readable code before the human message, and the same meta.request_id the successful responses carry. Quote it and we can find your exact request.
Errors are free
Nothing on this page is billed. You are charged for a 2xx and nothing else — a rejected key, a bad parameter, a rate limit, or an outage on our side all cost you zero. Retry without watching the meter.
- UNAUTHORIZEDHTTP 401
- Missing, malformed, expired, or revoked API key.
- FORBIDDENHTTP 403
- The key is valid but lacks the scope this product needs.
- VALIDATION_ERRORHTTP 422
- A query parameter is the wrong type or out of range.
- RATE_LIMITEDHTTP 429
- Rate limit exhausted. `Retry-After` says how long to wait.
- SERVICE_UNAVAILABLEHTTP 503
- No data recent enough to serve. Carries `Retry-After`, and is never billed.
Total requests1
CacheNone
- Status
- Operational
- Category
- Finance
- Scope
- market:read
- Rate limit
- 300 requests / 60s per key
- Pricing
- 1 credit / request
- PPh 21 Tax Calculator
1/1 passing