Acumatica · Customization

Acumatica Numbering Sequences — Customisation Patterns

Every document type in Acumatica — orders, invoices, shipments — gets its reference number from a numbering sequence, configured once under System Automation and then invisibly.

John Kihiu12 min read

A client in the logistics space once asked me for something that sounded simple: invoice numbers that reset to 1 every fiscal year, per branch, with a two-letter branch prefix, because their tax authority's e-invoicing integration rejected anything else. Numbering sequences in Acumatica can do this, but the configuration screen hides just enough behavior that getting it right on the first attempt is rare. Here is what I actually walk through.

A numbering sequence is a small state machine, not just a counter

Every numbering sequence (configured on the Numbering Sequences screen, CS201010) tracks a current value, a prefix, a length with zero-padding, and optionally a set of "numbering segments" that can key off branch, or reset the counter based on a defined interval, annually, monthly, or never. The important mental model: a numbering sequence is not one counter, it is potentially many counters, one per unique combination of the segmenting keys you configure, all managed under a single sequence ID that document types reference.

TEXT
Sequence: ARINVOICE
  Numbering: Not Numeric (has segments)
  Start Date    Prefix    Start Nbr   Increment   Warning Nbr
  01/01/2026    KE-       000001      1           999900

  Segment: Branch (2 chars, from branch value)
  Segment: Year (annual reset)
  Segment: Numeric (6 digits, per the counter above)

With branch and year both configured as segments, the platform actually maintains a distinct counter for every branch-year combination, so Nairobi's 2026 sequence and Mombasa's 2026 sequence are two entirely separate counters even though they share one sequence ID and one configuration screen.

Numeric-only sequences vs segmented sequences

The simplest sequences are pure numeric: a prefix, a start number, an increment, done. Most out-of-the-box document types ship this way. The moment a requirement involves resetting by year, varying by branch, or embedding a document-type code inside the number itself, you need a segmented sequence, and segmented sequences are configured through a genuinely different part of the screen from plain numeric ones, which is the first place I see people get lost, they configure a prefix on a numeric sequence and then can't find where to add a year-reset behavior because that option only appears once you have added at least one segment.

Test the reset behavior before go-live, not after New Year's Day

Annual-reset sequences are the single most common numbering bug I get called about in January. The reset triggers on the segment's defined start date, not on save, so if a sequence was configured mid-year with an annual segment, the first real test of the reset behavior often does not happen until the actual fiscal year rolls over, live, in production. I always advance a sandbox instance's system date (or configure a short-interval test segment temporarily) to force a rollover and confirm the next number looks right before the client depends on it.

One sequence can serve many document types, deliberately or by accident

Document types (in AR, AP, SO, and elsewhere) each reference a numbering sequence ID in their configuration, and nothing stops two unrelated document types from pointing at the same sequence. Sometimes that is deliberate, a client wants Credit Memos and Invoices to draw from one interleaved number range because their statutory numbering rules require gap-free sequential numbers across all AR document types. More often, I find it by accident during an audit: someone cloned a document type configuration and never repointed the numbering sequence field, so two unrelated document types have been silently sharing one counter, which is usually harmless until someone needs to explain a numbering gap to an auditor and the true cause turns out to be "we share a sequence with something else."

Generating numbers from code: use the platform's mechanism, don't roll your own

Custom document types built for a bespoke screen still need proper numbering, and the temptation to hand-roll a MAX-plus-one query is exactly the kind of shortcut that produces duplicate numbers the first time two users save concurrently. Acumatica's numbering infrastructure already handles this safely:

C#
// Wire a DAC's key field to a numbering sequence via AutoNumber,
// the same mechanism the base document types use, rather than
// querying for a max value and incrementing it yourself.
[PXDBString(15, IsUnicode = true, InputMask = "")]
[PXDefault]
[PXFieldDescription]
[AutoNumber(typeof(Setup.docNumberingID), typeof(AccessInfo.businessDate))]
public string RefNbr { get; set; }
public abstract class refNbr : PX.Data.BQL.BqlString.Field<refNbr> { }

AutoNumber pulls and increments the sequence transactionally at persist time, which is what actually prevents two concurrent saves from getting the same number, a guarantee a hand-written "select max, add one" query cannot make under real concurrent load.

Gaps happen, and that is usually fine

A number gets consumed the moment a document is created and assigned a number, even if that document is later deleted or the save is abandoned before completing, in some flows. Clients occasionally ask for gap-free numbering as a hard requirement, which is a genuinely harder problem, it usually means deferring number assignment until the point of final release or posting rather than at document creation, which is a real customization, not a numbering sequence setting. Confirm early whether "sequential" in a client's requirement actually means gap-free, because building for gap-free numbering after the fact touches every insertion point for that document type, not just the numbering sequence configuration.

Wrapping up

Numbering sequences look like a single counter field but are really a small configurable state machine: segments determine how many independent counters actually exist under one sequence ID, reset behavior needs to be tested against a real rollover before go-live, and document types can share sequences either deliberately or by accidental misconfiguration. When numbering needs to be generated from custom code, use AutoNumber rather than a hand-rolled max-plus-one query, and clarify early whether "sequential" really means gap-free before assuming the standard mechanism covers it.

John Kihiu
Acumatica ERP Developer · Laravel Engineer

Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.