GraphQL backend for B2B Organizations.
This app exposes admin and storefront GraphQL APIs to create and manage B2B organizations, cost centers, users, and related settings.
Creating organizations with cost centers
Two mutations can create an organization together with one or more cost centers. They share DefaultCostCenterInput, but behave differently regarding custom IDs and admin user setup.
| Mutation | Input type | Organization ID | Cost center ID | Admin user |
|---|---|---|---|---|
createOrganization | OrganizationInput | Auto-generated by Master Data | Auto-generated by Master Data | Not attached automatically |
createOrganizationAndCostCentersWithId | NormalizedOrganizationInput | Custom (input.id) | Custom (costCenters[].id / defaultCostCenter.id) | Attached to each cost center |
When to use each mutation
Use createOrganizationAndCostCentersWithId when the integration needs fixed organization and cost center identifiers (for example, syncing with an external ERP or CRM).
Use createOrganization when identifiers should be generated by Master Data. In this flow, do not send id on the organization or on cost centers. Use the costCenterId returned by the mutation when querying or updating the created cost center.
Sending a custom cost center id to createOrganization may cause a 400 response if that identifier already exists in Master Data (The document already exist with id or alternate key.).
Organization status on create
OrganizationInput and NormalizedOrganizationInput accept an optional status field when creating an organization.
| Value | Meaning |
|---|---|
| (omitted) | Defaults to active (backward compatible) |
active | Organization is active |
inactive | Organization is inactive |
on-hold | Organization is on hold |
Canonical values match updateOrganization. Omitting status keeps the historical create behavior. Creating with a non-active status does not send the organization status-changed email (that email only applies when status changes via updateOrganization).
The
statusfield returned bycreateOrganizationandcreateOrganizationAndCostCentersWithIdis the mutation's operation result (often empty), not the organization's lifecycle status. QuerygetOrganizationByIdwith the returnedidto confirm the persisted status.
_10query GetOrganization($id: ID!) {_10 getOrganizationById(id: $id) {_10 id_10 name_10 status_10 }_10}
Cost center addresses
DefaultCostCenterInput supports two ways to send addresses when creating an organization:
| Field | Type | Description |
|---|---|---|
address | AddressInput | Single address (backward compatible) |
addresses | [AddressInput] | Multiple addresses (optional) |
Both fields can coexist in the same input. Resolution order:
- If
addressesis provided and non-empty, it is used. - Otherwise, if
addressis provided, it is stored as a one-item array. - Otherwise, an empty array is stored.
This matches the behavior already available on createCostCenterWithId, which uses CostCenterInput.addresses.
Optional address fields (such as complement) may be omitted in GraphQL. They are normalized to empty strings before persistence when created through organization mutations.
Example: multiple addresses with custom IDs
Use createOrganizationAndCostCentersWithId:
_10mutation CreateOrganizationAndCostCenters($input: NormalizedOrganizationInput!) {_10 createOrganizationAndCostCentersWithId(input: $input) {_10 id_10 href_10 status_10 }_10}
_38{_38 "input": {_38 "id": "org-example-001",_38 "name": "Example Organization",_38 "tradeName": "Example Trade Name",_38 "b2bCustomerAdmin": {_38 "firstName": "Admin",_38 "lastName": "User",_38 "email": "admin@example.com"_38 },_38 "costCenters": [_38 {_38 "id": "cc-example-001",_38 "name": "Main Cost Center",_38 "addresses": [_38 {_38 "addressType": "BillingAddress",_38 "street": "100 Main Street",_38 "city": "Chicago",_38 "state": "IL",_38 "country": "USA",_38 "postalCode": "60601",_38 "complement": ""_38 },_38 {_38 "addressType": "ShippingAddress",_38 "street": "200 Warehouse Ave",_38 "city": "Chicago",_38 "state": "IL",_38 "country": "USA",_38 "postalCode": "60602",_38 "complement": ""_38 }_38 ]_38 }_38 ]_38 }_38}
Example: single address (legacy field)
The singular address field remains supported:
_26{_26 "input": {_26 "id": "org-example-002",_26 "name": "Legacy Organization",_26 "b2bCustomerAdmin": {_26 "firstName": "Admin",_26 "lastName": "User",_26 "email": "admin.legacy@example.com"_26 },_26 "costCenters": [_26 {_26 "id": "cc-example-002",_26 "name": "Main Cost Center",_26 "address": {_26 "addressType": "BillingAddress",_26 "street": "5th Avenue",_26 "city": "New York",_26 "state": "NY",_26 "country": "USA",_26 "postalCode": "10001",_26 "complement": ""_26 }_26 }_26 ]_26 }_26}
Example: multiple addresses without custom IDs
Use createOrganization and omit all id fields:
_10mutation CreateOrganization($input: OrganizationInput!, $notifyUsers: Boolean) {_10 createOrganization(input: $input, notifyUsers: $notifyUsers) {_10 id_10 costCenterId_10 href_10 status_10 }_10}
_36{_36 "notifyUsers": false,_36 "input": {_36 "name": "Auto ID Organization",_36 "b2bCustomerAdmin": {_36 "firstName": "Admin",_36 "lastName": "User",_36 "email": "admin.auto@example.com"_36 },_36 "costCenters": [_36 {_36 "name": "Main Cost Center",_36 "addresses": [_36 {_36 "addressType": "BillingAddress",_36 "street": "Rodeo Drive",_36 "city": "Beverly Hills",_36 "state": "CA",_36 "country": "USA",_36 "postalCode": "90210",_36 "complement": ""_36 },_36 {_36 "addressType": "ShippingAddress",_36 "street": "Sunset Blvd",_36 "city": "Los Angeles",_36 "state": "CA",_36 "country": "USA",_36 "postalCode": "90211",_36 "complement": ""_36 }_36 ]_36 }_36 ]_36 }_36}
Use the returned costCenterId to query the created cost center:
_12query GetCostCenter($id: ID!) {_12 getCostCenterById(id: $id) {_12 id_12 name_12 addresses {_12 addressType_12 street_12 city_12 state_12 }_12 }_12}
Related mutations
createCostCenterWithId— create a cost center with a custom ID andaddresseson an existing organization.updateCostCenter— update cost center fields, includingaddresses.