Get distributor sell-out in without retyping it.
Distributors send sell-out and stock by API push, the upload API or email. Every file is checked, stamped with where it came from, and kept as received.
POST /v1/ingest/sales
x-api-key: ••••••••••••3f9a
content-type: application/json
{
"distributorId": "DIST-NYC-01",
"data": [
{ "invoiceDate": "21/10/2026", "outletName": "Hudson Medical Pharmacy",
"sku": "CRD-10", "qty": 36, "netValue": 16200 },
...
]
} 202 Accepted
{
"message": "Accepted",
"uploadId": "b7f3c21e-41d0-4c8a-9e62-0f5d1a7e2b90"
} The account and distributor come from the key itself. A key pinned to one distributor cannot write for another.
POST /v1/sales/uploads/presign
authorization: Bearer ••••
{
"distributorId": "DIST-NYC-01",
"fileType": "stock"
} 200 OK
{
"url": "https://…",
"fields": {
"key": "raw/…/DIST-NYC-01/61d2aa90….csv",
"Content-Type": "text/csv",
"x-amz-meta-distributorid": "DIST-NYC-01",
"x-amz-meta-filetype": "stock",
…
}
} A signed upload slot for one CSV that expires in 15 minutes. The server sets the file key, so the caller never chooses where the file lands.
| Batch | Period | Type | Status |
|---|---|---|---|
| b7f3c21e | 2026-10 | sales | received |
| 61d2aa90 | 2026-10 | stock | projected |
| f09e44b3 | 2026-09 | sales | projected |
| 2c7b8e15 | 2026-09 | sales | rejected |
| d4a1937c | 2026-08 | sales | projected |
Unmatched rows never enter a territory rollup, so they are missing from every figure above.
Distributor codes mapped to a catalog product. An unmapped code sells but cannot be attributed to a product.
Outlets under this distributor's partition that resolve to a territory.
Three ways in, all checked the same way.
A distributor's system can push rows as JSON to the ingest endpoint with an API key. The key decides the account, and a key pinned to one distributor can only write that distributor's data, whatever the request says.
For files, the upload API issues a signed link for one sales or stock CSV. The link expires after 15 minutes and the server decides where the file is stored, so a caller can never write over another file. Distributors without an integration can email their CSV from a registered sender address.
Checked against the distributor's own format.
Each distributor has a mapping that names its columns and date formats. Rows are read with that mapping, numbers in local formats such as "1,234.50" or "(500)" are understood, and dates are parsed by the format you set, never guessed.
A row that cannot be read is set aside with a reason code instead of being loaded as a zero. A batch for a closed period is refused whole.
You can always see where a number came from.
Every batch is stamped with the distributor, the file type, the mapping it ran under and who or what sent it. The file is kept exactly as received, and the cleaned version is written next to it before anything reaches your reports.
Batches appear on the distributor's page in the console with their period, type and status, so "did the file arrive" has an answer.
Questions people ask.
How do distributors send us data?
What happens to a bad row?
Can one distributor's key send data for another?
Is the original file kept?
Works well with.
Email ingest
Registered distributor senders email a CSV to Dexor. Unknown or spoofed senders are dropped, and every file is checked line by line before import.
Read moreData quality workbench
Match rate, rejected rows by reason and duplicate outlets for each distributor, on one screen, linked straight to the match queue.
Read moreNet sales rollups
Secondary sales net of returns, per distributor and territory, with a SKU breakdown. Figures still landing are marked provisional, never shown short.
Read moreSee it on your own team.
Tell us your fleet and we will size a proposal. Complete roll-out may take up to 4 months, counted from signed requirements and first payment.