Drypowder Help Center

Customer CSV export

Field reference for the Customers CSV export, with sources and definitions for all thirty-six columns.

The Customers CSV export gives you a snapshot of every customer account on your AR ledger, with balances, aging, adjustments, and a Collection Priority score for each one. This page documents every column in the file, where the value comes from, and the math behind the calculated fields.

You can pull this export from the Export button on the Customers Dashboard. Filters and sorting on the dashboard apply to the file, so narrow the view first if you want a focused download.

How the numbers get built

Drypowder does not compute these stats on the fly when you click Export. They are pre-computed and stored. The recomputation job runs whenever the underlying AR data changes for a dealer (a new invoice arrives from Spruce, a payment posts, a credit adjustment is issued), and it works in three steps.

  1. Read the source-of-truth tables. For each invoicing account (one row per dealer customer, identified by the dealer's ERP account number), the job streams every row representing an unpaid or partially paid invoice, an unapplied credit memo, and an unapplied debit memo. The word "outstanding" in those sources is doing a lot of work. Paid invoices, voided invoices, and fully applied credits are not in the source set, so they never enter the stats. If an invoice is partially paid, only the remaining balance is in the outstanding amount.
  2. Run an accumulator. The job walks each row, classifies it (current versus past due, which aging bucket, whether it sits on a statement, whether a statement discount is still available), and adds to running totals. The classification uses the dealer's local time zone, not UTC or the customer's time zone, so "past due" flips at midnight in the dealer's office.
  3. Persist the stats. When the accumulator is done, the totals are saved and surfaced to the CSV export, the Customers Dashboard, and the Stats Panel.

A consequence worth flagging: if a dealer's stats are stale because the recompute job is mid-run or has not yet been triggered for a specific account, the CSV will show the prior snapshot. This is rare in practice but real, and it is why the Outstanding column in the dashboard and the CSV can occasionally lag the per-invoice view by a few seconds.

Three concepts to anchor on before reading the column list

Current versus past due is decided by the invoice payment due date. An invoice with a due date of today, or any date in the future, counts as current. An invoice with a due date of yesterday or earlier counts as past due. There is no grace period built into the math. The check is daysOverdue = today − dueDate, evaluated in the dealer's time zone, and any non-positive result means the invoice is current.

Outstanding means "still owed right now." Every amount column is computed off the remaining balance on each invoice or adjustment, not the original face amount. A $10,000 invoice that has received a $7,000 partial payment contributes $3,000 to outstanding totals. A fully paid or voided invoice contributes nothing because it is no longer in the outstanding set.

Weighted average days overdue is dollar-weighted, not invoice-weighted. This is the column most likely to be misread. Drypowder is not computing the simple average of days overdue across a customer's past-due invoices. It is computing the average overdue duration weighted by dollar amount, which means one large invoice that is 60 days late will move the metric far more than ten small invoices that are 5 days late. The formula is sum(outstandingAmount × daysOverdue) / sum(outstandingAmount), restricted to past-due invoices only. If a customer has no past-due invoices the column reads zero.

Column-by-column reference

The CSV emits exactly thirty-six columns in this order. Column names are snake-case in the file.

Identity and account columns

CSV columnWhat it represents
account_idThe dealer's ERP-side account number for this customer, sometimes called the external account ID. This is what a Spruce user would recognize.
account_nameThe customer's account name as it appears in the dealer's ERP.
buyer_company_nameThe customer's company name as it appears in Drypowder. Blank if the customer has not registered for the Payments portal yet, because the buyer-company record is created at registration.
account_typeThe dealer's account classification — typically Cash, Credit, or System, but dealers can configure custom types in Spruce.
statusWhether the account is Active or Inactive in the ERP. Inactive accounts still appear in the export.
collection_priorityA 0 to 10 score that Drypowder calculates to rank which customers need attention now. See the dedicated explanation below.
invite_email_addressThe email address Drypowder last sent a portal invitation to, or blank if none has been sent.
invite_statusWhere the most recent invite stands: Pending (sent, not yet opened), Accepted, Declined, or Expired. Blank if the customer has never been invited.
invite_created_atWhen the most recent invite was first sent, ISO 8601 timestamp.
invite_updated_atWhen the most recent invite was last modified (accepted, declined, resent).

Combined outstanding rollup

These two columns are the headline number, the answer to "what does this customer owe me right now in total." They combine the outstanding invoice balance and any unapplied debit adjustments. Credit adjustments are reported separately and are not subtracted, since some dealers want to see gross AR exposure before netting credits.

CSV columnWhat it represents
outstanding_amountoutstanding_invoice_amount plus outstanding_debit_adjustment_amount. The dollar value of everything this customer has not paid.
outstanding_countThe number of outstanding documents that make up that amount, including both invoices and debit adjustments.

Outstanding invoices, by status

The next block breaks the outstanding balance down by whether each invoice is current, past due, or carries a still-available early-payment discount. Counts and dollar amounts are reported separately so the file can be pivoted either way.

CSV columnWhat it represents
outstanding_invoice_amountDollar value of every unpaid or partially paid invoice on this customer's account. Excludes debit and credit adjustments.
outstanding_invoice_countNumber of invoices that make up that amount.
current_invoice_amountDollar value of outstanding invoices whose payment due date is today or later.
current_invoice_countCount of those invoices.
discount_amountDollar value of statement or invoice discounts that this customer can still capture by paying before the discount date. Only counts current invoices whose discount date has not yet passed. If a discount window expired yesterday, it stops contributing to this column today.
discount_countNumber of invoices contributing to that discount amount.
past_due_invoice_amountDollar value of outstanding invoices whose due date is in the past.
past_due_invoice_countCount of those invoices.
past_due_invoice_weighted_average_days_overdueThe dollar-weighted average days overdue across all past-due invoices for this customer. See the formula above. Reads zero when there are no past-due invoices.

Aging buckets

The four aging buckets partition the past-due balance into the familiar 1-to-30, 31-to-60, 61-to-90, and 91-plus ranges. The buckets are mutually exclusive and exhaustive over the past-due set, which means past_due_invoice_amount should always equal the sum of the four bucket amounts. If it ever does not, that is a data integrity bug and worth a note to your Drypowder implementation lead.

Each bucket reports three columns: the amount, the count, and a bucket-local weighted average days overdue. The bucket-local weighted average uses the same dollar-weighted formula as the headline weighted average, but restricted to invoices that fall inside that one bucket. It is most useful when a customer's overall weighted average is being dragged up or down by a single large invoice and you want to see whether the older buckets are actually bad on their own.

CSV columnWhat it represents
one_to_thirty_invoice_amountDollar value of past-due invoices that are 1 to 30 days overdue.
one_to_thirty_invoice_countCount.
one_to_thirty_invoice_weighted_average_days_overdueDollar-weighted average days overdue within this bucket.
thirty_one_to_sixty_invoice_amountDollar value of past-due invoices that are 31 to 60 days overdue.
thirty_one_to_sixty_invoice_countCount.
thirty_one_to_sixty_invoice_weighted_average_days_overdueDollar-weighted average days overdue within this bucket.
sixty_one_to_ninety_invoice_amountDollar value of past-due invoices that are 61 to 90 days overdue.
sixty_one_to_ninety_invoice_countCount.
sixty_one_to_ninety_invoice_weighted_average_days_overdueDollar-weighted average days overdue within this bucket.
ninety_one_plus_invoice_amountDollar value of past-due invoices that are 91 or more days overdue.
ninety_one_plus_invoice_countCount.
ninety_one_plus_invoice_weighted_average_days_overdueDollar-weighted average days overdue within this bucket.

Credit and debit adjustments

The final four columns report the customer's unapplied adjustments. A credit adjustment is a credit memo the dealer has issued but the customer has not yet applied against an invoice, and a debit adjustment is an additional charge that has been posted to the account but has not yet been paid. Adjustments are not invoices, which is why they sit in their own columns rather than being mixed into the invoice totals.

CSV columnWhat it represents
outstanding_credit_adjustment_amountTotal dollar value of unapplied credit memos on this customer's account.
outstanding_credit_adjustment_countNumber of unapplied credit memos.
outstanding_debit_adjustment_amountTotal dollar value of unapplied debit memos on this customer's account.
outstanding_debit_adjustment_countNumber of unapplied debit memos.

How collection_priority is calculated

collection_priority is a 0 to 10 score that Drypowder uses to rank customers by collection urgency, with 10 meaning "most urgent." It is the only column in the CSV that is not a raw count, dollar amount, or identifier.

The score is a log-scaled, min-max normalized version of a single underlying signal: the dollar-weighted sum of days overdue across the customer's past-due invoices. Three implications fall out of that definition.

First, a customer with zero past-due invoices always scores zero. The score is not measuring how much they owe in total, only how much past-due exposure they represent. A customer can owe a great deal of money and score zero, provided they are paying on time.

Second, the score is relative to the dealer. Drypowder normalizes against the highest and lowest past-due exposure at the same dealer, so a customer with a 7.5 at one dealer might score 3.0 at a different dealer where the worst-case account is far more delinquent. This matters when comparing scores across dealers: do not. Compare within a dealer.

Third, the log scaling compresses the upper end of the distribution. A customer whose dollar-weighted overdue sum is twice as large as another customer's does not score twice as high, because the log function flattens out as the inputs grow. This is intentional and prevents one catastrophically delinquent account from making every other past-due account look like a 0.

When the numbers refresh

The recomputation job runs whenever AR data changes for an account: an invoice is created, updated, marked paid, or voided; a credit or debit adjustment is created, updated, or applied; a customer invite changes status. The job rebuilds the affected account in full rather than computing an incremental delta, which keeps the math simple and avoids the kind of drift that incremental aggregations are notorious for, since incremental rollups have a way of being correct on Tuesday and creatively wrong on Wednesday.

If something looks wrong in the CSV, the first thing to check is whether the underlying invoice data is correct in Drypowder. Open the customer's detail page and look at the invoices, adjustments, and payments tabs. Ninety-nine times out of a hundred the answer is that an invoice has not yet synced from Spruce, or has not been marked paid yet, and the stats are correctly reflecting Drypowder's current view of the world.

What is not in the CSV

A few things people occasionally expect to see in this export and will not find:

  • Statement-scoped versions of each column. The platform computes a parallel set of statement metrics (statement outstanding invoice amount, statement past-due invoice amount, and so on) that restrict the totals to invoices currently appearing on the customer's most recent statement. These are used inside the Payments portal but are not emitted into the CSV.
  • DSO. Days sales outstanding is not in this export and is not stored on the stats tables. The closest available metric is past_due_invoice_weighted_average_days_overdue, which answers a related but different question. DSO is a sales-volume-normalized metric; the weighted average overdue duration is a balance-weighted snapshot.
  • Payment history. This file is an AR snapshot, not a payment ledger. Use the Incoming Payments CSV export from the Payments page if you need a list of payments received.
  • Job-level breakouts. Drypowder computes a parallel set of stats per job, but those numbers do not surface in the customer CSV. They appear in the customer detail view when the job-level data exists.

Quick map: what to use when

QuestionColumn to look at
"How much does this customer owe me right now, all in?"outstanding_amount
"How much of that is past due?"past_due_invoice_amount
"How bad is the past-due, on average?"past_due_invoice_weighted_average_days_overdue
"How much of the past-due is really old?"ninety_one_plus_invoice_amount
"Are there discounts this customer is leaving on the table?"discount_amount
"Who should I call first?"sort descending by collection_priority
"Does this customer have credits sitting unapplied?"outstanding_credit_adjustment_amount
"Have we even invited this customer to the portal yet?"invite_status

On this page