Item and the ExternalReference.
Why these resources exist
Mapping between external systems is a pure translation — it never touches the billing engine. Rather than overload the billingProduct with integration concerns, Paygentic models the mapping anchor as its own resource. The Item is the canonical “thing you sell”; the ExternalReference records each link from an Item to a record in an external system.
The Item is CRM/ERP agnostic — it knows nothing about which external systems map to it. All of that lives on its ExternalReference rows, where provider is just a lowercase identifier. A common use case is bridging an upstream CRM such as Salesforce to a downstream ERP such as NetSuite. The resources make no assumption about provider, direction, or authority — those are conventions a consumer layers on top.
The full design rationale (including the comparison to Orb’s model and the variant analysis) lives in the Item Resource — Design Rationale document on PAYG-1142.
The Item
AnItem is intentionally thin — id, merchantId, name, and metadata. It carries no pricing, plan, currency, or metering, and it is independent of the billing Product.
Item with just a name and attach external references later, in any order.
The ExternalReference
AnExternalReference links an entity to its identifier in an external system. For mapping work the entityType is always item, and provider is a lowercase identifier such as salesforce or netsuite.
entityId must resolve to a live Item in the same merchant.
Multiple references per provider
AnItem may carry several references for the same provider. For example, aliases for renamed or legacy codes that all point at the same Item, or several valid downstream posting targets. Additional references beyond the primary are non-primary aliases (see below). A consumer selects the specific target it needs at the point of use.
isPrimary vs isDefault
Two independent boolean flags express two different guarantees:isPrimary— at most one claiming reference per(merchant, provider, externalId). This is the deduplication guarantee: a claimed code resolves back to exactly oneItem. Additional unclaimed references with the same code are allowed as aliases, which is what lets several items share a ledger account. Omitting it claims the code; passfalsefor a code that is only ever sent outward. It cannot be cleared once set — claim the code on the item it should resolve to instead, which moves the claim in one write.isDefault— at most one designated code per(merchant, entityType, entityId, provider): the one sent when a consumer needs a single answer. Omitting it designates the entity’s first code for that provider, so an entity with one code needs no further action, and it cannot be cleared — designate another of the entity’s codes, which moves the designation.
false, because both flags resolve differently when unstated, and a generated client materialises a declared default into every request body — which is how the designation silently stopped happening for one dashboard release.
Resolution
Resolve an external code to itsItem(s) by listing with the provider + externalId filter (you must supply both together). Resolution returns every live Item mapped to that (provider, externalId) — the canonical primary plus any non-primary aliases. Resolution returns the primary Item first; its matching reference’s isPrimary: true identifies it unambiguously (the partial-unique index guarantees at most one primary per code). An unknown code returns an empty list rather than an error.
Callers that only want the canonical owner take the first result; callers reconciling renamed or legacy codes get the full alias set.
Item returns its live external references in the externalReferences array. The Item itself reports no provider-specific lifecycle state. The consumer derives any gating (for example, “is this mapped to a downstream system yet?”) from the presence of the relevant references. There is no hard stop at import time; an Item that carries only inbound references is still valid and simply has no downstream reference attached yet.
See the API Reference for the full request and response schemas.