Docs / Money and business
UPI handles and payment QR codes API
Which app and bank is behind @okaxis, and what a UPI or Bharat QR code says.
The handle after the @ in a UPI ID names the app and the partner bank that issued it. The QR reader takes the text inside a payment QR code (a upi://pay link or an EMVCo string, which Bharat QR uses), splits it into payee, amount, merchant category, city and reference, and checks its checksum.
https://api.dharun.devNo key needed for most600 units a minute, 3000 with a free keyThis page as MarkdownKnown UPI handles
GET/v1/upi-handles
curl
curl "https://api.dharun.dev/v1/upi-handles?utm_medium=docs"JavaScript
const response = await fetch("https://api.dharun.dev/v1/upi-handles?utm_medium=docs");
const body = await response.json();
if (!response.ok) throw new Error(body.error.message);
console.log(body.data);Python
import requests
response = requests.get("https://api.dharun.dev/v1/upi-handles?utm_medium=docs", timeout=10)
body = response.json()
if not response.ok:
raise RuntimeError(body["error"]["message"])
print(body["data"])Try it here
Change the values and send the request from your browser. Needs JavaScript.
Response, with lists and long text shortened
{
"data": [
{
"handle": "airtel",
"app": "Airtel Thanks",
"bank": "Airtel Payments Bank",
"kind": "bank"
},
{
"handle": "apl",
"app": "Amazon Pay",
"bank": "Axis Bank",
"kind": "app"
},
{
"handle": "aubank",
"app": "AU 0101",
"bank": "AU Small Finance Bank",
"kind": "bank"
}
],
"meta": {
"total": 54,
"note": "A handle says which app and partner bank issued a UPI ID; the money can sit in any bank the person linked. It says nothing about who the person is. Typed from N…"
}
}Look up a UPI handle
GET/v1/upi-handles/{handle}
Give the handle (okhdfcbank) or a whole UPI ID; only the part after the @ is read.
| Parameter | Description |
|---|---|
handlepath, required | The handle, with or without the name and @ before it. |
curl
curl "https://api.dharun.dev/v1/upi-handles/okhdfcbank?utm_medium=docs"JavaScript
const response = await fetch("https://api.dharun.dev/v1/upi-handles/okhdfcbank?utm_medium=docs");
const body = await response.json();
if (!response.ok) throw new Error(body.error.message);
console.log(body.data);Python
import requests
response = requests.get("https://api.dharun.dev/v1/upi-handles/okhdfcbank?utm_medium=docs", timeout=10)
body = response.json()
if not response.ok:
raise RuntimeError(body["error"]["message"])
print(body["data"])Try it here
Change the values and send the request from your browser. Needs JavaScript.
Response, with lists and long text shortened
{
"data": {
"handle": "okhdfcbank",
"app": "Google Pay",
"bank": "HDFC Bank",
"kind": "app"
},
"meta": {
"note": "A handle says which app and partner bank issued a UPI ID; the money can sit in any bank the person linked. It says nothing about who the person is. Typed from N…"
}
}Read a UPI or Bharat QR code's text
GET/v1/qr/parsePOST
Splits the text of a payment QR code into its fields and checks the EMVCo checksum. To get the text from a picture, POST the picture to /v1/barcode/read first.
Also takes POST: The QR code's text, as text/plain or JSON {"text": "..."}. Send it as text/plain, or as JSON {"text": "..."} with the other options beside it, up to 256 KB.
What you send here is never written to the log, and the answer is not cached.
| Parameter | Description |
|---|---|
textquery | The QR code's text. |
curl
curl "https://api.dharun.dev/v1/qr/parse?text=upi%3A%2F%2Fpay%3Fpa%3Dshop%40okaxis%26pn%3DSri%2520Murugan%2520Stores%26am%3D250%26cu%3DINR%26mc%3D5411&utm_medium=docs"JavaScript
const response = await fetch("https://api.dharun.dev/v1/qr/parse?text=upi%3A%2F%2Fpay%3Fpa%3Dshop%40okaxis%26pn%3DSri%2520Murugan%2520Stores%26am%3D250%26cu%3DINR%26mc%3D5411&utm_medium=docs");
const body = await response.json();
if (!response.ok) throw new Error(body.error.message);
console.log(body.data);Python
import requests
response = requests.get("https://api.dharun.dev/v1/qr/parse?text=upi%3A%2F%2Fpay%3Fpa%3Dshop%40okaxis%26pn%3DSri%2520Murugan%2520Stores%26am%3D250%26cu%3DINR%26mc%3D5411&utm_medium=docs", timeout=10)
body = response.json()
if not response.ok:
raise RuntimeError(body["error"]["message"])
print(body["data"])Try it here
Change the values and send the request from your browser. Needs JavaScript.
Response
{
"data": {
"kind": "upi",
"payee": "shop@okaxis",
"payeeName": "Sri Murugan Stores",
"amount": "250",
"currency": "INR",
"merchantCategoryCode": "5411",
"merchantCategory": "grocery stores and supermarkets",
"fields": {
"_handle": "Google Pay (Axis Bank)",
"am": "250",
"cu": "INR",
"mc": "5411",
"pa": "shop@okaxis",
"pn": "Sri Murugan Stores"
},
"warnings": []
},
"meta": {
"note": "Reads what the code says; it cannot tell whether the payee is genuine. To read a QR code from a picture, use POST /v1/barcode/read."
}
}Using an AI assistant? Connect the MCP server and it can call this API by itself. Want every endpoint on one bench? Open the playground.