DMS integration
This guide is for distributor management system (DMS) teams. It covers how to send documents to Mikono, the update flags Mikono returns, the reason codes, duplicate document numbers, and what is planned: SFTP transfer and the daily reconciliation.
Mikono follows your format
The payloads, the transport, the flag format and the reason codes belong to the DMS owner. Mikono maps to them; you do not change your system for Mikono. Where your standard defines one of these, it replaces what this guide proposes, and only the mapping on Mikono’s side changes.
The pattern is the one you already run: the DMS sends its documents to Mikono, Mikono posts them, and Mikono returns an update flag for every document. Mikono also has its own JSON document format, called canonical, for partners without a standard of their own.
In the paths below, {system} is the DMS’s name on the connection. Today that is canonical; edge365 is planned: the EDGE 365 format is not mapped yet, so documents must use the canonical form for now. The document names in the tables below are EDGE 365’s, each mapped to its canonical document type. Each connection is set up for one distributor code; documents for any other distributor code are rejected with R07.
Ways to send documents
JSON push
POST /api/v1/dms/{system}/documentstakes one document or a batch of up to 500. It needs thedms:ingestscope and anIdempotency-Key.- The response comes at once, with a
receivedorrejectedflag for each document after the format checks. Posting follows within seconds, and thepostedorrejectedflag comes back through your return path (below). - If your standard expects the final flags in the response itself, the connection can run in synchronous mode: Mikono posts before it answers, up to 50 documents per call.
curl -s -X POST "$BASE/dms/{system}/documents" \
-H "Authorization: Bearer $KEY" \
-H "Idempotency-Key: 2026-10-02-KBDVSM001-batch-07" \
-H "Content-Type: application/json" \
-d @documents.jsonXML files
POST /api/v1/dms/{system}/filestakes the file as the body (application/xml) or as one file inmultipart/form-data.- Mikono stores the file, registers it as a batch and parses it. A file with the same SHA-256 checksum as one already received is not processed again.
- The flags come back as one XML flag file per batch, at
GET /api/v1/dms/{system}/files/{batchId}/flags. Delivery of flag files to an SFTPoutbound/folder is planned.
curl -s -X POST "$BASE/dms/{system}/files" \
-H "Authorization: Bearer $KEY" \
-H "Idempotency-Key: invoices-2026-10-02-0700.xml" \
-H "Content-Type: application/xml" \
--data-binary @invoices-2026-10-02-0700.xmlScheduled SFTP transfer by your agent (planned)
Planned, not built yet. There is no SFTP host today; send files with the XML file call above. When it is built, it will work as follows.
- Mikono will provide an SFTP location with five folders per connection:
inbound/,processing/,processed/,rejected/andoutbound/. Your agent will upload files toinbound/. - Mikono will check
inbound/every 5 minutes. Each new file will move toprocessing/, be posted, and move toprocessed/. Its flag file will be written tooutbound/for your agent to collect. - A file that cannot be read will move to
rejected/, with a flag file naming the reason. No file will be deleted without a trace. - Each distributor will have its own SSH key, rotated on request, and your agent’s IP addresses will be allowlisted.
- If no file has arrived by the connection’s cut-off time plus one hour, the distributor’s administrators will be alerted.
Documents Mikono receives
| DMS document | Number | What Mikono does |
|---|---|---|
| Customer | UG and 7 digits | Creates or updates the outlet by its outlet code. |
| Product | 6 digits | Creates or updates the product by its code. Empties are products. |
| Price, price group | — | Sets the price per price group and unit. |
| Salesman, route plan | Route code | Sets the route, the salesman code and the journey plan. |
| Warehouse, van | M, D, V_ and route, -G or -B | Matches the Mikono warehouse or van. |
| Reason codes | OG01, CP01 … | Looks up the reason on stock and cheque documents. |
| Van Replenishment | VR and 6 digits | Transfers stock from the main warehouse to the van. |
| Van Stock Out | VU and route | Transfers stock from the van back to the main warehouse or to damages. |
| Invoice | CS, route and 6 digits | Posts the invoice with its selling, free issue and empties lines, and moves stock off the van. |
| Return | RT and route | Posts the return, moves stock back to the van and, where money moves, creates a credit note. |
| Credit Note | — | Posts the credit note. A Cancelled status reverses it, unless QuickBooks already holds the credit memo (see Reversals). |
| Customer Collection | PY and route | Records the payment and allocates it to CS invoices by their numbers. |
| Cheque Processing | — | Clears the cheque, or reverses the payment when it bounced (CP01, CP02), unless QuickBooks already holds the payment (see Reversals). |
| Route Settlement | One per salesman per day | Closes the salesman's day: compares cash handed in, credit and closing stock with what Mikono posted, closes the cash session and books any cash difference. Waits (R08) for a listed document that has not posted yet. |
| Company Invoice | 95508… | Posts the supplier bill and receives the goods when received and invoiced quantities agree. If they differ, R09: record the receipt and the supplier claim by hand. |
| Stock Adjustment | IJ and 6 digits | Posts the stock adjustment. |
| Inventory Summary | — | Writes nothing. Compares with Mikono’s stock per warehouse and lists the differences. |
| Daily totals per salesman | — | Writes nothing. Used by the daily reconciliation for that salesman and day. |
| Fiscal status | — | Planned. Stored and flagged received; not posted yet. |
A document type without a mapping in Mikono stays received, with the note No mapper for <type> yet, until its mapping is built.
Where money or stock moves and the distributor has a QuickBooks connection, Mikono also posts the document to its QuickBooks company, in the same way as a document entered in Mikono.
Reversals
- A cancelled credit note or a bounced cheque is reversed automatically only when QuickBooks does not hold the credit memo or payment.
- A new version of a document, such as a Cancelled credit note, whose previous version is still waiting for its QuickBooks posting is held: it stays
receivedwith the noteWaiting for the previous version's QuickBooks postinguntil that posting has an outcome. It is not retried asR08and is not rejected automatically, however long the wait. If QuickBooks posts the previous version, the new version is processed against it; if that posting fails, the new version is processed as if the previous version never reached QuickBooks. Mikono stops checking a QuickBooks posting after 48 hours; the new version then stays held until someone in Mikono checks the QuickBooks posting log and re-processes it, which checks the posting again. - A reversal of another document, such as a bounced cheque against a collection, waits with
R08while that document's QuickBooks posting is still pending: it is retried for 48 hours, then rejected withR08. - Once QuickBooks holds the posting, Mikono cannot void it there yet: the document is rejected with
R09, nothing is reversed, and the text says what to void by hand, first in QuickBooks, then in Mikono.
When the distributor’s organisation is connected to EFRIS, Mikono submits every DMS invoice and every DMS credit note against an invoice (including the credit note of a return) to URA. This is the default for a DMS connection. If the DMS already fiscalises its documents, the distributor turns off “Fiscalise DMS documents with EFRIS (URA)” on the connection, and Mikono then neither queues nor fiscalises that connection’s documents, so nothing is fiscalised twice.
EFRIS submission runs after posting and does not hold the flag: a document is flagged posted without waiting for URA. Its fiscal status, and the FDN once URA issues it, are in the invoice’s or credit note’s fiscal block in the API. A credit note that URA may already hold cannot be cancelled from the DMS; the cancellation is rejected with R09 and nothing changes in Mikono.
While EFRIS applies, Mikono rejects with R09, before posting anything, a document URA could not accept: a credit note against an invoice that carries only an amount, or credits a product that is not on exactly one line of that invoice, and a cash sale paid by card or another method EFRIS cannot record yet (cash and mobile money are supported; send the sale on credit and the payment as a collection). Turning the switch off also cancels the connection’s documents that are still waiting to go to URA.
Update flags
| Flag | Meaning | Fields |
|---|---|---|
received | Stored and passed the format checks. Until it posts, it can carry a note, such as Waiting for QuickBooks. | documentId, distributorCode, documentType, documentNumber, receivedAt, updatedAt, and note when there is one |
posted | Posted in Mikono and, where money or stock moves and QuickBooks applies, in QuickBooks. quickbooksRef is null when the document has no QuickBooks posting, for example when the distributor has no QuickBooks connection. | As received, plus mikonoRef, quickbooksRef, postedAt |
rejected | Not posted, with a reason code. If the QuickBooks posting fails after Mikono applied the document, it is rejected with R06 or R09 and the Mikono posting stays: it is not reversed. | As received, plus reasonCode, reasonText |
superseded | An earlier version, replaced when the same document arrived again with another DMS status, such as Confirmed to Cancelled. The new version carries the current flag. | As received |
- A document is
postedonly when its QuickBooks posting succeeded, or when it has no QuickBooks effect. A failed QuickBooks posting turns intorejectedwithR06orR09and QuickBooks’ reason in the text. The document stays applied in Mikono. - The current version of a document ends
postedorrejectedwith a reason; earlier versions endsuperseded. A document waiting for a code or document Mikono has not received yet staysreceivedwith anoteand is retried for 48 hours before it is rejected withR08. A new version held for its previous version's QuickBooks posting staysreceiveduntil that posting has an outcome and is not rejected automatically. A document type Mikono does not map yet staysreceived. A rejected document can be processed again once its cause is fixed in Mikono, and gets a new flag.
[
{
"documentId": "k57a2b3c4d5e6f7g8h9j0k1m2n3p4q5r",
"distributorCode": "KBD001",
"documentType": "sale_invoice",
"documentNumber": "CSKBDVSM001000123",
"state": "posted",
"mikonoRef": { "table": "invoices", "id": "kd7…" },
"quickbooksRef": "1043",
"receivedAt": "2026-10-02T07:15:02.000Z",
"postedAt": "2026-10-02T07:15:09.000Z",
"updatedAt": "2026-10-02T07:15:09.000Z"
},
{
"documentId": "k57a2b3c4d5e6f7g8h9j0k1m2n3p4q5t",
"distributorCode": "KBD001",
"documentType": "sale_invoice",
"documentNumber": "CSKBDVSM001000125",
"state": "received",
"note": "Product 780999 is not known yet",
"receivedAt": "2026-10-02T07:15:02.000Z",
"updatedAt": "2026-10-02T07:15:03.000Z"
},
{
"documentId": "k57a2b3c4d5e6f7g8h9j0k1m2n3p4q5s",
"distributorCode": "KBD001",
"documentType": "sale_invoice",
"documentNumber": "CSKBDVSM001000124",
"state": "rejected",
"reasonCode": "R08",
"reasonText": "Product 780999 is not known yet",
"receivedAt": "2026-09-30T07:15:02.000Z",
"updatedAt": "2026-10-02T07:20:11.000Z"
}
]Flags come back by one of three return paths, set on the connection:
- in the response to your call;
- as a call from Mikono to your endpoint, retried on failure like a webhook;
- as a flag file per XML batch, read with
GET /api/v1/dms/{system}/files/{batchId}/flags. Delivery of flag files to an SFTPoutbound/folder is planned.
You can also pull flags at any time with GET /api/v1/dms/{system}/flags?since=&state=, which needs the dms:flags:read scope. Every flag is also sent as the dms.document.flagged webhook.
curl -s "$BASE/dms/{system}/flags?since=2026-10-02T00:00:00Z&state=rejected" \
-H "Authorization: Bearer $KEY"Reason codes
Mikono proposes these codes. If your standard has its own reason codes, Mikono uses yours.
| Code | Reason |
|---|---|
R01 | The document names no customer code. A customer code Mikono does not know yet is R08, not R01. |
R02 | Reserved. Mikono does not send it: an unknown product code is held as R08. |
R03 | Something is not set up in Mikono: a DMS location record that matches no Mikono location; a linked location that is inactive in Mikono; no damages location for bad stock; a sale or return with no location and no salesman; a salesman not linked to a Mikono user; no organisation cash account; no default sales or promotions expense account; a product without a pack size, or one that does not track stock; or no vendor for a supplier invoice. Fix the set-up, then re-process the document. A route or location a document refers to that is not received or linked yet is R08, not R03. |
R04 | Lines do not add up to the document total. |
R05 | The same document number was already received with different content and the same DMS status. Nothing is posted, and the document cannot be re-processed: send a status change or a new number. |
R06 | The accounting period is closed: in Mikono (before posting) or in QuickBooks (when posting). The reason text names which. |
R07 | Document for another distributor code. |
R08 | Depends on something Mikono has not received yet: a customer or product code it does not know, an invoice that a collection, credit note or return refers to, a customer's route not received yet, a location code on a stock, sale or transfer document not linked to a Mikono location yet, customers a route plan names that are not received yet, stock not yet on the van, or the QuickBooks posting of another document that a reversal, such as a bounced cheque, must wait for. The document stays received, with the reason in its note, and is retried for 48 hours. If it still cannot post, it is rejected with R08 and the same text. A new version of a document whose previous version is still waiting for its QuickBooks posting is not R08: it is held, and is not rejected automatically (see Reversals). |
R09 | Other. The reason is in the text. |
Duplicate document numbers
Each document is identified by a natural key, by default the distributor code, the document type and the document number. The key is kept for good, not only for the 24 hours of an Idempotency-Key.
| Mikono receives | What happens |
|---|---|
| The same key with the same content | The existing flag is returned. Nothing is posted again. This is a normal resend. |
| The same key with different content and a changed DMS status, such as Confirmed to Cancelled, or a cheque from Open to Bounced | The earlier posting is reversed or updated and the document is flagged again. The earlier version is kept as superseded. |
| The same key with different content and the same status | Rejected with R05. Nothing is posted. |
The natural key can be set per document type, because some document numbers repeat. In one distributor’s back office, every empties return carried the same number, such as RTKBDVSM001000001, on different dates and for different outlets. For returns the key is therefore the distributor code, RT, the document number, the document date, the customer code and a fingerprint of the lines. Those three returns are received as three returns. Which fields make a return unique is your decision; Mikono changes the key to match.
Files are also checked by checksum, and API calls by Idempotency-Key, so a resent batch never posts twice.
Daily reconciliation
After the connection’s cut-off time, Mikono reconciles each salesman’s day. For each salesman code and business date it counts and totals each document type: received, posted, rejected and still pending. It compares these with your daily totals document where you send one, or with the Route Settlement.
- The result is kept per salesman and day, with each difference: a document you list that never arrived, one that arrived and did not post, one Mikono posted that you do not list, a count or value per type that the listed documents do not explain, and the Route Settlement’s cash, credit and stock differences.
- Missing and unexpected documents are named only when the document used for the comparison (your daily totals, or otherwise the Route Settlement) lists their numbers. Without that list, Mikono compares counts and values and still names the documents it received that did not post.
- Mikono sends the
dms.reconciliation.completedwebhook when a day’s result changes. A reconciliation file or flag in your format can be added if your standard has one. - When a day’s result changes and has differences, Mikono sends an in-app notification to the distributor’s members who manage settings, and to its owner.
- A late document refreshes its day’s result, and the last three days are checked again.