Get started

This page takes you from sign-up to a first request that returns a result, in a few minutes of reading. Every route is described in the API reference

1. Create an API key

  1. Sign up and confirm your mobile number. The account gets 50 trial credits
  2. Open the API keys page, create a key and choose the slip:lookup scope (add slip:read to read history as well; neither scope includes the other)
  3. Copy the key and store it right away. It starts with csk_ and is shown only once: we do not keep the key itself, so it cannot be viewed again. If you lose it, create a new key and revoke the old one.

Keep the key on your server. Never put it in web page code or a mobile app.

2. Send your first request

Read the text in the QR on the slip with any QR reader and send it.

curl https://api.checkslip.com/api/slips/lookup \
  -H "Authorization: Bearer $CHECKSLIP_API_KEY" \
  -H "Idempotency-Key: order-1042-slip-1" \
  -H "Content-Type: application/json" \
  -d '{"qr":"00330006000001010306902126302105340875102TH9104F86F"}'

The qr value above only shows the format; use the text of the QR on the slip your customer sent you. Without a QR at hand, send the slip image instead as multipart/form-data, field image.

3. Read the answer

Decide from outcome in the body, not from the HTTP status.

Example response
{
  "request_id": "0192d4e0-7c1a-7b3e-9f00-1a2b3c4d5e6f",
  "outcome": "FOUND",
  "checked_at": "2026-10-29T10:41:02+07:00",
  "slip": {
    "trans_ref": "630210534087",
    "transferred_at": "2026-10-29T10:33:30+07:00",
    "amount": {
      "satang": 5000,
      "currency": "THB"
    },
    "sender": {
      "bank": {
        "code": "KKP",
        "bot_code": "069",
        "name_th": "ธนาคารเกียรตินาคินภัทร",
        "name_en": "Kiatnakin Phatra Bank"
      },
      "name_th": "นาย สมชาย ใ",
      "name_en": "MR. SOMCHAI J",
      "account": "0439"
    },
    "receiver": {
      "kind": "BANK_ACCOUNT",
      "bank": {
        "code": "GSB",
        "bot_code": "030",
        "name_th": "ธนาคารออมสิน",
        "name_en": "Government Savings Bank"
      },
      "name_th": "นางสาว สมหญิง ร",
      "name_en": "MISS SOMYING R",
      "account": "9681"
    }
  }
}
outcomeWhat it means for your shopCredit
FOUNDFound
The bank holds this transfer. Compare the amount, receiver and time with your order, then decide yourself.
1 credit taken
NOT_FOUNDNot found
The bank holds no transfer for this trans_ref at the time we asked. It only says there is no transfer, not why. You decide, for example by asking the customer for more proof.
No credit taken
DUPLICATEDuplicate
Your account already got a found result for this slip; duplicate_of.request_id points at the first one. If that was another order, the slip was already used with your shop. If it was the same order, see step 5.
No credit taken
PENDINGWaiting for bank
Transfer lookup outcomes
No credit taken
UNAVAILABLEUnavailable
Error codes
No credit taken
INVALID_QRInvalid QR
Error codes
No credit taken
INVALID_FILEUnreadable file
Error codes
No credit taken
QR_TAMPEREDQR mismatch
Error codes
No credit taken
TOO_OLDToo old
Error codes
No credit taken

A lookup is still named check in the API, in the error code CHECK_NOT_FOUND. The name is kept for compatibility and means the same lookup.

4. When a credit is taken

One credit is taken only when the outcome is FOUND. Other outcomes take none, DUPLICATE and NOT_FOUND included.

PENDING (waiting for the bank) takes nothing yet: we ask the bank again for you, take one credit if the transfer turns up later, and send the result by webhook.

Your credit balance and every credit taken are in the app

5. Send Idempotency-Key with every request

If the connection drops or times out before you get an answer, send the same request again with the same Idempotency-Key within 24 hours. You get the first answer back (same request_id, same result): no new lookup with the bank and no extra credit.

Sent again without the first key, it is a new request. If the first one was FOUND, the new one is DUPLICATE and takes no credit, but your code may read it as a reused slip and turn away a customer who really paid.

The same slip sent in several requests at the same moment without a key is still charged once: one request gets FOUND and the rest get DUPLICATE. While the first one runs, every request holds a credit for a moment, so with few credits left an extra request may get 402 instead of DUPLICATE (neither is charged).

Use a key tied to the order and that slip, such as order-1042-slip-1. The same key with a different body gets the error idempotency-key-reused, and while the first request is still running you get idempotency-in-flight: wait and send again with the same key.

6. When something goes wrong

Every error is application/problem+json (RFC 9457). Read type to know what happened; each type has a page with the cause and the fix

Contact the team with the instance value from the response (the same number as the X-Request-Id header).

Next