Authentication

All endpoints (except login) require a Bearer token in the header:

Authorization: Bearer <access_token>

Login (Org User)

POST /api/v1/auth/login Request:
{
  "agent_id": "GAMDEMO0001",
  "username": "admin",
  "password": "OrgAdmin@123"
}
Success Response (200):
{
  "success": true,
  "message": "login successful",
  "data": {
    "user": {
      "id": "11111111-1111-1111-1111-111111111111",
      "username": "admin",
      "email": "admin@demo.com",
      "name": "Demo Admin",
      "role": "org_admin",
      "status": "active",
      "org_id": "9551fa77-16ad-4df5-9284-dc23cb95c237",
      "sub_agent_id": "GAMDEMO0002"
    },
    "tokens": {
      "access_token": "eyJhbGciOiJIUzI1NiIs...",
      "refresh_token": "eyJhbGciOiJIUzI1NiIs...",
      "expires_in_seconds": 3600
    },
    "agent_id": "GAMDEMO0001"
  }
}
Error Response (401):
{
  "success": false,
  "error": "invalid credentials"
}

Organization Profile

Get Organization Profile

GET /api/v1/org/profile Success Response (200):
{
  "success": true,
  "message": "profile retrieved",
  "data": {
    "id": "9551fa77-16ad-4df5-9284-dc23cb95c237",
    "agent_id": "GAMDEMO0001",
    "name": "Demo Travel Agency",
    "slug": "demo-travel",
    "email": "org@demo.com",
    "phone": "+91 9876543210",
    "address": "123 Main Street, Mumbai",
    "country": "IN",
    "subscription_type": "full",
    "status": "active",
    "ip_whitelist_enabled": false,
    "wallet": {
      "id": "11111111-1111-1111-1111-111111111110",
      "balance": 100000,
      "currency": "INR",
      "credit_limit": 0,
      "is_active": true
    }
  }
}

Update Organization Profile

PUT /api/v1/org/profile Request:
{
  "name": "Demo Travel Agency",
  "email": "org@demo.com",
  "phone": "+91 9876543210",
  "address": "123 Main Street, Mumbai",
  "country": "IN"
}
Success Response (200):
{
  "success": true,
  "message": "profile updated"
}

Organization Settings

Get Settings

GET /api/v1/org/settings Success Response (200):
{
  "success": true,
  "message": "settings retrieved",
  "data": [
    {
      "key": "allow_agent_registration",
      "value": "true",
      "org_id": "9551fa77-16ad-4df5-9284-dc23cb95c237"
    }
  ]
}

Update Setting

PUT /api/v1/org/settings Request:
{
  "key": "allow_agent_registration",
  "value": "true"
}
Success Response (200):
{
  "success": true,
  "message": "setting updated"
}

Users Management

List Users

GET /api/v1/org/users

Query Parameters: page, per_page

Success Response (200):
{
  "success": true,
  "data": [
    {
      "id": "5b920162-500f-474f-8e7a-5f131053a7d5",
      "username": "testagent",
      "email": "agent@demo.com",
      "name": "Test Agent",
      "role": "agent",
      "status": "active",
      "created_at": "2026-04-10T14:47:58.251295+05:30"
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 20,
    "total": 2,
    "total_pages": 1
  }
}

Create User

POST /api/v1/org/users Request:
{
  "email": "agent@demo.com",
  "name": "Test Agent",
  "username": "testagent",
  "password": "Agent@123",
  "role": "agent"
}

Valid Roles: org_admin, agent

Success Response (200):
{
  "success": true,
  "message": "user created",
  "data": {
    "id": "5b920162-500f-474f-8e7a-5f131053a7d5",
    "username": "testagent",
    "email": "agent@demo.com",
    "name": "Test Agent",
    "role": "agent",
    "status": "active",
    "org_id": "9551fa77-16ad-4df5-9284-dc23cb95c237",
    "sub_agent_id": "GAMWE0VFZSA"
  }
}

Get User by ID

GET /api/v1/org/users/:id

Update User

PUT /api/v1/org/users/:id Request:
{
  "name": "Updated Name",
  "email": "new@demo.com",
  "phone": "+919999999999"
}

Delete User

DELETE /api/v1/org/users/:id

Suspend User

PUT /api/v1/org/users/:id/suspend

Activate User

PUT /api/v1/org/users/:id/activate

Assign Package to User

PUT /api/v1/org/users/:id/package Request:
{
  "package_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
}

Organization Wallet

Get Organization Wallet

GET /api/v1/org/wallet Success Response (200):
{
  "success": true,
  "message": "wallet retrieved",
  "data": {
    "id": "11111111-1111-1111-1111-111111111110",
    "owner_id": "9551fa77-16ad-4df5-9284-dc23cb95c237",
    "owner_type": "org",
    "balance": 100000,
    "currency": "INR",
    "credit_limit": 0,
    "is_active": true
  }
}

Get Wallet Transactions

GET /api/v1/org/wallet/transactions

Query Parameters: page, per_page

Topup Agent Wallet

POST /api/v1/org/wallet/topup/:agent_id Request:
{
  "amount": 5000,
  "description": "Bonus credit"
}

Self Profile (/me endpoints)

All authenticated org users (both org_admin and agent) can access these endpoints.

Get My Profile

GET /api/v1/me Success Response (200):
{
  "success": true,
  "message": "profile retrieved",
  "data": {
    "id": "11111111-1111-1111-1111-111111111111",
    "username": "admin",
    "email": "admin@demo.com",
    "name": "Demo Admin",
    "phone": "",
    "role": "org_admin",
    "status": "active",
    "org_id": "9551fa77-16ad-4df5-9284-dc23cb95c237",
    "sub_agent_id": "GAMDEMO0002",
    "last_login_at": "2026-04-10T14:45:35.36903+05:30"
  }
}

Update My Profile

PUT /api/v1/me Request:
{
  "name": "Updated Name",
  "phone": "+919999999999"
}

Change Password

PUT /api/v1/me/password Request:
{
  "current_password": "OldPassword@123",
  "new_password": "NewPassword@123"
}
Success Response (200):
{
  "success": true,
  "message": "password changed successfully"
}
Error Response (400):
{
  "success": false,
  "error": "current password is incorrect"
}

My Stats

GET /api/v1/me/stats Success Response (200):
{
  "success": true,
  "message": "stats retrieved",
  "data": {
    "total_bookings": 0,
    "confirmed_bookings": 0,
    "cancelled_bookings": 0,
    "total_spent": 0,
    "total_commissions": 0,
    "wallet_balance": 0
  }
}

Wallet (Self)

Get My Wallet

GET /api/v1/wallet Success Response (200):
{
  "success": true,
  "message": "wallet retrieved",
  "data": {
    "id": "22222222-2222-2222-2222-222222222220",
    "owner_id": "5b920162-500f-474f-8e7a-5f131053a7d5",
    "owner_type": "user",
    "balance": 5000,
    "currency": "INR",
    "credit_limit": 0,
    "is_active": true
  }
}

Get My Transactions

GET /api/v1/wallet/transactions

Query Parameters: page, per_page

Get Fare Rules

POST /api/v1/flights/fare-rules Request:
{
  "fare_key": "riya:W8j24Tcq6yjEiC6Sn8BKGwSb..."
}

Note: Use the offer_token from the search response as the fare_key.

Success Response (200):
{
  "success": true,
  "message": "fare rules retrieved",
  "data": {
    "fare_rules": {
      "fare_basis": "XNRA015",
      "fare_type": "Refundable",
      "cancellation_rules": [
        { "from": "0H", "to": "24H", "penalty_amount": 350, "penalty_percent": 0 }
      ],
      "baggage_allowance": {
        "check_in": "15KG",
        "cabin": "7KG"
      }
    }
  }
}
Error Response (400):
{
  "success": false,
  "error": "offer_ids (or fare_keys) must contain at least one non-empty value"
}

Price Itinerary

POST /api/v1/flights/price Request:
{
  "offer_ids": ["riya:W8j24Tcq6yjEiC6Sn8BKGwSb..."],
  "adults": 1,
  "children": 0,
  "infants": 0
}
Success Response (200):
{
  "success": true,
  "message": "pricing successful",
  "data": {
    "booking_keys": ["riya-book:eyJ..."],
    "expires_at": "2026-04-10T10:03:07.279146Z",
    "price_summary": {
      "total_payable": 2368,
      "public_fare": 2368,
      "currency": "INR",
      "base_fare_total": 1001,
      "tax_total": 1367,
      "agent_details": {
        "agent_fare": 2363,
        "service_fee": 50,
        "gst_on_service_fee": 0,
        "platform_charge": 25,
        "agent_commission": 5
      }
    },
    "passenger_breakdown": [
      {
        "pax_type": "ADT",
        "count": 1,
        "base_per_pax": 1001,
        "tax_per_pax": 1367,
        "total_per_pax": 2368
      }
    ]
  }
}
Error Response (402 - Insufficient Balance):
{
  "success": false,
  "error": "insufficient wallet balance to proceed — available: 0.00, required: 2372.00 (agent fare)"
}

Get Seat Map

POST /api/v1/flights/seat-map Request:
{
  "fare_key": "riya:test",
  "segment_id": "seg_123"
}
Success Response (200):
{
  "success": true,
  "message": "seat map",
  "data": {
    "info": "seat map requires provider-specific parameters — use fare_key to identify the provider"
  }
}

Book Flight

POST /api/v1/flights/book Request:
{
  "booking_key": "riya-book:eyJ...",
  "contact_email": "john@example.com",
  "contact_phone": "+919999999999",
  "passengers": [
    {
      "title": "MR",
      "first_name": "JOHN",
      "last_name": "DOE",
      "dob": "1990-06-15",
      "type": "ADT"
    }
  ]
}
Success Response (200):
{
  "success": true,
  "message": "booking created",
  "data": {
    "booking_id": "45b43ee4-ad9d-45f1-8023-d7be77e3b5d2",
    "booking_ref": "FA-1775294257592",
    "status": "pending",
    "pnr": ""
  }
}

List Bookings

GET /api/v1/flights/bookings

Query Parameters: page, per_page, status (pending, confirmed, cancelled)

Success Response (200):
{
  "success": true,
  "data": [
    {
      "id": "8555813d-f437-49ff-9e7e-a1d144894528",
      "booking_ref": "FA-1775272567576",
      "pnr": "BX04HD0001",
      "provider": "riya",
      "origin": "BOM",
      "destination": "DEL",
      "passenger_count": 1,
      "base_fare": 2162,
      "public_fare": 2162,
      "currency": "INR",
      "status": "confirmed",
      "booked_at": "2026-04-04T08:46:07.576683+05:30",
      "passengers": [
        {
          "title": "MR",
          "first_name": "JOHN",
          "last_name": "DOE",
          "type": "ADT"
        }
      ]
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 20,
    "total": 3,
    "total_pages": 1
  }
}

Get Booking Details

GET /api/v1/flights/bookings/:ref Example:
GET /api/v1/flights/bookings/FA-1775272567576
Success Response (200):
{
  "success": true,
  "data": {
    "booking_id": "8555813d-f437-49ff-9e7e-a1d144894528",
    "booking_ref": "FA-1775272567576",
    "pnr": "BX04HD0001",
    "status": "confirmed",
    "provider": "riya",
    "origin": "BOM",
    "destination": "DEL",
    "passengers": [
      {
        "title": "MR",
        "first_name": "JOHN",
        "last_name": "DOE",
        "dob": "1990-06-15",
        "type": "ADT",
        "seat_no": ""
      }
    ]
  }
}

Retrieve Booking

GET /api/v1/flights/bookings/:ref/retrieve Example:
GET /api/v1/flights/bookings/FA-1775272567576/retrieve
Success Response (200):
{
  "success": true,
  "data": {
    "booking_ref": "FA-1775272567576",
    "pnr": "BX04HD0001",
    "status": "confirmed",
    "provider_booking_id": "RACCU03000030103630040404260094069",
    "ticket_status": "CONFIRMED"
  }
}

Track Booking Status

GET /api/v1/flights/bookings/:ref/track Example:
GET /api/v1/flights/bookings/FA-1775272567576/track
Success Response (200):
{
  "success": true,
  "message": "booking status",
  "data": {
    "Status": {
      "Track_Status": "SUCCESS",
      "ResultCode": "1"
    },
    "TrackStatusresponse": {
      "ItinearyDetails": [
        {
          "RiyaPNR": "BX04HD0001",
          "TotalAmount": "2162.00",
          "TicketStatus": "CONFIRMED",
          "TripType": "O"
        }
      ]
    }
  }
}

Get SSR (Special Services)

GET /api/v1/flights/bookings/:ref/ssr Example:
GET /api/v1/flights/bookings/FA-1775272567576/ssr
Success Response (200):
{
  "success": true,
  "message": "SSR retrieved",
  "data": {
    "baggage": [
      { "code": "BAG15", "description": "15kg Check-in", "price": 0 }
    ],
    "meals": [
      { "code": "VML", "description": "Vegetarian Meal", "price": 350 }
    ],
    "seats": []
  }
}

Get Cancellation Penalty

POST /api/v1/flights/bookings/:ref/penalty Example:
POST /api/v1/flights/bookings/FA-1775272567576/penalty
Request:
{}
Success Response (200):
{
  "success": true,
  "message": "cancellation penalty",
  "data": {
    "penalty": 350,
    "refund_amount": 1812,
    "currency": "INR"
  }
}

Cancel Booking

POST /api/v1/flights/bookings/:ref/cancel Example:
POST /api/v1/flights/bookings/FA-1775272567576/cancel
Request:
{}
Success Response (200):
{
  "success": true,
  "message": "booking cancelled",
  "data": {
    "cancellation_id": "cancel-uuid",
    "refund_amount": 1812,
    "status": "cancelled"
  }
}

Issue Ticket

POST /api/v1/flights/bookings/:ref/issue-ticket Example:
POST /api/v1/flights/bookings/FA-1775272567576/issue-ticket
Request:
{}
Success Response (200):
{
  "success": true,
  "message": "ticket issued",
  "data": {
    "ticket_numbers": ["BX04HD00011-1"],
    "status": "issued"
  }
}

Reschedule Availability

POST /api/v1/flights/bookings/:ref/reschedule-avail Example:
POST /api/v1/flights/bookings/FA-1775272567576/reschedule-avail
Request:
{
  "new_date": "2026-06-15"
}
Success Response (200):
{
  "success": true,
  "message": "reschedule options retrieved",
  "data": {
    "options": [
      {
        "date": "2026-06-15",
        "penalty_amount": 500,
        "fare_difference": 200
      }
    ]
  }
}

Notifications

List Notifications

GET /api/v1/notifications

Query Parameters: page, per_page

Success Response (200):
{
  "success": true,
  "data": [],
  "meta": {
    "page": 1,
    "per_page": 20,
    "total": 0,
    "total_pages": 0
  }
}

Get Unread Count

GET /api/v1/notifications/unread-count Success Response (200):
{
  "success": true,
  "message": "unread count",
  "data": {
    "unread": 0
  }
}

Mark Notification as Read

PUT /api/v1/notifications/:id/read

Mark All as Read

PUT /api/v1/notifications/read-all

Common Error Responses

401 Unauthorized

{
  "success": false,
  "error": "invalid credentials"
}

403 Forbidden

{
  "success": false,
  "error": "access denied"
}

404 Not Found

{
  "success": false,
  "error": "resource not found"
}

422 Validation Error

{
  "success": false,
  "error": "code=422, message=[{field this field is required}]"
}

429 Too Many Requests (IP Blocked)

{
  "success": false,
  "error": "Too many failed attempts — IP blocked for 1 minute(s)."
}

402 Insufficient Balance

{
  "success": false,
  "error": "insufficient wallet balance to proceed — available: 0.00, required: 2372.00 (agent fare)"
}

Notes

  • All timestamps are in ISO 8601 format (UTC)
  • All monetary values are in INR
  • Agent ID format: GAM + 8 alphanumeric characters (e.g., GAMDEMO0001)
  • Sub Agent ID format: GAM + 8 alphanumeric characters (e.g., GAMDEMO0002)
  • After 3 failed login attempts from same IP, the IP gets blocked for 15 minutes