Company profiles
Create and update complete customer and supplier profiles with the commercial setup needed for connected onboarding.
Supported writes
| Endpoint | Scope | Required header |
|---|---|---|
POST /customers | customers:write | Idempotency-Key |
PATCH /customers/{id} | customers:write | If-Match |
POST /customers/{id}/archive or /unarchive | customers:write | If-Match |
POST /suppliers | suppliers:write | Idempotency-Key |
PATCH /suppliers/{id} | suppliers:write | If-Match |
POST /suppliers/{id}/archive or /unarchive | suppliers:write | If-Match |
POST requests require a stable idempotency key. PATCH requests require the latest updatedAt value as If-Match and preserve omitted fields. Add dryRun=true to the same endpoint when your workflow needs a non-mutating readiness check before execution.
Customer profiles
Customer profile writes combine identity with an initial primary location, billing or shipping address, account owner, payment terms, customer-service representative, and credit limit. Resolve the referenced records first through the company reference directories. Use the locations and addresses endpoints for additional customer locations or addresses after the customer exists.
curl "$SHELFCYCLE_API_BASE_URL/customers" \
-X POST \
-H "Authorization: Bearer $SHELFCYCLE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: crm:lead-1842:create-customer" \
-d '{
"name": "Northstar Chemical",
"externalId": "NS-1842",
"pipelineStatus": "PROSPECT",
"primaryLocation": {
"name": "Northstar Chemical HQ",
"email": "ops@northstar.example",
"phone": "555-0100",
"accountOwnerId": "salesperson-id",
"paymentTermsId": "payment-term-id",
"customerServiceRepresentativeId": "customer-service-id",
"creditLimit": {
"amountCents": 2500000,
"currencyCode": "USD"
},
"address": {
"name": "Northstar Chemical HQ",
"externalId": "CRM-ADDRESS-1842-HQ",
"street1": "100 Market Street",
"city": "Chicago",
"state": "IL",
"zip": "60601",
"country": "US",
"isBilling": true,
"isShipping": true
}
}
}'
Customer locations carry commercial details independently. accountOwnerId selects a salesperson representative, customerServiceRepresentativeId selects a customer_service representative, and paymentTermsId selects a payment-term record. Credit uses integer amountCents; an optional currencyCode must match the organization base currency returned by /me.
Supplier profiles
Supplier profile writes combine identity and contact details with tax ID, payment terms, credit limit, preferred unit of measure, an eligible cost ledger account, a supplier representative, and an optional source-identified ship-from address. Use the supplier ship-from endpoints for additional locations after the supplier exists.
curl "$SHELFCYCLE_API_BASE_URL/suppliers" \
-X POST \
-H "Authorization: Bearer $SHELFCYCLE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: erp:supplier-902:create" \
-d '{
"name": "Acme Supply",
"externalId": "ERP-SUPPLIER-902",
"email": "orders@acme.example",
"taxId": "12-3456789",
"paymentTermsId": "payment-term-id",
"creditLimit": { "amountCents": 1000000, "currencyCode": "USD" },
"preferredUnitOfMeasure": "Imperial",
"costLedgerAccountId": "ledger-account-id",
"supplierRepresentativeId": "supplier-representative-id",
"primaryShipFromAddress": {
"name": "Acme Supply Warehouse",
"externalId": "ERP-SHIPFROM-HOU",
"street1": "20 Industrial Way",
"city": "Houston",
"state": "TX",
"zip": "77002",
"country": "US",
"defaultSupplierShippingInstructions": "Call before pickup."
}
}'
preferredUnitOfMeasure accepts NoPreference, Metric, or Imperial. Select costLedgerAccountId from GET /reference/ledger-accounts, paymentTermsId from GET /payment-terms, and supplierRepresentativeId from a supplier row returned by GET /representatives.
Supplier finder rows, detail reads, and create or update responses include carrierProfile, with DOT number, MC number, saved operating status, and the profile's own updatedAt, or null for a supplier without a carrier profile. Use PUT /suppliers/{id}/carrier-profile after creating a supplier to add its carrier details. See Supplier carriers for discovery, preview, replacement, and removal examples.
Source IDs and separate records
Customer, supplier, nested customer-address, and nested supplier ship-from creates accept source externalId values. Keep each externalId separate from the request's Idempotency-Key: the first identifies the business record, while the second identifies the create request and its retries.
When a supported create resembles an existing profile but represents a separate legitimate source record, add top-level duplicateResolution: "create_distinct". Omission keeps the normal duplicate check. Exact source-ID conflicts still require correction. See Account setup for the complete workflow and all six supported create families.
Read before update
Use GET /customers/{id} or GET /suppliers/{id} before a PATCH. The response includes updatedAt; send that exact value as If-Match so ShelfCycle can reject stale overwrites with 409 stale_record.
Customer and supplier profiles can also be archived and restored with the same write scope and current user permission. Preview the selected action, then apply it with the latest updatedAt value. See Archive and restore for the complete flow and receipt.
Create or update one profile at a time, record every outcome, and stop on exact identity, archived, stale, or access errors.