B2B Data Integration Notes

Modified on Mon, 16 Mar at 12:15 PM


The goal of this document is to give an external vendor a simple contract for the minimum data we need in order to create or update:

  • organizations
  • locations
  • users


Recommended Import Order


Imports should run in this order:

  1. Organizations
  2. Locations
  3. Users


Locations and users are linked to an organization by the vendor's organization/customer number. If the organization does not already exist, the location or user record will be skipped.


General Integration Expectations

  • We can work with either JSON or CSV, but a JSON API is preferred.
  • Each feed should be idempotent. Sending the same record again should update the same object, not create a duplicate.
  • Stable external identifiers are required.
  • Empty strings are acceptable for optional fields.
  • Field names do not have to match this document exactly if a mapping layer is added, but these are the values we need.


Minimum Fields By Entity


1. Organizations


Organizations are upserted by organization_number.


Minimum fields:

FieldRequiredNotes
organization_numberYesVendor/customer/account number. Must be stable and unique.
organization_nameYesDisplay name for the organization.
statusPreferredactive or inactive. If omitted, we should agree on the default.


Common optional fields:

FieldNotes
sales_incentiveBoolean flag for incentive/SPIF participation.
sales_rep_emailUsed to associate an internal sales rep when applicable.
websiteOrganization website if available.
dataFree-form source metadata if needed.


Example:

[
  {
    "organization_number": "CUST-1001",
    "organization_name": "Example Jewelers",
    "status": "active",
    "sales_incentive": true,
    "sales_rep_email": "rep@example.com"
  }
]


2. Locations


Locations are upserted by the combination of:

  • organization_number
  • location_id


Minimum fields:

FieldRequiredNotes
organization_numberYesMust match an existing organization.
location_idYesStable unique location/store identifier from the source system.
location_nameYesStore name. If no store name exists, city is an acceptable fallback.
address1YesPrimary street address.
cityYesCity/locality.


Strongly recommended fields:

FieldNotes
address2Suite, unit, etc.
stateState/province/region.
postal_codeZIP/postal code.
country2- or 3-letter code, depending on source availability.
phoneMain store phone number.
statusactive, inactive, or hidden when applicable.


Example:

[
  {
    "organization_number": "CUST-1001",
    "location_id": "CUST-1001-NYC",
    "location_name": "Example Jewelers Manhattan",
    "address1": "123 Main St",
    "address2": "Suite 400",
    "city": "New York",
    "state": "NY",
    "postal_code": "10001",
    "country": "US",
    "phone": "212-555-0100",
    "status": "active"
  }
]


3. Users


Users are linked to an organization by organization_number.


Current importers support two common patterns:

  • one user per organization, keyed by organization number
  • many users per organization, keyed by a user-specific external id or username


For a new integration, a stable user-level identifier is preferred.


Minimum fields:

FieldRequiredNotes
organization_numberYesMust match an existing organization.
user_id or usernameYesStable unique user identifier from the vendor system.
nameYesFull name.
emailYesValid email preferred. If unavailable, call that out early so fallback behavior can be defined.


Strongly recommended fields:

FieldNotes
phoneUser phone number.
activeBoolean or equivalent active/inactive flag.
passwordOnly if the vendor is the system of record for credentials. Otherwise we can use invite/random-password flows.
roleOptional if manager/associate distinctions are needed.


Example:

[
  {
    "organization_number": "CUST-1001",
    "user_id": "USR-9001",
    "username": "jsmith",
    "name": "Jane Smith",
    "email": "jane.smith@example.com",
    "phone": "212-555-0199",
    "active": true
  }
]


Update Rules

  • Organization records should update by organization_number.
  • Location records should update by organization_number + location_id.
  • User records should update by stable user identifier, while retaining the organization link.


Validation Notes

  • organization_number, location_id, and user identifier values must remain stable over time.
  • Email addresses should be valid email strings.
  • Status values should be normalized before delivery when possible.
  • If a source system cannot provide one of the fields listed as minimum, that should be discussed before implementation because it changes importer behavior.


Preferred API Shape

If the vendor is exposing an API instead of files, the simplest shape is three endpoints:

  • GET /organizations
  • GET /locations
  • GET /users


Each endpoint should return a flat array of records, with full refresh data for that entity type.

If incremental sync is supported, include:

  • updated_at
  • a way to filter by last modified timestamp


Summary

At minimum, we need:

  • organizations: stable organization number + organization name
  • locations: organization number + stable location id + name + address + city
  • users: organization number + stable user id/username + name + email

Anything beyond that can be layered in once the base import is working.


Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select at least one of the reasons
CAPTCHA verification is required.

Feedback sent

We appreciate your effort and will try to fix the article