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.

Base URL https://api.dharun.devNo key needed for most600 units a minute, 3000 with a free keyThis page as Markdown

Known 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.

ParameterDescription
handlepath, requiredThe 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.

ParameterDescription
textqueryThe 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.