DSO calculator
See how long cash stays tied up after a sale on account: 40000 of receivables against 365000 of annual credit sales is a DSO of 40 days. Average daily credit sales and receivables turnover come with it. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Accounts receivable
- 40,000
- Credit sales
- 365,000
- Days
- 365
- Days sales outstanding
- 40
- Average daily credit sales
- 1,000
- Receivables turnover
- 9.125
Days sales outstanding, or DSO, is the working-capital identity that turns an accounts-receivable balance and a period of credit sales into a collection lag measured in days. Given receivables, total credit sales, and the length of the period, DSO equals receivables divided by credit sales, times the number of days. Controllers, credit managers, and students look up this number whenever they need to see how long cash stays tied up after a sale on account. This days sales outstanding calculator accepts those three inputs, applies the identity, and returns the collection period in days together with average daily credit sales and the implied receivables turnover.
What days sales outstanding means and how receivables over credit sales become a day count
Days sales outstanding measures how many days, on average, a firm's credit customers take to pay after a sale on account. Algebraically it is accounts receivable divided by total credit sales for the period, multiplied by the number of days in that period. The same identity is receivables divided by average daily credit sales, which is credit sales over days; both forms return the same collection lag.
DSO is a flow-versus-stock conversion, not a forecast of a single invoice and not an aging schedule. A lower figure means cash returns faster; a higher figure means more working capital sits in trade receivables. Compare DSO with the stated terms: if invoices are Net 30 and DSO sits near forty-five, collections are late on average even if every invoice looks current on the day it is issued.
The period length you send must match the sales window — annual credit sales with three hundred sixty-five or three hundred sixty days, a quarter with ninety, a month with thirty or the actual calendar days of that month. Use average receivables, beginning plus ending over two, when you want a period-average DSO, or period-end receivables for a snapshot against that period's sales.
Credit sales must be a finite number strictly greater than zero; a zero sales total cannot be the denominator and is rejected instead of inventing a collection period. Accounts receivable may be zero, which yields a DSO of zero because nothing is left to collect. Numeric outputs use half-up rounding so goldens compare byte-for-byte across runtimes.
What to enter and what you get back
Optional decimals is an integer from zero through twelve, default six, controlling half-up rounding on the numeric outputs. A formula string restates DSO equals accounts receivable over credit sales times days. Example: forty thousand of receivables, three hundred sixty-five thousand of credit sales, and three hundred sixty-five days returns a DSO of forty, average daily credit sales of one thousand, and a turnover of nine point one two five.
Credit sales is the field the product contract singles out: a zero sales total is never silently replaced with cash sales, net revenue, or one, and a missing sales figure is not treated as zero. Failed validation does not consume balance, which keeps exploratory scripts cheap when developers intentionally send a zero credit-sales total to confirm the error path.
What you can do with it
Credit terms versus actual collection lag
Turn period-end or average receivables, credit sales, and period days into DSO and compare the day count with stated Net 30 or Net 60 terms.
Classroom DSO homework and LMS keys
Mark problems that ask students to compute DSO as (accounts receivable / credit sales) × days, including annual 365-day and quarterly 90-day windows.
FAQ
How is days sales outstanding calculated?
Send a non-negative receivable balance, a positive credit-sales total for the same window, and the length of that window in days. Forty thousand of receivables against three hundred sixty-five thousand of annual credit sales is a DSO of forty days.
What does a high or low DSO mean?
A lower DSO means customers pay faster and less cash sits in receivables. A higher DSO means a longer collection lag. Compare the result with your stated terms: a DSO well above Net 30 is a collections problem even if the ledger still looks current.
What happens if credit sales is zero?
Days sales outstanding divides accounts receivable by credit sales, so a zero credit-sales total is not a valid denominator.
Should I use 365, 360, or 90 for days?
Match days to the sales window you send. Use 365 or 360 with annual credit sales, 90 with a quarter, and 30 or the calendar days of the month with monthly sales. Mixing annual sales with a 90-day factor inflates DSO.
How do I compare DSO with my payment terms?
Set the DSO next to the terms on your invoices. If you invoice at Net 30 and DSO sits near forty-five, customers are paying late on average, even if every invoice looked current on the day it was issued.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/fin/days-sales-outstanding \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"accounts_receivable":40000,"credit_sales":365000,"days":365}'const res = await fetch("https://api.kit.forhosting.com/fin/days-sales-outstanding", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"accounts_receivable": 40000,
"credit_sales": 365000,
"days": 365
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/fin/days-sales-outstanding",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"accounts_receivable": 40000,
"credit_sales": 365000,
"days": 365
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/fin/days-sales-outstanding", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"accounts_receivable":40000,"credit_sales":365000,"days":365}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"accounts_receivable":40000,"credit_sales":365000,"days":365}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/fin/days-sales-outstanding", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"accounts_receivable": 40000,
"credit_sales": 365000,
"days": 365
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "fin.days_sales_outstanding",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
A credit-sales figure of zero fails with invalid_input instead of dividing by zero.
What days sales outstanding means and how receivables over credit sales become a day count
A company that holds forty thousand of receivables against three hundred sixty-five thousand of credit sales over a three-hundred-sixty-five-day year has a DSO of forty thousand over three hundred sixty-five thousand times three hundred sixty-five, which is exactly forty days: average daily credit sales of one thousand, and forty days of sales sitting in the ledger. This endpoint does not fetch ledger balances, aging buckets, or payment-term calendars; it applies the identity you supply so homework keys, landing-page widgets, and automation share one auditable day count.
Input contract, response shape, and error behaviour
POST a JSON body with three required finite numbers. accounts_receivable (aliases ar, receivables, accounts_receivable_balance, ending_receivables, and average_receivables) is the receivable stock in currency units for the same window as the sales figure; it must be finite and greater than or equal to zero. credit_sales (aliases total_credit_sales, net_credit_sales, sales, credit_sales_total, and net_sales) is the period's credit sales in the same currency and must be a finite number strictly greater than zero. days (aliases days_in_period, period_days, n, and period) is the length of that sales window in days and must be a finite number strictly greater than zero. On success the body echoes the three inputs, then days_sales_outstanding as the collection period in days, average_daily_credit_sales as credit sales over days, and — when receivables are positive — receivables_turnover as credit sales over receivables. Missing fields, non-finite values, a negative receivable balance, a zero or negative period length, or a credit-sales total that is zero or negative fail with invalid_input naming the field and are not billed. Prefer plain JSON numbers over strings with currency symbols or thousand separators; numeric strings are accepted only when they match a strict finite number pattern without commas or labels. Pricing is a fixed $0.002 per successful call with unit item.
Where a days sales outstanding calculator earns its keep
Educators and LMS platforms need an oracle for the definition question that asks students to compute DSO as receivables over credit sales times days, including the quarterly case with ninety days and the annual case with three hundred sixty-five, without a full ERP extract. Content teams can contrast DSO with receivables turnover and with days payable outstanding so readers see why a short collection lag still fails to fund a longer payables cycle, and why cash conversion cycle needs all three legs. Use this capability when you already have receivables, credit sales, and a matching day count; if you have only cash collections by aging bucket and want a weighted collection curve, that is a different identity and does not belong in this DSO definition. Treasury and FP&A files often store ending receivables and period sales in separate columns; a deterministic endpoint recovers DSO without a spreadsheet cell that someone might later rewrite as turnover by dropping the days multiplier. Integrators wire the endpoint into notebooks, workflow tools, or edge workers to pin goldens whenever a close package changes the stored receivable stock or the credit-sales total. Keep credit_sales strictly positive, pin the rounded days_sales_outstanding field in tests, and you get reproducible collection periods for widgets, classrooms, and production without standing up a working-capital library of your own.
Integration use cases
Working-capital close packages
Recover days_sales_outstanding from receivable and credit-sales columns without accidentally dropping the days multiplier (that would be turnover, not DSO).
Technical questions
What does the days sales outstanding calculator cost?
The browser tool is free. API requests use prepaid KIT balance at $0.002 per successful call; invalid input is not billed.