Customers & Prescriptions – OptoSoft API
Create and update customers, search the customer register, detect duplicates, and manage spectacle and contact-lens prescriptions (SPH, CYL, AXIS, ADD, PD) plus the referring-doctor master.
13 endpoints in this module. Every request needs a JWT bearer token — see Authentication.
Customers & Prescriptions
The customer module is the entry point for almost every OptoSoft workflow. It holds the customer register, the full optical prescription history (spectacle powers and contact-lens parameters), and the referring-doctor master used on prescriptions and orders.
A customer in OptoSoft is more than a contact record: it carries the latest recorded
prescription inline (the lefT_* /
righT_* fields), membership and loyalty flags,
marketing consent (DND) flags, and GST details for business customers.
Typical sequence
- Search with
/api/Customer/listby mobile number. - If nothing matches, guard with
/api/Customer/check-duplicate, then create via/api/Customer/upsert. - Attach the eye test with
/api/Customer/save-prescription. - Raise the order — see Sales Orders.
Mobile number is the practical natural key. OptoSoft does not enforce
uniqueness on it, so always search before creating and always run
check-duplicate in an automated import, or you
will fragment a customer’s prescription and purchase history across duplicates.
The search model
Six endpoints on this page share one request model. Every field is a filter: supply only
the ones you want to narrow by and omit the rest. companyID
and branchID are numeric here, unlike most of the API.
| Field | Type | Required | Description |
|---|---|---|---|
| companyID | int64 | Required | Your OptoSoft company (tenant). |
| branchID | int64 | Required | The store to search within. |
| yearID | int64 | Optional | Financial year. Resolve from GET /api/Common/GetYears. |
| customerID | string | Optional | Encrypted customer ID. Set this to fetch one specific customer. |
| firstName | string | Optional | Partial match on given name. |
| lastName | string | Optional | Partial match on surname. |
| mobile | string | Optional | Mobile number. The most reliable lookup. |
| phoneNO | string | Optional | Landline number. |
| string | Optional | Email address. | |
| city | string | Optional | City filter. |
| isActive | string | Optional | Active flag, sent as a string ("true" / "false"). |
| customerSourceStringID | string | Optional | Acquisition source. Values from GET /api/quickSale/getSources. |
| typeID | string | Optional | Customer category / type. |
| orderBy | string | Optional | Sort column, optionally with DESC. |
| fromPage | int32 | Optional | First row of the range (row-range paging). |
| toPage | int32 | Optional | Last row of the range. |
Customer endpoints
POST /api/Customer/list
Bearer tokenSearches the customer register and returns a paged list. This is the endpoint you use to find a walk-in customer by mobile number.
Request body
The shared search model described above.
Example request
curl -X POST https://api.opto-soft.com/api/Customer/list \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"companyID": 18,
"branchID": 24,
"mobile": "9876543210",
"fromPage": 1,
"toPage": 20,
"orderBy": "FirstName"
}'
Example response — 200 OK
{
"Items": [
{
"CustomerID": "Q2ZQdGhSZVhBaVlXTnpaWFF3TWk0d01B",
"Name": "Rajesh Sharma",
"Mobile": "9876543210",
"PhoneNO": null,
"Email": "rajesh.sharma@email.com",
"City": "Mumbai",
"IsActive": "true",
"CreatedDate": "2023-06-10T09:15:00",
"PrescriptionID": "Q2ZQdGhSZVhBaVlXTnpaWFF5TWk0d01B",
"VisitingDate": "15/01/2024"
},
{
"CustomerID": "Q2ZQdGhSZVhBaVlXTnpaWFF3T0M0d01B",
"Name": "Priya Patel",
"Mobile": "9123456780",
"PhoneNO": null,
"Email": "priya@email.com",
"City": "Pune",
"IsActive": "true",
"CreatedDate": "2024-01-05T11:20:00",
"PrescriptionID": null,
"VisitingDate": null
}
],
"Total": 512,
"PageNumber": 1,
"PageSize": 20
}
POST /api/Customer/detail
Bearer token
Returns the complete record for a single customer, including address, membership
and the inline latest prescription. Set customerID
to the encrypted ID returned by /api/Customer/list.
Request body
The shared search model, with
customerID set.
Example request
curl -X POST https://api.opto-soft.com/api/Customer/detail \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"companyID": 18,
"branchID": 24,
"customerID": "ENCRYPTED_CUSTOMER_ID"
}'
Example response — 200 OK
{
"ID": "Q2ZQdGhSZVhBaVlXTnpaWFF3TWk0d01B",
"BranchID": "Q2ZQdGhSZVhBaVlXTnpaWFF4TWk0d01B",
"CompanyID": "Q2ZQdGhSZVhBaVlXTnpaWFF4T0M0d01B",
"CustomerID": "CUST-00123",
"Title": "Mr.",
"FirstName": "Rajesh",
"MiddleName": "",
"LastName": "Sharma",
"IsMarried": true,
"Reference": "Walk-in",
"BirthDate": "1989-05-15T00:00:00",
"Mobile": "9876543210",
"EmailId": "rajesh.sharma@email.com",
"City": "Mumbai",
"ZipCode": "400001",
"Address": "123 MG Road",
"HouseNumber": "A-12",
"SocietyName": "Green Gardens",
"Street": "MG Road",
"Area": "Fort",
"Landmark": "Near Post Office",
"IsActive": true,
"NewCustomer": false,
"IsNRI": false,
"GSTNO": null,
"IsStoreCustomer": false,
"IsMember": true,
"MembershipID": "Q2ZQdGhSZVhBaVlXTnpaWFF5TWk0d01B",
"Age": 35,
"BloodGroup": "O+",
"IsBlackList": false,
"DNDForPromotionalMessage": false,
"DNDForTransactionalMessage": false,
"IsForeigner": false,
"StateID": "Q2ZQdGhSZVhBaVlXTnpaWFF5T0M0d01B",
"CountryID": "Q2ZQdGhSZVhBaVlXTnpaWFF6TWk0d01B",
"LEFT_SphericalWithSign": "-1.50",
"RIGHT_SphericalWithSign": "-2.00",
"RIGHT_CylinderWithSign": "-0.75",
"LEFT_CylinderWithSign": "-0.50",
"LEFT_AxisWithSign": "180",
"RIGHT_AxisWithSign": "175",
"RIGHT_AdditionWithSign": "+1.00",
"LEFT_AdditionWithSign": "+1.00",
"LEFTVision": "6/6",
"RIGHTVision": "6/9",
"LEFTVN": null,
"RIGHTVN": null,
"RIGHTPD": "32",
"LEFTPD": "32",
"LEFTBC": null,
"RIGHTBC": null,
"LEFTDIA": null,
"RIGHTDIA": null,
"PrescriptionRemarks": "Driving glasses recommended",
"SalesOrderID": "Q2ZQdGhSZVhBaVlXTnpaWFF6T0M0d01B",
"CreatedDate": "2023-06-10T09:15:00",
"ModifiedDate": "2024-01-20T14:30:00"
}
POST /api/Customer/check-duplicate
Bearer token
Tests whether a customer matching the supplied mobile, email or name already
exists, without creating anything. Call this before
upsert in any bulk import.
Request body
The shared search model. Populate the identifying fields you are about to insert.
Example request
curl -X POST https://api.opto-soft.com/api/Customer/check-duplicate \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"companyID": 18,
"branchID": 24,
"mobile": "9876543210",
"firstName": "Anita",
"lastName": "Shah"
}'
Example response — 200 OK
{
"isDuplicate": true,
"customer": {
"ID": "Q2ZQdGhSZVhBaVlXTnpaWFF3TWk0d01B",
"CustomerID": "CUST-00123",
"Title": "Mr.",
"FirstName": "Rajesh",
"MiddleName": "",
"LastName": "Sharma",
"Mobile": "9876543210",
"EmailId": "rajesh.sharma@email.com",
"City": "Mumbai",
"Address": "123 MG Road",
"ZipCode": "400001",
"IsActive": true,
"IsMember": true,
"MembershipID": "Q2ZQdGhSZVhBaVlXTnpaWFF5TWk0d01B",
"Age": 35,
"BloodGroup": "O+",
"BirthDate": "1989-05-15T00:00:00",
"LEFT_SphericalWithSign": "-1.50",
"RIGHT_SphericalWithSign": "-2.00",
"RIGHT_CylinderWithSign": "-0.75",
"LEFT_CylinderWithSign": "-0.50",
"LEFT_AxisWithSign": "180",
"RIGHT_AxisWithSign": "175",
"RIGHT_AdditionWithSign": "+1.00",
"LEFT_AdditionWithSign": "+1.00",
"SalesOrderID": "Q2ZQdGhSZVhBaVlXTnpaWFF5T0M0d01B"
}
}
Example response — 200 (no duplicate found)
{
"isDuplicate": false,
"customer": null
}
POST /api/Customer/upsert
Bearer token
Creates a new customer, or updates an existing one when
id is supplied. This is the largest model in
the customer module (77 fields), but only a handful are needed to create a usable
record.
Most-used fields
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | Optional | Encrypted customer ID. Omit to create; supply to update. |
| companyID | string | Required | Encrypted company ID — a string here, unlike the search model. |
| branchID | string | Required | Encrypted branch ID. |
| yearID | string | Required | Encrypted financial-year ID. |
| firstName | string | Required | Given name. |
| lastName | string | Optional | Surname. |
| mobile | string | Required | Mobile number. Used for WhatsApp and SMS recalls. |
| emailId | string | Optional | Email address. |
| title | string | Optional | Salutation (Mr, Mrs, Ms, Dr). |
| genderID | string | Optional | Encrypted gender ID from GET /api/quickSale/getGenders. |
| birthDate | date-time | Optional | Drives birthday marketing campaigns. |
| address | string | Optional | Free-text address. Structured parts are also available (see full list). |
| city | string | Optional | City. |
| zipCode | string | Optional | PIN code. |
| stateID | string | Optional | Encrypted state ID from GET /api/Common/GetStates/{countryId}. Drives CGST/SGST vs IGST. |
| countryID | string | Optional | Encrypted country ID from GET /api/Common/GetCountries. |
| gstno | string | Optional | GSTIN for B2B invoices. |
| customerSourceID | string | Optional | How the customer found you. |
| isActive | boolean | Optional | Defaults to active. |
| dndForPromotionalMessage | boolean | Optional | Suppress marketing messages. Set from your own consent capture. |
| dndForTransactionalMessage | boolean | Optional | Suppress order and receipt notifications. |
Show all 77 fields
| Field | Type |
|---|---|
| id | string |
| branchID | string |
| stateID | string |
| countryID | string |
| faceShapeID | string |
| genderID | string |
| companyID | string |
| customerID | string |
| yearID | string |
| title | string |
| firstName | string |
| middleName | string |
| lastName | string |
| isMarried | boolean |
| reference | string |
| birthDate | date-time |
| remarks | string |
| mobile | string |
| emailId | string |
| city | string |
| zipCode | string |
| address | string |
| houseNumber | string |
| societyName | string |
| street | string |
| area | string |
| landmark | string |
| isActive | boolean |
| createdBy | string |
| createdDate | date-time |
| createdIP | string |
| modifiedBy | string |
| modifiedDate | date-time |
| modifiedIP | string |
| newCustomer | boolean |
| isNRI | boolean |
| marriageDate | date-time |
| existingCustomerReference | string |
| phoneNO | string |
| gstno | string |
| customerSourceID | string |
| customerCategoryID | string |
| isStoreCustomer | boolean |
| storeID | string |
| isMember | boolean |
| membershipID | string |
| age | int32 |
| bloodGroup | string |
| self | string |
| isBlackList | boolean |
| dndForPromotionalMessage | boolean |
| dndForTransactionalMessage | boolean |
| clientConsentImage | string |
| clientConsentDisplayName | string |
| prescriptionDocument | string |
| prescriptionDocumentDisplayName | string |
| isForeigner | boolean |
| lefT_SphericalWithSign | string |
| righT_SphericalWithSign | string |
| righT_CylinderWithSign | string |
| lefT_CylinderWithSign | string |
| lefT_AxisWithSign | string |
| righT_AxisWithSign | string |
| righT_AdditionWithSign | string |
| lefT_AdditionWithSign | string |
| leftVision | string |
| rightVision | string |
| leftvn | string |
| rightvn | string |
| rightpd | string |
| leftpd | string |
| leftbc | string |
| rightbc | string |
| leftdia | string |
| rightdia | string |
| prescriptionRemarks | string |
| salesOrderID | string |
Example request
curl -X POST https://api.opto-soft.com/api/Customer/upsert \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"companyID": "ENCRYPTED_COMPANY_ID",
"branchID": "ENCRYPTED_BRANCH_ID",
"yearID": "ENCRYPTED_YEAR_ID",
"title": "Ms",
"firstName": "Anita",
"lastName": "Shah",
"mobile": "9876543210",
"emailId": "anita.shah.example.in",
"city": "Ahmedabad",
"zipCode": "380015",
"isActive": true,
"dndForPromotionalMessage": false
}'
The scoping fields are encrypted strings on this endpoint, not
the numeric values used by the search model. Take them from a prior response
(for example /api/Customer/detail) rather
than converting the numbers yourself.
Example response — 200 OK
{
"success": true,
"message": "Customer saved successfully.",
"customerID": "Q2ZQdGhSZVhBaVlXTnpaWFF3TWk0d01B"
}
Prescription endpoints
A prescription in OptoSoft is an eye info record identified by
customerEyeInfoID, holding one row per lens type
(distance, near, contact lens) with the standard optical parameters.
| Parameter | Optical meaning |
|---|---|
| sph | Sphere — myopia or hyperopia correction, in dioptres. |
| cyl | Cylinder — astigmatism correction. |
| axis | Axis of the cylinder, 0–180 degrees. |
| add | Addition — near power for bifocal and progressive lenses. |
| va | Visual acuity, distance. |
| vn | Visual acuity, near. |
| pd | Pupillary distance, in millimetres. |
| bc | Base curve — contact lenses. |
| dia | Diameter — contact lenses. |
| fh | Fitting height for progressive lenses. |
| th | Total height of the lens. |
| lensTypeID | Encrypted lens-type ID identifying which row this is. |
POST /api/Customer/prescription-list
Bearer tokenLists a customer’s prescription history, newest first. Use it to show previous eye tests before recording a new one.
Request body
The shared search model, with
customerID set.
Example request
curl -X POST https://api.opto-soft.com/api/Customer/prescription-list \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"companyID": 18,
"branchID": 24,
"customerID": "ENCRYPTED_CUSTOMER_ID",
"fromPage": 1,
"toPage": 10
}'
Example response — 200 OK
{
"Items": [
{
"Id": "Q2ZQdGhSZVhBaVlXTnpaWFF3TWk0d01B",
"CustomerID": "Q2ZQdGhSZVhBaVlXTnpaWFF4TWk0d01B",
"TypeID": 1,
"DoctorName": "Dr. Anjali Mehta",
"VisitingDate": "2024-01-15T00:00:00",
"VisitingDateString": "15/01/2024",
"Spherical_Left": "-1.50",
"Cylindrical_Left": "-0.50",
"Axis_Left": "180",
"Addition_Left": null,
"Vision_Left": "6/6",
"Spherical_Right": "-2.00",
"Cylindrical_Right": "-0.75",
"Axis_Right": "175",
"Addition_Right": null,
"Vision_Right": "6/9",
"Remarks": "Advised anti-glare coating",
"IsActive": true
}
],
"Total": 5,
"PageNumber": 1,
"PageSize": 10
}
POST /api/Customer/GetPrescription
Bearer tokenReturns the summary view of one prescription.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| customerEyeInfoID | string | Required | Encrypted prescription ID from prescription-list. |
Example request
curl -X POST https://api.opto-soft.com/api/Customer/GetPrescription \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "customerEyeInfoID": "ENCRYPTED_EYE_INFO_ID" }'
Example response — 200 OK
{
"Id": "Q2ZQdGhSZVhBaVlXTnpaWFF3TWk0d01B",
"CustomerID": "Q2ZQdGhSZVhBaVlXTnpaWFF4TWk0d01B",
"ItemTypeId": 1,
"TypeID": 1,
"SpectacleType": null,
"EyeInfo_DoctorID": "Q2ZQdGhSZVhBaVlXTnpaWFF5TWk0d01B",
"DoctorName": "Dr. Anjali Mehta",
"VisitingDate": "2024-01-15T00:00:00",
"VisitingDateString": "15/01/2024",
"Spherical_Left": "-1.50",
"Cylindrical_Left": "-0.50",
"Axis_Left": "180",
"Addition_Left": null,
"Vision_Left": "6/6",
"BaseCurve_Left": null,
"Diameter_Left": null,
"VN_Left": null,
"PD_Left": "32",
"Dist_Left": null,
"Near_Left": null,
"K1_Left": null,
"K2_Left": null,
"WODist_Left": null,
"WONear_Left": null,
"PIN_Left": null,
"IOP_Left": null,
"Spherical_Right": "-2.00",
"Cylindrical_Right": "-0.75",
"Axis_Right": "175",
"Addition_Right": null,
"Vision_Right": "6/9",
"BaseCurve_Right": null,
"Diameter_Right": null,
"VN_Right": null,
"PD_Right": "32",
"Dist_Right": null,
"Near_Right": null,
"K1_Right": null,
"K2_Right": null,
"WODist_Right": null,
"WONear_Right": null,
"PIN_Right": null,
"IOP_Right": null,
"Remarks": "Advised anti-glare coating",
"IsActive": true,
"GoToSalesOrder": false,
"EyeCheckupRecallDate": "2024-07-15T00:00:00",
"IsPrevious": false
}
POST /api/Customer/prescription-full-detail
Bearer token
Returns the complete prescription, including every lens-type row and the
associated doctor and remarks. Use this when reprinting an Rx or pre-filling a
reorder; GetPrescription returns the lighter
summary.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| customerEyeInfoID | string | Required | Encrypted prescription ID. |
Example request
curl -X POST https://api.opto-soft.com/api/Customer/prescription-full-detail \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "customerEyeInfoID": "ENCRYPTED_EYE_INFO_ID" }'
Example response — 200 OK
{
"CustomerID": "Q2ZQdGhSZVhBaVlXTnpaWFF3TWk0d01B",
"FirstName": "Rajesh",
"LastName": "Sharma",
"Mobile": "9876543210",
"EmailID": "rajesh.sharma@email.com",
"City": "Mumbai",
"VisitingDate": "2024-01-15T00:00:00",
"TypeID": 1,
"Spherical_Left": "-1.50",
"Spherical_Right": "-2.00",
"Cylindrical_Left": "-0.50",
"Cylindrical_Right": "-0.75",
"Axis_Left": "180",
"Axis_Right": "175",
"Addition_Left": null,
"Addition_Right": null,
"Vision_Left": "6/6",
"Vision_Right": "6/9",
"VN_Left": null,
"VN_Right": null,
"PD_Left": "32",
"PD_Right": "32",
"BaseCurve_Left": null,
"BaseCurve_Right": null,
"Diameter_Left": null,
"Diameter_Right": null,
"K1_Left": null,
"K1_Right": null,
"K2_Left": null,
"K2_Right": null,
"PrescriptionRemarks": "Advised anti-glare coating",
"CompanyName": "Vision Optics Pvt Ltd",
"CompanyAddress": "123 MG Road, Fort, Mumbai",
"CompanyEmailID": "info@visionoptics.com",
"CompanyMobile": "9876543210",
"BranchName": "Main Branch",
"BranchAddress": "123 MG Road",
"BranchEmail": "main@visionoptics.com",
"BranchMoile": "9876500000",
"DoctorID": "Q2ZQdGhSZVhBaVlXTnpaWFF5T0M0d01B"
}
POST /api/Customer/save-prescription
Bearer token
Records a new eye test against a customer. The customer identity fields sit at the
top level and the optical powers go in
prescriptionList, one entry per lens type.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| companyID | int64 | Required | Company (tenant). |
| branchID | int64 | Required | Store. |
| yearID | int64 | Required | Financial year. |
| customerID | string | Required | Encrypted customer ID the prescription belongs to. |
| id | string | Optional | Encrypted prescription ID. Omit to create a new one. |
| firstName | string | Optional | Customer name, echoed onto the Rx printout. |
| lastName | string | Optional | Customer surname. |
| mobile | string | Optional | Contact number. |
| string | Optional | Email address. | |
| birthDate | string | Optional | Date of birth. |
| genderID | string | Optional | Encrypted gender ID. |
| doctorID | string | Optional | Encrypted referring-doctor ID. See doctor endpoints. |
| presripionTypeID | string | Optional | Prescription type. Note the spelling in the API. |
| visitingDate | string | Optional | Date of the eye test. |
| sourceID | string | Optional | Encrypted acquisition-source ID. |
| houseNO | string | Optional | Address — house number. |
| societyName | string | Optional | Address — society or building. |
| street | string | Optional | Address — street. |
| area | string | Optional | Address — area. |
| city | string | Optional | Address — city. |
| prescriptionRemarks | string | Optional | Free-text clinical notes. |
| prescriptionList | array | Required | One entry per lens type — see the parameter table above. |
Example request
curl -X POST https://api.opto-soft.com/api/Customer/save-prescription \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"companyID": 18,
"branchID": 24,
"yearID": 9,
"customerID": "ENCRYPTED_CUSTOMER_ID",
"doctorID": "ENCRYPTED_DOCTOR_ID",
"visitingDate": "2026-07-26",
"prescriptionRemarks": "Progressive lenses advised.",
"prescriptionList": [
{
"lensTypeID": "ENCRYPTED_LENS_TYPE_ID",
"sph": "-1.75",
"cyl": "-0.50",
"axis": "90",
"add": "+2.00",
"va": "6/6",
"vn": "N6",
"pd": "62"
}
]
}'
Example response — 200 OK
{
"Message": "Prescription saved successfully.",
"CustomerID": "Q2ZQdGhSZVhBaVlXTnpaWFF3TWk0d01B",
"EyeInfoID": "Q2ZQdGhSZVhBaVlXTnpaWFF4TWk0d01B"
}
POST /api/Customer/delete-prescription
Bearer token
Removes a prescription record. Note this is a POST,
not DELETE.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| customerEyeInfoID | string | Required | Encrypted prescription ID to delete. |
Example request
curl -X POST https://api.opto-soft.com/api/Customer/delete-prescription \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "customerEyeInfoID": "ENCRYPTED_EYE_INFO_ID" }'
A prescription already referenced by a dispensed order should normally be superseded by saving a new one rather than deleted, so the order keeps its clinical audit trail.
Example response — 200 OK
{
"success": true,
"message": "Prescription deleted successfully."
}
Doctor endpoints
Prescriptions can cite a referring optometrist or ophthalmologist. These four endpoints maintain that master list.
POST /api/Customer/doctor-list
Bearer tokenReturns the full doctor list for the branch, unpaged. Suitable for populating a dropdown at start-up.
Request body
The shared search model.
Example request
curl -X POST https://api.opto-soft.com/api/Customer/doctor-list \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "companyID": 18, "branchID": 24 }'
Example response — 200 OK
{
"Items": [
{
"DoctorID": "Q2ZQdGhSZVhBaVlXTnpaWFF3TWk0d01B",
"DoctorName": "Dr. Anjali Mehta",
"Mobile": "9876500001",
"Email": "dr.anjali@clinic.com",
"City": "Mumbai",
"IsActive": "true"
}
],
"Total": 12,
"PageNumber": 1,
"PageSize": 20
}
POST /api/Customer/doctor-list-page
Bearer token
The paged equivalent of doctor-list, for a
searchable admin grid. Use the fromPage and
toPage row range.
Request body
The shared search model, with paging fields set.
Example request
curl -X POST https://api.opto-soft.com/api/Customer/doctor-list-page \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"companyID": 18,
"branchID": 24,
"firstName": "Mehta",
"fromPage": 1,
"toPage": 25,
"orderBy": "Name"
}'
Example response — 200 OK
{
"Items": [
{
"DoctorID": "Q2ZQdGhSZVhBaVlXTnpaWFF3TWk0d01B",
"DoctorName": "Dr. Anjali Mehta",
"Mobile": "9876500001",
"Email": "dr.anjali@clinic.com",
"City": "Mumbai",
"IsActive": "true"
}
],
"Total": 12,
"PageNumber": 1,
"PageSize": 20
}
GET /api/Customer/get-doctor/{id}
Bearer tokenReturns one doctor record by encrypted ID.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | Required | Encrypted doctor ID from doctor-list. |
Example request
curl https://api.opto-soft.com/api/Customer/get-doctor/ENCRYPTED_DOCTOR_ID \
-H "Authorization: Bearer YOUR_TOKEN"
POST /api/Customer/save-doctor
Bearer token
Creates a doctor, or updates an existing one when
id is supplied.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | Optional | Encrypted doctor ID. Omit to create. |
| name | string | Required | Doctor’s full name as it should print on the Rx. |
| mobile | string | Optional | Contact number. |
| string | Optional | Email address. | |
| address | string | Optional | Clinic address. |
| city | string | Optional | City. |
| stateID | string | Optional | Encrypted state ID. |
| countryID | string | Optional | Encrypted country ID. |
| zipCode | string | Optional | PIN code. |
| remarks | string | Optional | Internal notes. |
| isActive | boolean | Optional | Set false to retire without deleting. |
Example request
curl -X POST https://api.opto-soft.com/api/Customer/save-doctor \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Dr. R. Mehta",
"mobile": "9825012345",
"city": "Ahmedabad",
"isActive": true
}'
Example response — 200 OK
{
"ID": "Q2ZQdGhSZVhBaVlXTnpaWFF3TWk0d01B",
"Name": "Dr. Anjali Mehta",
"Mobile": "9876500001",
"Email": "dr.anjali@clinic.com",
"Address": "Clinic Road",
"City": "Mumbai",
"StateID": "Q2ZQdGhSZVhBaVlXTnpaWFF5TWk0d01B",
"CountryID": "Q2ZQdGhSZVhBaVlXTnpaWFF5T0M0d01B",
"ZipCode": "400001",
"Remarks": null,
"IsActive": true
}