Konek QR

API error codes

Every Konek QR API error code, what it means and what to do about it, including when it is safe to retry.

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

JSON
{
  "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.
  • title and detail are for people. detail is in Indonesian unless you send Accept-Language: en.
  • type opens that code's entry on this page.
  • A 422 validation_failed also carries an errors list: one row per field, each with its own field, code and message.

When it is safe to retry

  • 429 rate_limited: wait for the number of seconds in the Retry-After header, then retry.
  • 500 internal_error or a timeout: retry with the same Idempotency-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:

FieldcodeMeaning
amountamount_out_of_rangeThe amount must be Rp1,000–Rp9,999,500, or Rp1,500–Rp10,000,000 when the unique code is subtracted.
expiresInMinutesexpiry_out_of_rangeThe expiry must be 5–1,440 minutes.
descriptiondescription_invalidAt most 200 characters.
referenceIdreference_invalidMust be 1–100 characters.
returnUrlreturn_url_invalidMust be a full https address.
metadatametadata_invalidMust be a JSON object of at most 4 KB.
qrisIdid_invalidNot a valid id.
aftercursor_invalidThe cursor is unknown, from the other mode, or older than 30 days. Start again without after.
typestypes_invalidIt names an unknown event type.
waitwait_invalidMust 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].