API documentation
Sign in to get a keyQuick start
- Ask your administrator for an account, then create a key under API keys.
- Send the key in the
X-API-Keyheader. - Pass a UPI ID or QR text in the
upiparameter and readresult.
Endpoint
GET POST https://upi-qr.hosting-access.net/api/v1/check
| Header | X-API-Key: <key> or Authorization: Bearer <key> |
|---|---|
| Parameter | upi (required): query string, form field or JSON body |
| Accepted input | A UPI ID such as name@bank, or the full text inside a UPI QR such as upi://pay?pa=…&pn=…&mc=…. To check a QR image, decode it first (any QR scanner library) and send the text. |
| Health check | GET https://upi-qr.hosting-access.net/health returns {"status":"ok"} |
Response
{
"success": true,
"input_type": "qr",
"upi_id": "shop@ybl",
"name": "Shop",
"merchant_code": "5411",
"is_personal": false,
"is_merchant": true,
"result": false,
"confidence": "high",
"usage": { "used_today": 12, "daily_limit": 1000 }
}
| Field | Type | Description |
|---|---|---|
success | boolean | true when the request was processed. |
input_type | string | qr for a upi:// payload, upi_id for a bare ID. |
upi_id | string | The payee UPI ID that was checked. |
name | string|null | Payee name (pn) from the QR, if present. |
merchant_code | string|null | Merchant category code (mc) from the QR, if present. |
result | boolean | true = personal, false = merchant. |
is_personal / is_merchant | boolean | Explicit flags, the inverse of each other. |
confidence | string | high, medium or low (see below). |
usage | object | used_today and daily_limit (null = unlimited) for your key. |
Confidence levels
- high Strong evidence for the answer.
- medium Reasonable evidence; fine for most uses.
- low Little evidence either way. Treat as "unknown, probably personal".
Code examples
curl -X POST https://upi-qr.hosting-access.net/api/v1/check \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"upi": "upi://pay?pa=shop@ybl&pn=Shop&mc=5411"}'curl "https://upi-qr.hosting-access.net/api/v1/check?upi=someone@oksbi" \ -H "X-API-Key: YOUR_API_KEY"
const res = await fetch('https://upi-qr.hosting-access.net/api/v1/check', {
method: 'POST',
headers: { 'X-API-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
body: JSON.stringify({ upi: 'someone@oksbi' })
});
const data = await res.json();
if (data.result === true) { /* personal */ } else { /* merchant */ }$ch = curl_init('https://upi-qr.hosting-access.net/api/v1/check?upi=' . urlencode('someone@oksbi'));
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: YOUR_API_KEY'],
]);
$data = json_decode(curl_exec($ch), true);
var_dump($data['result']); // true = personal, false = merchantimport requests
r = requests.post(
'https://upi-qr.hosting-access.net/api/v1/check',
headers={'X-API-Key': 'YOUR_API_KEY'},
json={'upi': 'someone@oksbi'},
timeout=10,
)
data = r.json()
print('personal' if data.get('result') else 'merchant')Errors
{
"success": false,
"error": "invalid_input",
"message": "Not a valid UPI ID format (expected name@handle)."
}
| HTTP | error | Meaning |
|---|---|---|
| 401 | missing_api_key | No key was sent. |
| 401 | invalid_api_key | The key does not exist. |
| 403 | key_disabled | The key or its owner is disabled. |
| 403 | domain_not_allowed | The request's domain is not on the key's whitelist. |
| 422 | missing_input / invalid_input | The upi value is missing or malformed. |
| 429 | daily_limit_reached | The key's daily limit is used up (resets at 00:00 UTC). |
| 500 | server_error | Something went wrong on our side. Retry shortly. |
Try it live
No signup neededDomain whitelisting
If a key has whitelisted domains, requests must carry an Origin or Referer from one of them. Use *.example.com to allow subdomains.
Browsers always send these headers and cannot fake them, so whitelisting protects keys embedded in web pages. Server-side callers can set any header, so keep keys without a whitelist on your backend.
FAQ
Can it be 100% accurate?
No public UPI lookup exists for account type. The result is a best estimate built from several signals in the QR or ID, so check confidence before acting on it.
Is the demo rate limited?
Yes, 30 checks per minute per visitor. Use an API key for real traffic.
Do you store what I check?
Authenticated API requests are logged for your key's history and deleted automatically after 90 days. Demo checks are not stored.