BUSY

BUSY integrates by acting as a web server on port 981: nine service codes over HTTP GET, credentials and XML in headers, plus raw SQL read access.

BUSY is an Indian accounting, GST billing and inventory package from BUSY Infotech Pvt. Ltd., founded in New Delhi in 1997 and used, by the vendor's own count, by more than 600,000 businesses. It is one of the two dominant desktop accounting products in the Indian MSME market alongside Tally, and in any small or mid-sized Indian retailer or distributor that runs BUSY it is the system of record for sale invoices, purchase bills, the item master, stock and the customer ledger. It also has a Middle East presence, sold there since 2008.

BUSY does not publish developer documentation on its website. It does, however, have a well defined integration interface, documented by the vendor in a partner document called "Integration using BUSY as Web Service", and it is unusual in shape: the BUSY desktop application itself becomes an HTTP server on the local machine, and everything is done with HTTP GET requests whose parameters, including the entire XML document being written, are carried in request headers.

At a glance

Warning

Two constraints decide whether this connector is viable at all. First, the BUSY application must be running and the target company must be logged in on that machine for the listener to answer. This is not a server API, it is an automation hook into a running desktop session. Second, the entire voucher XML is sent in an HTTP request header, and web servers, proxies and HTTP client libraries impose header size limits, commonly 8 KB to 16 KB in total. A sale invoice with many lines, batch details or serial numbers will exceed that. Test with your largest realistic document before committing.

What it is

BUSY Infotech is led by managing director Brijesh Kumar Agrawal and employs over 350 people across India. The product is sold in editions: Start, Smart, Power and Power+, with Power+ covering multiple users and multiple companies. Adjacent products are the BUSY mobile app, BUSY Online for cloud access, BUSY Recom for e-commerce reconciliation and a variant for commission agents in agricultural markets. The core product remains a Windows desktop application over a local database, and its strengths are GST compliance, e-invoicing against the government invoice registration portal, e-way bills and GSTR reconciliation.

That matters for integration planning. BUSY's own FAQ, under third party services, answers the question "Is API access available for BUSY?" with: "BUSY have API integration option but it require third party aaplication also." The spelling is the vendor's. The same FAQ set directs customers to authorised channel partners for customised integration. In other words the interface exists and is supported, but BUSY does not present it as a self-serve developer product and does not staff a developer relations function.

API access

There is no signup, no console and no key. To integrate:

  1. The customer runs BUSY on a machine you can reach over the network, with the target company open and logged in.
  2. The web service listener is enabled in BUSY's configuration and listens on a port, 981 by default. BUSY's own sample code uses 985 in its live line and has 981 commented out, so the port is configurable and must be confirmed per site rather than assumed.
  3. You obtain a BUSY company user name and password with the rights you need.
  4. Your integration calls that host and port directly. There is no vendor-hosted gateway.

Supporting files referenced by the vendor document but not published alongside it:

  • "BUSY Constants.doc", which holds the numeric constants for voucher types and master types. Without it you are guessing at the type numbers. Two are confirmed from BUSY's own samples: voucher type 9 is Sale, master type 2 is Account. Ask the partner or the vendor for this file, it is a hard dependency.
  • A sample Visual Studio 2013 Windows application in Visual Basic that exercises all nine service codes.

No official SDK is published in any language, and no first-party OpenAPI or WSDL exists, which is unsurprising for a header-based GET interface.

For a cloud-hosted customer on BUSY Online, whether this interface is reachable at all is unconfirmed and should be the first question asked.

Authentication

There is no token exchange and no session. Every request carries the credentials.

  • UserName: a valid user name of the BUSY company.
  • Pwd: that user's password.

Both are plain request headers. There is no hashing, no nonce and no signature. BUSY's own Postman collection uses http://localhost:981, and one request in it uses https://103.96.251.142:982, which suggests a TLS variant on a different port exists at some sites, but the vendor document mentions only the plain listener.

Consequences to design around:

  • Never route this over an untrusted network without a tunnel. Credentials go in cleartext headers on every call.
  • There is nothing to refresh and nothing to expire, so credential rotation is a manual, per-site operation.
  • Multi-account means one host, port and credential pair per BUSY installation and per company. Keep them as separate connection records.

A read call looks like this:

GET / HTTP/1.1
Host: 192.168.0.32:981
SC: 1
Qry: Select * from Tran1 where VchType=9
UserName: a
Pwd: a

The response carries the data as XML in the body, and the outcome in response headers:

  • Result: the string T for success or F for failure.
  • Description: the error message when Result is F.

BUSY's sample code reads exactly those two response headers to decide whether the call worked. A connector must do the same, because the HTTP status code is not the signal.

Objects we can read

BUSY exposes three read service codes. Service code 1 is a general escape hatch, 8 and 9 are record fetches.

Service codes

Header names vary slightly between the vendor document and the Postman collection: the document writes VchXML and MasterXML, the collection uses VchXml and MasterXml, and the collection uses VchCode where the document says VoucherCode. HTTP header names are case-insensitive so the casing does not matter, but VchCode against VoucherCode is a real difference. Try the document's spelling first and fall back.

Orders and invoices

BUSY has no separate sales order object in the integration surface; everything is a voucher, selected by VchType. Sale is voucher type 9.

  • Fetch one: SC: 8 with VoucherCode, returning the voucher as XML.
  • Find them: SC: 1 with a SQL query. BUSY's own sample uses Select * from Tran1 where VchType=9, so Tran1 is the voucher table and VchType the discriminator. That is the practical listing and incremental-sync mechanism, since there is no list endpoint and no modified-since filter.

Order items, products, inventory, customers

All of these come back inside voucher and master XML, or through SQL. There is no per-object endpoint.

A sale voucher in BUSY's own predefined XML format, from the vendor's sample, trimmed to one line:

<Sale>
  <VchSeriesName>Main</VchSeriesName>
  <Date>01-04-2024</Date>
  <VchType>9</VchType>
  <StockUpdationDate>01-04-2024</StockUpdationDate>
  <VchNo>2/2023-24</VchNo>
  <AutoVchNo>6</AutoVchNo>
  <STPTName>Local-ItemWise</STPTName>
  <MasterName1>Customer-Amit Gupta</MasterName1>
  <MasterName2>Main Store</MasterName2>
  <TranCurName>Rs.</TranCurName>
  <BillingDetails>
    <PartyName>Customer-Amit Gupta</PartyName>
    <Address1>New Delhi</Address1>
    <Address2>India</Address2>
    <MobileNo>9992229989</MobileNo>
  </BillingDetails>
  <VchOtherInfoDetails>
    <Transport>Santosh Transport</Transport>
    <Station>Dadri</Station>
    <Narration1>NA-</Narration1>
    <GrDate>01-04-2024</GrDate>
  </VchOtherInfoDetails>
  <ItemEntries>
    <ItemDetail>
      <SrNo>1</SrNo>
      <ItemName>Acer Laptop</ItemName>
      <UnitName>Pcs.</UnitName>
      <AltUnitName>Pcs.</AltUnitName>
      <ConFactor>1</ConFactor>
      <Qty>1</Qty>
      <QtyMainUnit>1</QtyMainUnit>
      <QtyAltUnit>1</QtyAltUnit>
      <ItemTaxCategory>GST 18%</ItemTaxCategory>
      <Price>26000</Price>
      <ListPrice>26000</ListPrice>
      <ItemMRP>30000</ItemMRP>
      <Amt>30680</Amt>
      <NettAmount>25386.4</NettAmount>
      <STAmount>4680</STAmount>
      <STPercent>9</STPercent>
      <TaxBeforeSurcharge>2340</TaxBeforeSurcharge>
      <STPercent1>9</STPercent1>
      <TaxBeforeSurcharge1>2340</TaxBeforeSurcharge1>
      <MC>Main Store</MC>
      <ItemSerialNoEntries />
      <ParamStockEntries />
      <BatchEntries />
      <DiscountStructure>Simple Discount, % of Price</DiscountStructure>
    </ItemDetail>
  </ItemEntries>
  <BillSundries>
    <BSDetail>
      <SrNo>1</SrNo>
      <BSName>Discount</BSName>
      <PercentVal>2</PercentVal>
      <PercentOperatedOn>60180</PercentOperatedOn>
      <Amt>1203.6</Amt>
    </BSDetail>
  </BillSundries>
  <PendingBillDetails>
    <BillDetail>
      <MasterName1>Customer-Amit Gupta</MasterName1>
      <BillRefs>
        <Method>1</Method>
        <RefNo>1/2023-24</RefNo>
        <Date>01-04-2024</Date>
        <DueDate>01-04-2024</DueDate>
        <Value1>-58976.4</Value1>
      </BillRefs>
    </BillDetail>
  </PendingBillDetails>
</Sale>

Things worth noticing in that structure:

  • References are by name, not by id. MasterName1 is the party, MasterName2 the store, ItemName the item. That removes the id-resolution step most ERPs force on you, but it makes the integration sensitive to renames and to exact string matching.
  • STPercent and STPercent1 with TaxBeforeSurcharge and TaxBeforeSurcharge1 are the two halves of Indian intra-state GST, CGST and SGST. A single-rate assumption will be wrong.
  • Discounts sit in BillSundries at document level and in DiscountStructure at line level, not as a single number.
  • PendingBillDetails carries the bill-by-bill receivable reference, which is what makes payment matching possible later.
  • ItemSerialNoEntries, ParamStockEntries and BatchEntries are the serial, parameterised stock and batch blocks. For pharma or any batch-tracked business, these will be populated and will make the header size problem worse.
  • Dates are DD-MM-YYYY strings. StockUpdationDate is separate from Date, so stock effect and accounting effect can differ.

An account master, from the same source:

<Account>
  <Name>Hemant Bhatt</Name>
  <Alias>Hemant</Alias>
  <PrintName>Hemant Bhatt</PrintName>
  <ParentGroup>Sundry Debtors</ParentGroup>
  <BillByBillBalancing>True</BillByBillBalancing>
  <Address>
    <Address1>Model Town</Address1>
    <Address2>Delhi</Address2>
    <Mobile>8282828282</Mobile>
    <WhatsAppNo>918282828282</WhatsAppNo>
    <ITPAN>782837BN34</ITPAN>
    <GSTNo>07782837BN34224322</GSTNo>
    <CountryName>India</CountryName>
    <StateName>Delhi</StateName>
    <AreaName>---Others---</AreaName>
  </Address>
  <SupplierType>1</SupplierType>
  <PriceLevel>@</PriceLevel>
  <PriceLevelForPurc>@</PriceLevelForPurc>
  <TaxType>Others</TaxType>
  <TypeOfDealerGST>Registered</TypeOfDealerGST>
  <ReverseChargeType>Not Applicable</ReverseChargeType>
  <InputType>Section 17(5)-ITC None</InputType>
</Account>

Everything under Address, plus Name, PrintName, ITPAN and GSTNo, is PII or tax identity data. ITPAN is a permanent account number and should be treated as sensitive, not merely personal.

Shipments, returns and settlements

No shipment object and no carrier data. Transport name and station appear as free text on the voucher, nothing more. Returns are voucher types like any other, reachable once you know the constant. There is no settlement object; BUSY Recom, the vendor's e-commerce reconciliation product, is a separate paid module and is not part of this interface.

Warning

Service code 1 takes an arbitrary SQL string and runs it against the open BUSY company database. It is the only practical way to list and to sync incrementally, so a connector will use it, but understand what it is: unrestricted database access authenticated by a BUSY user name and password sent in a cleartext header. Restrict the credential, restrict the network path, log every query, and never let a query string be built from untrusted input.

Writing back: listings, price and stock

For BUSY, read this as pushing sale vouchers, purchase vouchers and stock movements in. It works, and it is the interface's main purpose.

Add a sale voucher:

GET / HTTP/1.1
Host: 192.168.0.32:981
SC: 2
VchType: 9
VchXML: <Sale><VchSeriesName>Main</VchSeriesName>...</Sale>
UserName: a
Pwd: a

On success the response body contains the new voucher code as a long integer, and the Result response header is T. Store that voucher code: it is the key for service codes 4 and 8.

Modify an existing voucher two ways:

  • SC: 3 by voucher number and series, with a ModifyKey header selecting the matching basis. The Postman collection uses ModifyKey: 3 with the comment that the voucher is matched on voucher number and voucher series. The full set of ModifyKey values is in the vendor document's table but is not legible in the copy available; get it from the vendor.
  • SC: 4 by voucher code, which is unambiguous and is what a connector should prefer.

Masters:

  • SC: 5 adds a master of the given MasterType, returning the new master code.
  • SC: 6 modifies by master code, SC: 7 modifies by master name.

Price and stock specifically:

  • Price lives on the item master and on price levels (PriceLevel on the account master). Update it through the master services, not through a dedicated price call.
  • Stock is never set directly. It changes when a voucher that affects stock is posted, which is the right behaviour for an accounting package and means a stock correction must be modelled as a stock journal or adjustment voucher type, selected by its constant.
  • There is no idempotency key. The safest guard is to write your own external reference into a voucher field and check for it with a service code 1 query before posting, because a retried SC: 2 will create a second voucher.

Batch sizes: one document per call. There is no bulk service code. Combined with the header size limit, this interface is suited to steady per-document posting, not to nightly bulk loads. For bulk work the customer's own Excel import and export in BUSY is the realistic route.

Webhooks and notifications

None. BUSY has no event subscription, no callback URL, no signature scheme and no outbound notification of any kind in this interface. The listener is passive.

Poll with service code 1. A workable pattern:

  • Keep a high water mark on the voucher table and query for rows above it, ordered, in page-sized chunks. BUSY's own sample query is Select * from Tran1 where VchType=9, so Tran1 is the table to work from. Confirm the primary key and the timestamp or modification column against the customer's actual schema before relying on either.
  • A five to fifteen minute interval is reasonable for sale vouchers on a single-site installation.
  • Remember the listener only answers while BUSY is open with the company logged in, so the connector must tolerate long windows where every call fails, typically overnight and on holidays. Build backoff and alerting around that rather than treating it as an outage.

Rate limits and pagination

No rate limit is published, and none is likely to exist, because the listener is the desktop application itself. The real limit is that machine: BUSY is serving an interactive user at the same time.

There is no pagination model. Service codes 8 and 9 return one record. Service code 1 returns the whole recordset of whatever SQL you sent, in one XML document, in one response. Pagination is therefore your responsibility, expressed in the SQL, and you should always express it, because an unbounded select * against a busy company's voucher table will return a very large XML document and may exhaust memory on either side.

Practical guidance: one request at a time per installation, bounded result sets of a few hundred rows, and an agreed quiet window with the customer for anything heavy.

Mapping to the unified model

Field names are from BUSY's own sample XML. BUSY documents are user-configurable and the field set varies with edition and configuration, so verify against a real export from the customer's company.

Gaps and open questions

  • The "BUSY Constants.doc" file is a hard dependency and was not available. Without it only voucher type 9 and master type 2 are known. Obtain it before estimating.
  • The ModifyKey value table could not be read in full from the available copy of the vendor document. Only ModifyKey: 3, matching on voucher number and series, is confirmed.
  • The vendor document carries no version number and no date, so it is unknown which BUSY releases it describes. The Postman collection samples are dated to financial year 2023-24 and 2024-25, which suggests the interface was current at least to then.
  • Whether this interface is available on BUSY Online, the cloud offering, is unknown and is the first question to ask for any cloud customer.
  • The exact maximum header size accepted by the BUSY listener is unpublished. This is the single biggest practical unknown, because it determines the largest document you can post.
  • Response body format for service code 1 is described only as "XML string of resultant recordset". The element naming and type handling were not observed.
  • Whether a TLS listener is officially supported is unclear. One sample uses https on port 982, the vendor document mentions only the plain listener.
  • Error semantics beyond Result and Description are unpublished. There is no error code list.
  • No published rate limit, no concurrency guidance and no statement about what happens if two clients call at once while a user is typing in BUSY.
  • busyaccounting.com is no longer a BUSY property, it now serves an unrelated Chinese sports site. Do not use it as a source.

Sources

  • "Integration using BUSY as Web Service", BUSY Infotech Pvt. Ltd. partner document, five pages, footer marked BIPL. Retrieved 2026-09-22 from a public mirror at github.com/yajurvendr/IISV2. Source of the port 981 behaviour, the nine service codes, the header names and the Result and Description response headers
  • BUSY's own Visual Studio 2013 Visual Basic sample application, same mirror, Form1.vb. Source of the request construction, the Select * from Tran1 where VchType=9 query and the response header handling
  • Public Postman collection "Busy API", uid 57904330-e87e80b6-9dfa-4a4e-b667-dc616c6ebdc8, retrieved 2026-09-22. Source of the full sale voucher and account master XML samples and the header spellings
  • BUSY third party services integration FAQ, read 2026-09-22. Source of the vendor statement that API integration exists but requires a third party application, and of the direction to channel partners
  • BUSY about page, read 2026-09-22. Company, founding year, user count, editions
  • BUSY home page, read 2026-09-22
  • DNS checks on 2026-09-22: api.busy.in, developer.busy.in, docs.busy.in, help.busy.in, support.busy.in and kb.busy.in do not resolve