<!-- Place at .github/copilot-instructions.md in your repo -->

# Integrating Eko Platform Services (EPS) APIs

EPS is an API platform for payments, banking-correspondent services (AePS, DMT, BBPS) and identity verification (PAN, Aadhaar, bank, GST, etc.) in India. This pack tells an AI coding agent how to call EPS APIs correctly.

## Environments

| Environment | Base URL | Notes |
| --- | --- | --- |
| UAT / Sandbox | https://staging.eko.in/ekoapi/v3 | Self-serve credentials available immediately on signup. |
| Production | https://api.eko.in/ekoicici/v3 | Credentials issued after organizational KYC. |

## Authentication & request signing

> **Backend-only. The access_key is a server-side secret used to compute the per-request secret-key (HMAC-SHA256). Never expose access_key or compute secret-key in a browser/frontend.**

Every request sends these headers:

| Header | Description |
| --- | --- |
| developer_key | Static API key issued to your account after KYC. |
| secret-key | Dynamic per-request signature: base64(HMAC-SHA256(timestamp, base64(access_key))). |
| secret-key-timestamp | Current time in milliseconds since UNIX epoch, used to compute secret-key. Must match server time. |
| content-type | application/json |

Compute `secret-key` (server-side) as:

1. Base64-encode the access_key.
2. Generate the current timestamp in milliseconds (as a string).
3. Compute HMAC-SHA256 of the timestamp using the base64-encoded key.
4. Base64-encode the resulting signature — this is the secret-key.

Full auth reference: https://eps.eko.in/docs/how-auth-works

## Error model

Responses carry `status` (0 = success) and a granular `response_status_id`. Common codes (e.g. `463` = user not found, `347` = insufficient balance). Full table: https://eps.eko.in/docs/error-codes.

## API endpoints

| API | Method | Path | Summary |
| --- | --- | --- | --- |
| Get Sender Profile | GET | `/customer/payment/dmt-fino/sender/{customer_id}` | Fetch the DMT-Fino profile of a registered sender by mobile number. |
| Onboard Sender | POST | `/customer/payment/dmt-fino/sender/{customer_id}` | Register a new customer as a DMT-Fino sender using basic KYC details. |
| Sender eKYC (Biometric) | PUT | `/customer/payment/dmt-fino/sender/{customer_id}/otp` | Initiate biometric Aadhaar eKYC to verify and upgrade a DMT sender's account. |
| Validate eKYC OTP | PUT | `/customer/payment/dmt-fino/sender/{customer_id}/otp/verify` | Confirm sender eKYC by verifying the OTP sent to the Aadhaar-linked mobile. |
| Get Recipients | GET | `/customer/payment/dmt-fino/sender/{customer_id}/recipients` | Retrieve the list of saved beneficiaries for a DMT sender. |
| Add Recipient | POST | `/customer/payment/dmt-fino/sender/{customer_id}/recipient1` | Register a new beneficiary under a sender's DMT-Fino account. |
| Send Transaction OTP | POST | `/customer/payment/dmt-fino/otp` | Request an OTP to the sender's mobile number to authorise an upcoming money transfer. |
| Initiate Transfer | POST | `/customer/payment/dmt-fino` | Execute a DMT-Fino money transfer after OTP verification. |
| AePS Cash Withdrawal | POST | `/customer/collection/aeps-fingpay/cash-withdrawal/{customer_id}` | Withdraw cash from any Aadhaar-linked bank account using biometric fingerprint authentication — no card or PIN required. |
| AePS Balance Enquiry | POST | `/customer/collection/aeps-fingpay/balance-enquiry/{customer_id}` | Check a customer's bank account balance using Aadhaar number and biometric fingerprint — no card or PIN required. |
| Activate AePS Fingpay for Agent | PUT | `/admin/network/agent/{user_code}/aeps-fingpay/activate` | Onboard an agent for AePS Fingpay service by submitting their biometric device details and KYC documents. |
| AePS Fingpay — Daily Authentication (2FA) | POST | `/customer/aeps/fingpay/kyc/daily` | Perform the mandatory daily biometric authentication that authorises an agent to carry out AePS transactions for the current calendar day. |
| AePS Mini Statement | POST | `/customer/collection/aeps-fingpay/mini-statement/{customer_id}` | Retrieve the last few transactions from an Aadhaar-linked bank account via biometric authentication. |
| AePS Aadhaar Pay | POST | `/customer/collection/aeps-fingpay` | Accept merchant payments debited directly from a customer's Aadhaar-linked bank account via biometric authentication. |
| AePS Fingpay — Send OTP (eKYC) | POST | `/customer/aeps/fingpay/kyc/otp` | Initiate AePS Fingpay eKYC by sending an OTP to the agent's registered Aadhaar-linked mobile number. |
| AePS Fingpay — Biometric eKYC | POST | `/customer/aeps/fingpay/kyc/biometric` | Complete one-time AePS Fingpay eKYC by submitting the agent's Aadhaar and live biometric fingerprint capture. |
| Get BBPS Categories | GET | `/customer/payment/bbps/categories` | Retrieve the list of supported BBPS biller categories (electricity, gas, DTH, etc.). |
| Get BBPS Locations | GET | `/customer/payment/bbps/locations` | Retrieve the list of supported state/location IDs for filtering BBPS operators. |
| Get BBPS Operators | GET | `/customer/payment/bbps/operators` | List all active BBPS billers, optionally filtered by category and/or state. |
| Get Operator Parameters | GET | `/customer/payment/bbps/operator/{operator_id}/parameters` | Fetch the custom input fields required by a specific biller before payment. |
| Fetch BBPS Bill | GET | `/customer/payment/bbps/bill` | Retrieve outstanding bill details from a biller before processing payment. |
| Pay BBPS Bill | POST | `/customer/payment/bbps` | Process a bill payment or recharge for any BBPS-connected biller. |
| Activate BBPS Service | PUT | `/user/service/activate` | Onboard an agent/retailer for BBPS bill payment services using service code 53. |
| PAN Lite | POST | `/tools/kyc/pan-lite` | Instant PAN validation with name and DOB match scores plus Aadhaar seeding status. |
| PAN Advanced | POST | `/tools/kyc/pan-advanced` | Rich PAN verification returning registered name, PAN type, gender, DOB, masked Aadhaar, address, email, and mobile. |
| Bulk PAN Verification | POST | `/tools/kyc/pan/bulk` | Async batch PAN verification — submit multiple PANs in one call and poll for results via the Bulk PAN Status API. |
| Validate Aadhaar & Generate OTP | POST | `/customer/payment/dmt-levin/sender/{customer_id}/aadhaar/otp` | Validate a sender's Aadhaar number and trigger an OTP to the linked mobile for DMT Levin onboarding. |
| Validate Sender Aadhaar OTP | POST | `/customer/payment/dmt-levin/sender/{customer_id}/aadhaar/otp/verify` | Verify the Aadhaar OTP for a DMT Levin sender to complete identity validation. |
| Validate Aadhaar | POST | `/customer/payment/ppi-levin/sender/{customer_id}/aadhaar/otp` | Submit sender's Aadhaar number for OTP-based validation in the PPI Levin wallet onboarding flow. |
| Validate Aadhaar OTP | POST | `/customer/payment/ppi-levin/sender/{customer_id}/aadhaar/otp/verify` | Verify the Aadhaar OTP to complete identity validation in the PPI Levin wallet onboarding flow. |
| Get Sender Information | GET | `/customer/payment/ppi-levin/sender/{customer_id}` | Fetch a PPI Levin sender's wallet profile and onboarding/OTP state by mobile number. |
| Onboard Sender | POST | `/customer/payment/ppi-levin/sender/{customer_id}` | Register a new customer as a PPI Levin wallet sender using basic KYC details. |
| Verify Sender OTP | POST | `/customer/payment/ppi-levin/sender/{customer_id}/otp/verify` | Verify the sender OTP to authenticate the PPI Levin wallet and return the sender's profile and balance. |
| Validate PAN | POST | `/customer/payment/ppi-levin/sender/{customer_id}/pan` | Validate the sender's PAN to complete PPI Levin KYC and return the updated wallet profile. |
| Get List of Recipients | GET | `/customer/payment/ppi-levin/sender/{customer_id}/recipients` | Retrieve the list of saved beneficiaries for a PPI Levin sender. |
| Add Recipient | POST | `/customer/payment/ppi-levin/sender/{customer_id}/recipient` | Register a new beneficiary under a PPI Levin sender's account. |
| Add Recipient Bank | POST | `/customer/payment/ppi-levin/sender/{customer_id}/bank/recipient` | Register a bank beneficiary for an existing PPI Levin recipient. |
| Send Transaction OTP | POST | `/customer/payment/ppi-levin/otp` | Request an OTP to the sender's mobile to authorise a PPI Levin transfer. |
| Initiate Transaction | POST | `/customer/payment/ppi-levin` | Execute a PPI Levin wallet transfer to a recipient after OTP verification. |
| Get Sender Information | GET | `/customer/payment/ppi-digikhata/sender/{customer_id}` | Fetch a DigiKhata wallet sender's profile and onboarding/OTP state by mobile number. |
| Onboard Sender | POST | `/customer/payment/ppi-digikhata/sender/{customer_id}` | Register a new customer as a PPI DigiKhata wallet sender using basic KYC details. |
| Generate Sender Verification OTP | POST | `/customer/payment/ppi-digikhata/sender/{customer_id}/otp` | Send a verification OTP to a DigiKhata sender's registered mobile number. |
| Verify Sender OTP | POST | `/customer/payment/ppi-digikhata/sender/{customer_id}/otp/verify` | Verify the sender OTP to authenticate the DigiKhata wallet and return the sender's profile and balance. |
| Get Aadhaar KYC Consent Languages | GET | `/customer/payment/ppi-digikhata/sender/{customer_id}/aadhaar/consent/languages` | List the languages available for the DigiKhata Aadhaar e-KYC consent. |
| Get Aadhaar KYC Consent Details | GET | `/customer/payment/ppi-digikhata/sender/{customer_id}/aadhaar/consent/details` | Fetch the DigiKhata Aadhaar e-KYC consent text and audio for a chosen language. |
| Generate Sender Aadhaar OTP | POST | `/customer/payment/ppi-digikhata/sender/{customer_id}/aadhaar/otp` | Validate a DigiKhata sender's Aadhaar number and trigger an OTP to the linked mobile. |
| Validate Sender Aadhaar OTP | POST | `/customer/payment/ppi-digikhata/sender/{customer_id}/aadhaar/otp/verify` | Verify the Aadhaar OTP to complete DigiKhata sender Aadhaar e-KYC. |
| Validate Sender PAN | POST | `/customer/payment/ppi-digikhata/sender/{customer_id}/pan` | Validate the sender's PAN to complete DigiKhata KYC and return the updated wallet profile. |
| Load Sender DigiKhata Wallet | POST | `/customer/payment/ppi-digikhata/sender/{customer_id}/wallet/loadwallet` | Load funds into a DigiKhata sender's prepaid wallet. |
| Get List of Recipients | GET | `/customer/payment/ppi-digikhata/sender/{customer_id}/recipients` | Retrieve the list of saved beneficiaries for a DigiKhata sender. |
| Add Recipient | POST | `/customer/payment/ppi-digikhata/sender/{customer_id}/recipient` | Register a new beneficiary under a DigiKhata sender's account. |
| Generate Add Recipient Bank OTP | POST | `/customer/payment/ppi-digikhata/sender/{customer_id}/recipient/bank/otp` | Generate an OTP to register a recipient's bank for a DigiKhata sender. |
| Validate OTP to Add Recipient | POST | `/customer/payment/ppi-digikhata/sender/{customer_id}/recipient/bank/otp/verify` | Verify the OTP to complete recipient bank registration for a DigiKhata sender. |
| Send Transaction OTP | POST | `/customer/payment/ppi-digikhata/otp` | Request an OTP to the sender's mobile to authorise a DigiKhata transfer. |
| Initiate Transaction | POST | `/customer/payment/ppi-digikhata` | Execute a DigiKhata wallet transfer to a recipient after OTP verification. |
| Onboard User | POST | `/user/network/eps-agent` | Register a new agent/retailer (merchant) on the EPS platform and receive their user_code. |
| Get User's Services | GET | `/user/account/services` | Check the activation status of every service for one of your agents. |
| Get All Services | GET | `/tools/catalog/service-codes` | List every service available on the platform with its service code and provider. |
| Get Settlement Account Balance | GET | `/user/account/balance` | Fetch the settlement-account (wallet) balance for a user. |
| Onboard Customer | POST | `/customer/account/{customer_id}` | Register a new customer on the platform; triggers an OTP to verify them. |
| Get Customer Information | GET | `/customer/profile/{customer_id}` | Check whether a customer is already enrolled on the platform by mobile number. |
| Verify Customer OTP | POST | `/customer/account/{customer_id}/otp/verify` | Verify the customer OTP to complete onboarding and return the customer profile. |
| Add Settlement Bank Account | POST | `/user/payment/aeps/settlement/account` | Register a bank account as an AePS fund-settlement recipient for an agent. |
| Get Settlement Bank Accounts | GET | `/user/payment/aeps/settlement/accounts` | List an agent's registered AePS settlement recipients with unsettled funds and remaining limit. |
| Initiate Settlement | POST | `/user/payment/aeps/settlement` | Settle an agent's AePS funds to a registered bank account via NEFT/IMPS/RTGS. |
| Transaction Inquiry | GET | `/tools/reference/transaction/{transaction-reference}` | Get the status of any transaction by Eko TID or your client_ref_id. |
| Get Refund OTP | POST | `/customer/payment/refund/{tid}/otp` | Request the refund OTP for a failed transaction (sent to the customer's mobile). |
| Initiate Refund | POST | `/customer/payment/refund/{tid}` | Refund a failed transaction to the customer after OTP consent. |
| Get Bank Details | GET | `/tools/reference/bank/{bank_code}` | Fetch a bank's details (id, name, channels) by its Eko bank code. |
| Get IFSC Details | GET | `/tools/reference/banks/ifsc/{ifsc}` | Resolve a bank and branch from an IFSC code. |
| Get Operator Code and Circle | GET | `/customer/payment/bbps/recharge/{customer_mobile}/operator` | Auto-detect a mobile number's recharge operator code and telecom circle. |
| Create DigiLocker URL | POST | `/tools/kyc/digilocker` | Generate a DigiLocker redirect URL to initiate consent-based Aadhaar document retrieval. |
| Get DigiLocker Document | POST | `/tools/kyc/digilocker/document` | Retrieve verified Aadhaar details from DigiLocker after the customer completes the consent journey. |
| Bank Account Verification | POST | `/tools/kyc/bank-account/sync` | Verify a bank account by transferring ₹1 (penny drop) and retrieve the account holder name, account status, and branch details in real time. |
| Bulk Bank Account Verification | POST | `/tools/kyc/bank-account/bulk` | Submit multiple bank accounts for penny-drop verification in a single API call; poll a status API for per-account results. |
| GST Verification | POST | `/tools/kyc/gstin` | Verify GSTIN details instantly — legal name, trade name, status, address, and filing metadata — for vendor onboarding and compliance checks. |
| Fetch GSTINs by PAN | POST | `/tools/kyc/gstin-with-pan` | Retrieve all GSTINs linked to a given PAN — with their state and status — in a single API call. |
| UPI ID (VPA) Verification | POST | `/customer/payment/upi/validate-vpa` | Validate a UPI Virtual Payment Address (VPA) and retrieve the registered payee name and mobile number in real time. |
| Driving License Verification | POST | `/tools/kyc/driving-license` | Verify driving license details in real time — holder name, DOB, address, validity, COV/badge class, and status. |
| Vehicle & RC Verification | POST | `/tools/kyc/vehicle-rc` | Verify a vehicle's registration certificate (RC) in real time — owner details, chassis/engine numbers, insurance validity, blacklist status, permits, fitness, and financier info via the VAHAN national database. |
| Employee Verification (Advance) | POST | `/tools/kyc/advance-employment` | Verify employment history and employee identity by phone number via EPFO/UAN data. |
| Reverse Geocoding | POST | `/tools/kyc/reverse-geocoding` | Convert latitude and longitude coordinates into structured Indian address data including locality, city, state, PIN code, and country. |
| Voter ID Verification | POST | `/tools/kyc/voter-id` | Validate EPIC (Voter ID) card details in real time against government records — returns name, age, address, constituency, and polling station information. |
| Passport Verification | POST | `/tools/kyc/passport` | Verify Indian passport application details using passport file number and date of birth. |
| CIN Verification | POST | `/tools/kyc/cin` | Verify Company Identification Numbers (CIN) against MCA records — returns company name, incorporation details, directors, and CIN status. |
| IP Verification | POST | `/tools/kyc/ip` | Geo-locate and risk-score an IP address in real time — detect proxies, VPNs, and assess fraud risk. |
| Name Match API | POST | `/tools/kyc/name-match` | AI-powered name comparison trained on 100M+ Indian name records — returns a match score (0–1) and match category for automated KYC decisions. |
| ITR Compliance Check | POST | `/tools/kyc/touras/itr-compliance` | Check income tax return filing and compliance status for a PAN holder in real time — ideal for lending, credit assessment, and financial due-diligence workflows. |
| DIN Verification | POST | `/tools/kyc/touras/din-verification` | Verify Director Identification Numbers (DIN) against MCA records — returns director name, DIN status, designation, and associated company information. |
| E-Challan Verification | POST | `/tools/kyc/touras/e-challan` | Fetch pending traffic challans for any vehicle using its registration number — challan number, offence, fine amount, date, status, and issuing authority returned in a single API call. |
| Email Verification | POST | `/tools/kyc/touras/check-email` | Verify an email address in real time — confirm the domain has live mail infrastructure, detect disposable addresses, and retrieve domain age as a trust signal. |
| FSSAI License Verification | POST | `/tools/kyc/touras/fetch-fssai` | Verify FSSAI food license details and status in real time. |

Full machine-readable specs: https://eps.eko.in/agent/eps.json (index: https://eps.eko.in/agent/index.json, per-API: https://eps.eko.in/agent/api/<slug>.json). OpenAPI: https://eps.eko.in/openapi.json.

## Multi-step recipes

### DMT — Send Money

Full domestic money transfer flow: look up the sender, onboard them if new, add the recipient, then send an OTP-verified transfer.

1. `dmt-get-sender` — Check whether the customer is already a registered DMT sender. (if response_status_id 463 → dmt-onboard-sender)
2. `dmt-onboard-sender` — Register a new sender when Get Sender returned 463.
3. `dmt-add-recipient` — Add the beneficiary the sender wants to transfer to.
4. `dmt-send-otp` — Trigger the transaction OTP sent to the sender.
5. `dmt-initiate-transfer` — Submit the OTP-verified transfer to complete the flow. (if response_status_id 0 → done)

### AePS — Cash Withdrawal

Aadhaar-enabled cash withdrawal: one-time agent activation, daily 2FA, then the biometric withdrawal.

1. `aeps-activate-fingpay` — One-time activation of AePS Fingpay for the agent.
2. `aeps-daily-auth` — Daily two-factor authentication required before transacting.
3. `aeps-cash-withdrawal` — Perform the biometric Aadhaar-enabled cash withdrawal. (if response_status_id 0 → done)

## Local development & testing (offline mock server)

Test EPS integrations without touching the live API. The mock server replays golden sample responses over plain HTTP on `http://localhost:4010`:

```bash
npx -y @ekoindia/eps-mock-server
```

It mirrors the real EPS paths, so point your EPS base URL at `http://localhost:4010` — no other code change needed. It does not require valid EPS credentials, but keep the same request shape and headers your integration sends. To exercise a documented error branch, append `?eps_scenario=<response_status_id>` to the request for endpoints whose fixture includes that code — e.g. calling the DMT sender lookup (`dmt-get-sender`) with `?eps_scenario=463` returns its "sender not found" branch from the DMT — Send Money recipe.

## Live context via MCP

Install the local context server for richer, on-demand lookups:

```bash
npx -y @ekoindia/eps-context-mcp
```
