API Version: 1.0
Base URL: https://online.2kadam.com
Service: UTI PSA Portal (Physical & Digital e-KYC PAN Card)
The 2kadam UTI PAN Reseller API enables B2B partners and developers to integrate UTI PSA portal access directly into their own websites. Using this API, you can generate a Single Sign-On (SSO) URL. When your retailer clicks this URL, they are automatically logged into the UTI portal where they can apply for both Physical and Digital PAN cards. Wallet deductions and real-time status updates are handled automatically.
All API requests must comply with the following security standards:
This endpoint deducts the required PAN card fee from your 2kadam wallet and returns a one-time-use UTI portal login URL.
| Header Name | Type | Required | Description |
|---|---|---|---|
Authorization |
String | Yes | Your API Token (e.g., Bearer YOUR_API_TOKEN) |
Content-Type |
String | Yes | application/json |
| Parameter | Type | Required | Description |
|---|---|---|---|
agent_id |
String | Yes | The ID or Mobile Number of your retailer/agent accessing the portal. |
pin |
String | Yes | Your secure 4-digit Wallet Transaction PIN. |
{
"agent_id": "9876543210",
"pin": "1234"
}
Redirect your retailer/agent to the url received in this response.
{
"status": "SUCCESS",
"message": "UTI URL Generated Successfully",
"txnid": "UTI1692345678",
"url": "https://www.myutiitsl.com/panonlineservices/loginCheckin?userHandle=..."
}
| HTTP Status | Message | Reason |
|---|---|---|
| 401 | Invalid API Token or User Account Inactive. | Missing/Wrong token or account disabled. |
| 403 | Security Alert: Invalid Wallet PIN. Access Blocked. | The pin provided is incorrect. |
| 403 | Security Alert: IP is not whitelisted. | Request sent from an unregistered server IP. |
| 500 | Insufficient Wallet Balance. | Not enough funds in your main wallet to process the request. |
To receive real-time status updates (Success, Failed, Refunded) on your own portal, you must configure a Callback URL.
POST API endpoint on your server (e.g., https://your-domain.com/api/callback).When a PAN application is successfully processed or rejected/refunded by UTI, our server will push the following JSON payload to your Callback URL via POST:
{
"txnid": "PANC1692345678",
"status": "SUCCESS",
"amount": 107.00,
"message": "PAN Application Submitted Successfully",
"service": "UTI_PAN",
"timestamp": "2026-08-19 14:30:00"
}
status Value |
Developer Action Required |
|---|---|
| SUCCESS | The application was successfully submitted. Mark the transaction as Success in your database. |
| REFUNDED | The application was failed, rejected, or aborted. You MUST refund the exact amount back to your agent's wallet. |
HTTP 200 OK response within 5 seconds.
You can use the following PHP code snippets to easily integrate the API into your platform.
<?php
$apiUrl = "https://online.2kadam.com/api/v1/uti/request";
$apiToken = "YOUR_API_TOKEN_HERE";
$walletPin = "1234";
$agentId = "9876543210";
$postData = json_encode([
"agent_id" => $agentId,
"pin" => $walletPin
]);
$ch = curl_init($apiUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/json",
"Authorization: " . $apiToken
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$result = json_decode($response, true);
if ($httpCode == 200 && isset($result['status']) && $result['status'] == 'SUCCESS') {
$redirectUrl = $result['url'];
// Save $result['txnid'] to your database here
// Redirect user to UTI Portal
header("Location: " . $redirectUrl);
exit;
} else {
echo "API Error: " . (isset($result['message']) ? $result['message'] : "Unknown Error");
}
?>
Save this code as callback.php on your server and enter its URL in your 2kadam API Settings.
<?php
// 1. Receive incoming JSON payload
$jsonPayload = file_get_contents('php://input');
$data = json_decode($jsonPayload, true);
if (!empty($data) && isset($data['txnid'])) {
$txnId = $data['txnid'];
$status = $data['status'];
$amount = $data['amount'];
if ($status === 'SUCCESS') {
// TODO: Update database status to SUCCESS for $txnId
} elseif ($status === 'REFUNDED') {
// TODO: Update database status to REFUNDED for $txnId
// TODO: Add $amount back to your retailer's wallet
}
// Must return 200 OK within 5 seconds
http_response_code(200);
echo json_encode(["status" => "Callback Received"]);
} else {
http_response_code(400);
echo json_encode(["status" => "Failed", "message" => "Invalid Payload"]);
}
?>