API v2 Reference
The MyPayIndia API v2 uses session-based authentication via Bearer tokens.
All requests and responses are JSON. If you have a question or issue,
ask in #dev on our Discord.
Conventions
Authentication
Log in viaPOST /api/v2/auth/login to receive a session ID.
Pass it as Authorization: Bearer <session_id> on all authenticated requests.
(You will still get a cookie from this endpoint, like in v1, and can use it instead if you want)
Money
All amounts are integers in paisa100 = 1.00 INR10000 = 100.00 INR
Timestamps
All timestamps are ISO 8601 with UTC offset2026-05-05T14:30:00+00:00
Response Shape
Success:{"success": true, "data": { ... }}Error:
{"success": false, "error": 1001, "message": "..."}
Error Codes
Error codes identify the error type. Themessage field is
human readable but should not be parsed programatically as it can change over time.
Maintenance Mode
Any endpoint may return503 with error code 9003 during maintenenace mode.
Authentication
Authenticate and receive a session ID.
Request Body
| Parameter | Type | Description |
|---|---|---|
| username | string required | Username or email address |
| password | string required | Account password |
| totp_code | string optional | TOTP authenticator code (required if 2FA is enabled) |
Response
{
"success": true,
"data": {
"session_id": "a1b2c3d4e5f6...",
"user": {
"id": 123,
"username": "johnpayment",
"role": "user"
}
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 1005 | 401 | Invalid username/email or password |
| 1002 | 401 | 2FA code required but not provided |
| 1010 | 401 | Invalid 2FA code |
| 1003 | 403 | Account is suspended |
session_id as Authorization: Bearer <session_id> on all authenticated requests.User
Get profile and balance information for the authenticated user.
Response
{
"success": true,
"data": {
"id": 11,
"username": "johnpayment",
"first_name": "John",
"last_name": "Payment",
"email": "[email protected]",
"balance": 1234500,
"role": "user",
"created": "2025-12-01T12:05:00+00:00",
"mfa_enabled": true
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 1001 | 401 | Not authenticated |
Get active restrictions on the authenticated user's account.
Response
{
"success": true,
"data": {
"restrictions": {
"frozen": {
"active": true,
"value": null,
"expires_at": "2026-06-01T00:00:00+00:00",
"label": "Account Frozen",
"description": "You cannot receive or send funds."
}
},
"restrictions_list": [
{
"id": "frozen",
"active": true,
"value": null,
"expires_at": "2026-06-01T00:00:00+00:00",
"label": "Account Frozen",
"description": "You cannot receive or send funds."
}
]
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 1001 | 401 | Not authenticated |
restrictions and restrictions_list carry the same restrictions in two shapes: an object keyed by restriction id, and an array where the id is a field. Pick whichever suits your client. With no active restrictions, restrictions is {} and restrictions_list is []. label is a short title for the restriction and description a sentence explaining it.List active and recently invalidated sessions for the authenticated user.
Response
{
"success": true,
"data": {
"sessions": [
{
"id": "a1b2c3...",
"device_info": "macOS",
"ip": "1.50.100.200",
"created_at": "2026-05-01T10:00:00+00:00",
"last_active": "2026-05-05T14:30:00+00:00",
"invalidated": false,
"invalidated_at": null,
"current": true
}
]
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 1001 | 401 | Not authenticated |
Invalidate (log out) a specific session.
Request Body
| Parameter | Type | Description |
|---|---|---|
| session_id | string required | The session ID to invalidate |
Response
{
"success": true
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 9004 | 400 | Invalid input or missing session_id |
| 1001 | 401 | Not authenticated |
| 9005 | 404 | Session not found or already invalidated |
Send a verification email to the authenticated user's email address.
Response
{
"success": true
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 1013 | 400 | Email already verified |
| 1001 | 401 | Not authenticated |
| 9006 | 429 | Rate limited (60 second cooldown) |
Transactions
Transfer funds to another user.
Request Body
| Parameter | Type | Description |
|---|---|---|
| recipient | string|integer required | Recipient username or user ID |
| amount | integer required | Amount in paisa |
| note | string optional | Optional transfer note |
Response
{
"success": true,
"data": {
"transaction_id": "TXN-1234567890-09af",
"status": "confirmed"
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 9004 | 400 | Invalid or missing input |
| 2001 | 400 | Insufficient balance |
| 2003 | 400 | Cannot transfer to yourself |
| 1001 | 401 | Not authenticated |
| 1003 | 403 | Account is suspended |
| 1004 | 403 | Sender or recipient account is frozen |
| 2005 | 403 | Sender or recipient is restricted from receiving or making transactions |
| 2002 | 404 | Recipient not found |
Get details of a specific transaction.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| id | string|integer required | Transaction database ID or transaction ID (TXN-xxx) |
Response
{
"success": true,
"data": {
"id": 456,
"transaction_id": "TXN-1234567890-09af",
"sender": {
"id": 123,
"username": "johnpayment"
},
"recipient": {
"id": 456,
"username": "timpurchase"
},
"amount": 10000,
"note": "Thanks for the Yuri",
"status": "confirmed",
"created": "2026-05-01T12:33:00+00:00"
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 9004 | 400 | Missing id or invalid identifier format |
| 1001 | 401 | Not authenticated |
| 9005 | 404 | Transaction not found |
Get transaction history for the authenticated user.
Response
{
"success": true,
"data": {
"transactions": [
{
"id": 456,
"transaction_id": "TXN-1234567890-09af",
"sender": { "id": 123, "username": "johnpayment" },
"recipient": { "id": 456, "username": "timpurchase" },
"amount": 10000,
"status": "confirmed",
"created": "2026-05-01T12:00:00+00:00",
"note": "Thanks for the Yuri"
}
]
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 1001 | 401 | Not authenticated |
Payment Links
Create a payment link. Deducts the amount from your balance immediately.
Request Body
| Parameter | Type | Description |
|---|---|---|
| amount | integer required | Amount in paisa |
| note | string optional | Optional note |
Response
{
"success": true,
"data": {
"id": 123,
"token": "a1b2c3d4...",
"amount": 10000,
"note": "yuri",
"url": "https://mypayindia.com/pay/link?token=a1b2c3d4..."
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 2001 | 400 | Insufficient balance |
| 9004 | 400 | Invalid input or missing amount |
| 1001 | 401 | Not authenticated |
| 1012 | 403 | Account email is not verified |
| 1003 | 403 | Account is suspended |
| 1004 | 403 | Account is frozen |
| 2005 | 403 | Account is restricted from creating payment links |
List all payment links created by the authenticated user.
Response
{
"success": true,
"data": {
"links": [
{
"id": 123,
"token": "a1b2c3d4...",
"amount": 10000,
"note": "yuri",
"created": "2026-05-01T12:00:00+00:00",
"status": "active",
"url": "https://mypayindia.com/pay/link?token=a1b2c3d4..."
}
]
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 1001 | 401 | Not authenticated |
Get details of a payment link by its token.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| token | string required | Payment link token |
Response
{
"success": true,
"data": {
"amount": 10000,
"creator": {
"username": "johnpayment"
},
"note": "yuri",
"created": "2026-05-01T12:00:00+00:00"
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 9004 | 400 | Missing token parameter |
| 3002 | 400 | Payment link already claimed |
| 3003 | 400 | Payment link cancelled |
| 3001 | 404 | Payment link not found or invalid token |
Claim a payment link and receive the funds.
Request Body
| Parameter | Type | Description |
|---|---|---|
| token | string required | Payment link token |
Response
{
"success": true,
"data": {
"transaction_id": "TXN-1234567890-09af"
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 9004 | 400 | Invalid input or missing token |
| 3004 | 400 | Payment link already used |
| 3005 | 400 | Cannot claim your own payment link |
| 1001 | 401 | Not authenticated |
| 1012 | 403 | Unverified account claiming above the unverified limit |
| 1003 | 403 | Account is suspended |
| 3001 | 404 | Payment link not found |
Cancel your own payment link and refund the amount to your balance.
Request Body
| Parameter | Type | Description |
|---|---|---|
| token | string required | Payment link token |
Response
{
"success": true
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 9004 | 400 | Invalid input or missing token |
| 3002 | 400 | Payment link was already claimed |
| 1001 | 401 | Not authenticated |
| 1003 | 403 | Account is suspended |
| 1014 | 403 | Not your payment link |
| 1015 | 403 | Would exceed account fund limits if refunded |
| 3001 | 404 | Payment link not found |
Subscriptions
List the authenticated user's subscriptions.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| status | string optional | Filter by status: active, trialing, past_due, cancelled, expired |
Response
{
"success": true,
"data": {
"subscriptions": [
{
"subscription_id": "sub_a1b2c3d4e5f6...",
"plan_name": "MyPayIndia Premium",
"business_name": "MyPayIndia",
"amount": 25000,
"interval": "monthly",
"interval_count": 1,
"status": "active",
"cancel_at_period_end": false,
"current_period_start": "2026-06-04T10:00:00+00:00",
"current_period_end": "2026-07-04T10:00:00+00:00",
"cancelled_at": null,
"created_at": "2026-06-04T10:00:00+00:00"
}
]
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 1001 | 401 | Not authenticated |
Cancel a subscription at the end of the current billing period.
Request Body
| Parameter | Type | Description |
|---|---|---|
| subscription_id | string required | The subscription ID (sub_xxx) |
Response
{
"success": true,
"data": {
"subscription_id": "sub_a1b2c3d4e5f6...",
"cancel_at_period_end": true
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 9004 | 400 | Missing subscription_id, or the subscription is already cancelled/scheduled for cancellation |
| 1001 | 401 | Not authenticated |
| 1003 | 403 | Account is suspended |
| 9005 | 404 | No such subscription for this user |
Undo a pending cancellation and resume a subscription.
Request Body
| Parameter | Type | Description |
|---|---|---|
| subscription_id | string required | The subscription ID (sub_xxx) |
Response
{
"success": true,
"data": {
"subscription_id": "sub_a1b2c3d4e5f6...",
"cancel_at_period_end": false
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 9004 | 400 | Missing subscription_id, or the subscription is not pending cancellation |
| 1001 | 401 | Not authenticated |
| 1003 | 403 | Account is suspended |
| 9005 | 404 | No such subscription for this user |
cancel_at_period_end: true). Cannot resume already cancelled or expired subscriptions.Agent
Get the current conversation with MyAgentIndia
Response
{
"success": true,
"data": {
"agent": {
"name": "Nancy C \"Quechua Juandres \"Eggball\" Marley\" Sizzem",
"short_name": "Nancy",
"avatar": "https://mypayindia.com/images/nancy.png"
},
"max_length": 300,
"greeting": "I am Nancy C \"Quechua Juandres \"Eggball\" Marley\" Sizzem. What can I help you with?",
"transcript": [
{
"role": "user",
"text": "what is my balance"
},
{
"role": "agent",
"text": "",
"confirmable": false,
"steps": [],
"results": [
{
"ok": true,
"message": "You have 12,345.00 INR",
"writes": false,
"kind": null,
"cards": []
}
]
}
],
"awaiting_confirmation": false,
"awaiting_answer": false,
"suggestions": [
"what is my balance",
"send 100 to mypayindia"
]
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 1001 | 401 | Not authenticated |
awaiting_confirmation means a change is planned and waiting on /api/v2/agent/confirm.
awaiting_answer means the agent asked for a missing detail and reads the next message as the answer.
Every other agent endpoint returns this same object.Say something to MyAgentIndia
Request Body
| Parameter | Type | Description |
|---|---|---|
| message | string required | What the user said (max 300 chars) |
Response
{
"success": true,
"data": {
"greeting": "...",
"transcript": ["..."],
"awaiting_confirmation": true,
"awaiting_answer": false,
"suggestions": ["..."],
"reply": [
{
"role": "agent",
"text": "Confirm this action:",
"confirmable": true,
"steps": [
{
"status": "ready",
"label": "Send money",
"description": "Recipient: @johnpayment / Amount: 100.00",
"note": null
}
],
"results": []
}
]
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 9004 | 400 | Missing or empty message |
| 1001 | 401 | Not authenticated |
reply is what the agent said back this turn, so you can append it without having to reapply the whole transcript.
Refusals come back as results[].ok: false, not an error response.
text may contain *emphasis* and [label](/path) links, render or strip them.
A result with a kind carries cards to draw as a list instead of a sentence:
payment-links
(token, amount, note, status, created, url), transactions
(id, reference, other_party, sent, amount, status, created)
and weather
(place, flag, label, icon, temperature, feels_like, humidity).Carry out the action MyAgentIndia is waiting on.
Response
{
"success": true,
"data": {
"greeting": "...",
"transcript": ["..."],
"awaiting_confirmation": false,
"awaiting_answer": false,
"suggestions": ["..."],
"reply": [
{
"role": "agent",
"text": "",
"confirmable": false,
"steps": [],
"results": [
{
"ok": true,
"message": "Sent 100.00 INR to @johnpayment.",
"writes": true,
"kind": null,
"cards": []
}
]
}
]
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 1001 | 401 | Not authenticated |
Turn down the action MyAgentIndia is waiting on.
Response
{
"success": true,
"data": {
"greeting": "...",
"transcript": ["..."],
"awaiting_confirmation": false,
"awaiting_answer": false,
"suggestions": ["..."],
"reply": [
{
"role": "agent",
"text": "Okay, I won't do that then",
"confirmable": false,
"steps": [],
"results": []
}
]
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 1001 | 401 | Not authenticated |
Start a new conversation.
Response
{
"success": true,
"data": {
"greeting": "...",
"transcript": [],
"awaiting_confirmation": false,
"awaiting_answer": false,
"suggestions": ["..."]
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 1001 | 401 | Not authenticated |
App
Check the latest and minimum supported app version for a platform.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| platform | string required | App platform, either "android" or "ios" |
Response
{
"success": true,
"data": {
"latest_version": 26050100,
"min_supported_version": 26040200,
"update_url": "https://mypayindia.com/app/android"
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
| 9004 | 400 | Missing or invalid platform (must be android or ios) |
min_supported_version.Public
Get the top 10 users by balance.
Response
{
"success": true,
"data": {
"leaderboard": [
{
"username": "johnpayment",
"balance": 1234500
}
]
}
}
Get the list of MyPayIndia team members.
Response
{
"success": true,
"data": {
"team": [
{
"name": "John Payment",
"role": "Intern 5",
"avatar": "https://mypayindia.com/siteassets/images/team/johnpayment.webp",
"joined": "2025-12-01T08:36:00+00:00",
"socials": {
"Website": "https://mypayindia.com",
"GitHub": "https://github.com/mypayindiadevs"
},
"status": "current",
"country": "US",
"country_name": "United States",
"country_flag": "🇺🇸",
"role_history": [
{
"role": "Intern 5",
"start_date": "2025-12-01",
"end_date": null
}
],
"contributions": [
"January redesign",
"MyPWAIndia"
],
"quote": "Online banking of the future",
"pride_flags": ["rainbow", "trans"]
}
]
}
}
status is one of current, past, or special_thanks. country/country_name/country_flag, quote, and pride_flags are null or an empty array/object if not set for that member. pride_flags entries are one of: rainbow, trans, bisexual, pansexual, nonbinary, lesbian, mlm, asexual, genderfluid, aromantic, agender, intersex.