Invoices – OptoSoft API

List GST invoices with paging and filters, pull the invoice-ready data for a sales order, and post a complete invoice back to OptoSoft.

6 endpoints in this module. Every request needs a JWT bearer token — see Authentication.

JWT bearer auth JSON request & response 85 documented endpoints Reviewed monthly

Invoices

An invoice is the GST tax document raised against a sales order. These six endpoints let you list invoices, discover which orders are still awaiting invoicing, pull the invoice-ready data for an order, and post a completed invoice back to OptoSoft.

In an optical store the order and the invoice are usually separated in time: the order is taken (often with an advance), the lenses are fitted, and the invoice is raised on delivery. That is why get-invoice-data-by-salesorder exists — it hands you a pre-filled invoice built from the order, which you complete and post back.

Indian GST split. Whether tax lands as CGST + SGST (intra-state) or IGST (inter-state) is decided by the customer’s stateID against the branch state. Set the customer’s state correctly on customer upsert and OptoSoft computes the split for you.

Listing invoices

POST /api/Invoice/List Bearer token

Returns a paged, filtered list of invoices. This is the endpoint an accounting integration polls to pull sales into Tally, Zoho Books or a GST return workflow. Paging uses the fromPage / toPage row-range style.

Request body

FieldTypeRequiredDescription
companyIDint64RequiredCompany (tenant).
branchIDint64RequiredStore.
yearIDint64RequiredFinancial year — the GST return period you are reconciling.
invoiceNumberstringOptionalInvoice number, exact or partial.
salesOrderNostringOptionalFind the invoice raised against a given order.
customerIDstringOptionalEncrypted customer ID.
customerNamestringOptionalPartial match on customer name.
customerMobilestringOptionalCustomer mobile number.
fromDatestringOptionalStart of the invoice-date range.
toDatestringOptionalEnd of the invoice-date range.
amountstringOptionalGross amount filter.
netAmountstringOptionalNet amount filter.
totalRowsstringOptionalEcho field used by the OptoSoft grid. Leave unset.
orderBystringOptionalSort column, optionally with DESC.
fromPageint32OptionalFirst row of the range.
toPageint32OptionalLast row of the range.

Example request

curl -X POST https://api.opto-soft.com/api/Invoice/List \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "companyID": 18,
    "branchID": 24,
    "yearID": 9,
    "fromDate": "2026-07-01",
    "toDate": "2026-07-31",
    "fromPage": 1,
    "toPage": 50,
    "orderBy": "Date DESC"
  }'

Response

FieldTypeDescription
totalRowsint32Total matching invoices, before paging.
data[].idstringEncrypted invoice ID. Use this on follow-up calls.
data[].plainIdint64Numeric invoice ID, for your own reconciliation only.
data[].invoiceNostringInvoice number as printed.
data[].salesOrderNostringOriginating order number.
data[].customerNamestringCustomer name.
data[].customerMobileNostringCustomer mobile number.
data[].datedate-timeInvoice date.
data[].netAmountdoubleInvoice value including GST.

Example response

{
  "totalRows": 132,
  "data": [
    {
      "id": "ENCRYPTED_INVOICE_ID",
      "plainId": 55219,
      "invoiceNo": "INV/2026/000913",
      "salesOrderNo": "SO/2026/001842",
      "customerName": "Anita Shah",
      "customerMobileNo": "9876543210",
      "date": "2026-07-24T16:05:00",
      "netAmount": 8450.00
    }
  ]
}

Errors

StatusCause
400Missing scoping field, or an unparseable date.
401Token missing or expired.

Preparing a new invoice

GET /api/Invoice/get-customers-for-invoice Bearer token

Lists customers who currently have at least one order awaiting invoicing. Step one of the "raise an invoice" workflow — it narrows a large customer register down to just those with pending work.

Query parameters

None. Scope comes from the bearer token.

Example request

curl https://api.opto-soft.com/api/Invoice/get-customers-for-invoice \
  -H "Authorization: Bearer YOUR_TOKEN"
GET /api/Invoice/get-sales-orders-for-invoice Bearer token

For a chosen customer, lists their orders that are ready to be invoiced. Step two of the workflow.

Query parameters

NameTypeRequiredDescription
customerIdstringRequiredEncrypted customer ID from the previous call.

Example request

curl "https://api.opto-soft.com/api/Invoice/get-sales-orders-for-invoice?customerId=ENCRYPTED_CUSTOMER_ID" \
  -H "Authorization: Bearer YOUR_TOKEN"
POST /api/Invoice/GetOrdersForNewInvoice Bearer token

Returns every order in the given company, branch and year that is still awaiting an invoice — the branch-wide view, rather than the per-customer view above. Use it to build a "pending invoicing" worklist.

Request body

FieldTypeRequiredDescription
companyIDint64RequiredCompany (tenant).
branchIDint64RequiredStore.
yearIDint64RequiredFinancial year.

Example request

curl -X POST https://api.opto-soft.com/api/Invoice/GetOrdersForNewInvoice \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "companyID": 18, "branchID": 24, "yearID": 9 }'
GET /api/Invoice/get-invoice-data-by-salesorder Bearer token

The key endpoint of this module. Given a sales order, it returns a fully populated invoice draft — customer, line items, GST breakdown and totals — ready to be reviewed and posted back via save-invoice-data.

Query parameters

NameTypeRequiredDescription
salesOrderIdstringRequiredEncrypted sales order ID.

Example request

curl "https://api.opto-soft.com/api/Invoice/get-invoice-data-by-salesorder?salesOrderId=ENCRYPTED_SALES_ORDER_ID" \
  -H "Authorization: Bearer YOUR_TOKEN"

The response is an OMFastWizardModel — the same composite object used by Quick Sale. Round-trip it: take the returned object, adjust only what you need, and post it to save-invoice-data. Do not attempt to build one from scratch.

Saving an invoice

POST /api/Invoice/save-invoice-data Bearer token

Commits an invoice. The request body is the full composite OMFastWizardModel (94 top-level properties, most of them nested objects and UI display flags).

Top-level structure

FieldTypeDescription
customerModelobjectThe customer the invoice is raised against.
salesorderModelobjectThe order being invoiced, with its line items.
receiptModelobjectPayment taken at the time of invoicing, if any.
eyeInfoModelobjectThe prescription dispensed against this invoice.
eyecheckupRecallModelobjectNext eye-test recall to schedule for the customer.
purchaseOrderModelobjectLinked lab or supplier purchase order.
autoItemTypeSectionListarrayItem-type sections shown in the OptoSoft wizard.
sessionIDstringCart session ID, when the invoice is built from a Quick Sale session.
orderDatedate-timeOrder date.
expectedDatedate-timeExpected delivery date.
supplierIDstringEncrypted supplier ID for lab work.
fitterIDstringEncrypted fitter ID.
priorityIDstringEncrypted job-priority ID.
isLensAddedbooleanWhether a lens line is present.
isSpectacleLensInOrderbooleanWhether a spectacle lens is on the order.
isExternalbooleanMarks an externally originated transaction.
userIdint64Operator recording the invoice.
branchCitystringBranch city, printed on the invoice.
visitorIPstringClient IP recorded for audit.
showQuickSaleAdd…SectionbooleanRoughly 60 display flags controlling OptoSoft wizard sections (frames, sunglasses, lenses, contact lenses, accessories and so on). Preserve whatever the GET returned; they do not affect the saved invoice.

Always round-trip this model. Call get-invoice-data-by-salesorder first, modify only the fields you need to change, and post the whole object back. Constructing an OMFastWizardModel by hand is not supported and will produce incorrect tax totals.

Example flow

# 1. Pull the pre-filled invoice draft for the order
curl "https://api.opto-soft.com/api/Invoice/get-invoice-data-by-salesorder?salesOrderId=ENCRYPTED_SALES_ORDER_ID" \
  -H "Authorization: Bearer YOUR_TOKEN" -o draft.json

# 2. Adjust draft.json as needed (dates, payment, remarks)

# 3. Post it back to commit the invoice
curl -X POST https://api.opto-soft.com/api/Invoice/save-invoice-data \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  --data-binary @draft.json

Inspect the response body before treating the invoice as saved. A 200 here confirms the request was accepted, not necessarily that a document number was allocated.

Printing

Rendered invoice PDFs and print-ready HTML come from the catalog module — see Catalog & Master Data for /api/Common/invoice/pdf and /api/Common/invoice/pdf/html.

Chat with us Call us