When a request to the API fails, Konek QR answers with an HTTP 4xx or 5xx status and an application/problem+json body (RFC 9457). This page lists every code, what it means and what to do about it.
What an error looks like
{
"type": "https://konekqr.web.id/errors/invalid_api_key",
"title": "Invalid API key",
"status": 401,
"code": "invalid_api_key",
"detail": "The API key is missing, wrong or revoked. Send the header Authorization: Bearer kq_live_… or kq_test_…."
}- Have your code check
code. Its values do not change between versions. titleanddetailare for people.detailis in Indonesian unless you sendAccept-Language: en.typeopens that code's entry on this page.- A
422 validation_failedalso carries anerrorslist: one row per field, each with its ownfield,codeandmessage.
When it is safe to retry
429 rate_limited: wait for the number of seconds in theRetry-Afterheader, then retry.500 internal_erroror a timeout: retry with the sameIdempotency-Key. If the invoice was created after all, you get that invoice back, not a second one.409 idempotency_in_progress: the first request is still running. Retry in a few seconds with the same key.- Any other 4xx fails again if you resend it unchanged. Fix the request, or the state of the account, first.
400 The request cannot be read
invalid_json
The body is not valid JSON, or it has a field the API does not know. Unknown fields are refused on purpose, so a typo like referenceID is never silently ignored.
Check the JSON and every field name against the API reference.
idempotency_key_invalid
The Idempotency-Key header is missing or longer than 100 characters. POST /v1/payments requires it.
Send one key per order, such as order-1001, and reuse that key when you retry that request.
401 API key refused
invalid_api_key
The API key is missing, wrong or revoked, or the account is suspended. The answer also carries a WWW-Authenticate: Bearer header.
Send Authorization: Bearer kq_live_… or kq_test_…. If the key is right and still refused, check in the dashboard that it is still active, or contact [email protected].
403 Not allowed
insufficient_scope
This key lacks the scope this request needs. The scopes are payments:read, payments:write and events:read.
Create a key with the scopes you need in the dashboard, then revoke the old one.
browser_not_allowed
The request came from a browser (it carried an Origin header). API keys are for servers only, so these requests are always refused, to keep keys from leaking through web pages.
Call the API from your server, then hand the result, such as payUrl or qrString, to the buyer's page.
cross_origin_rejected
A request that changes data came from a browser on another site. This is protection against CSRF.
As with browser_not_allowed: call the API from a server, not from a browser.
test_mode_only
POST /v1/payments/{id}/simulate was called with a live key, or for a live invoice. Simulation exists in test mode only; a live invoice is paid by a real payment only.
Use a kq_test_… key and a test invoice to try the paid flow.
404 Not found
not_found
There is no invoice with that id in your key's account and mode, or the qrisId you sent is not a QRIS of your account. A test key never sees live invoices, and a live key never sees test ones.
Check the id, and use a key of the same mode the invoice was created in.
409 Conflicts with the account's state
qris_not_ready
No QRIS can be used yet. A live invoice needs a verified QRIS that is past its 24-hour hold. A test invoice can use any QRIS of the account, verified or not.
Add or verify a QRIS in the dashboard. On an account that has had a verified QRIS before, a new QRIS can be used 24 hours after it is verified.
balance_negative
The account's fee balance is below zero, so new live invoices are held back. Test mode keeps working, and invoices already created are not affected.
Top up in the dashboard. Live invoices can be created again as soon as the balance is no longer negative. The Balance Policy has the rules.
nmid_mismatch
The NMID of the QRIS that would be used is not the expectedNmid you sent. No invoice was created, so a buyer never sees a QR for a QRIS you did not expect.
Check the QRIS in the dashboard. If it was replaced on purpose, update expectedNmid in your system.
detection_offline
You sent requireDetection: true, and no Listener phone was active in the last 7 minutes. No invoice was created, because its payment would not be confirmed automatically.
Turn on the cashier phone and make sure Listener is running. Or create the invoice without requireDetection and confirm the payment by hand.
too_many_pending
There are already 200 invoices awaiting payment in this mode.
Cancel invoices that will not be paid, or use a shorter expiry through expiresInMinutes.
unique_codes_exhausted
Every unique total for this amount is taken by other invoices in your account for the same provider. A total is locked from the moment its invoice is created until 24 hours after it expires.
Try again later, or change the amount slightly.
reference_taken
This referenceId is already used by another invoice of the same mode.
Use a referenceId that is unique per order. To retry a request without creating a second invoice, use Idempotency-Key, not referenceId.
payment_not_pending
This invoice is already paid or cancelled, so it cannot be cancelled or simulated again.
Read its current status with GET /v1/payments/{id}.
qris_seal_invalid
The stored QRIS content no longer matches its seal, so Konek QR has stopped using it. The seal is there so your QRIS cannot be swapped quietly.
Do not create invoices from this QRIS. Contact [email protected].
idempotency_conflict
This Idempotency-Key was used for a request with a different body in the last 24 hours.
Use a new key for a new order. When you retry, send exactly the same body.
idempotency_in_progress
A request with this Idempotency-Key is still being processed.
Retry in a few seconds with the same key and body.
413 Body too large
payload_too_large
The request body is over 64 KiB.
Send less. metadata on its own is limited to 4 KB.
422 Invalid fields
validation_failed
One or more fields are invalid. The errors list names each field with its own code:
| Field | code | Meaning |
|---|---|---|
amount | amount_out_of_range | The amount must be Rp1,000–Rp9,999,500, or Rp1,500–Rp10,000,000 when the unique code is subtracted. |
expiresInMinutes | expiry_out_of_range | The expiry must be 5–1,440 minutes. |
description | description_invalid | At most 200 characters. |
referenceId | reference_invalid | Must be 1–100 characters. |
returnUrl | return_url_invalid | Must be a full https address. |
metadata | metadata_invalid | Must be a JSON object of at most 4 KB. |
qrisId | id_invalid | Not a valid id. |
after | cursor_invalid | The cursor is unknown, from the other mode, or older than 30 days. Start again without after. |
types | types_invalid | It names an unknown event type. |
wait | wait_invalid | Must be 0–30 seconds. |
Fix the value as the table says, or show message to your user.
429 Too many requests
rate_limited
The limits are 120 requests a minute per key, and 120 new invoices a minute per account in each mode.
Wait for Retry-After, then retry. To wait for a payment, use webhooks or GET /v1/events?wait=30 instead of calling GET /v1/payments/{id} over and over.
500 Something failed on our side
internal_error
Something failed on the Konek QR servers. Your request was not the problem.
Retry with growing pauses. When creating an invoice, reuse the same Idempotency-Key so you never get a duplicate. If it keeps happening, check the service status or tell [email protected].
Something unclear or wrong? Write to [email protected].