ERP → Salesforce¶
This is the call ERP sends when it creates a Ship To. The sample is Peenya Depot, the first Ship To ERP has stored for DIST001, so the local code is DIST001_1.
ERP saves the row first, then posts Ship_To__c. The Salesforce Id in the create response is not stored. Salesforce then assigns Ship_To_Code__c itself and does not call POST /webhook/ship-to for an ERP-originated record.
POST /api/accounts/sold-tos/DIST001/ship-tos¶
What the ERP API receives¶
{
"shipToName": "Peenya Depot",
"shippingAddress": {
"street": "42 Peenya Industrial Area",
"city": "Bengaluru",
"state": "Karnataka",
"pincode": "560058"
},
"gstRegistrationNumber": "29ABCDE1234F1Z5",
"contactPerson": "Ravi Kumar",
"contactPhone": "9800112233"
}
DIST001 must already exist. A missing Sold To is HTTP 404 sold to account not found. A blank name is HTTP 400 ship to name is required. A pincode that is not 6 digits, and a phone that is present but not 10 digits, are HTTP 422 with unprocessable_entity, the same messages as the inbound call. GSTIN is stored uppercased and is not checked as a GSTIN.
ERP answers HTTP 201 with the saved row. id is ERP's row id. syncStatus is Synced when the Salesforce post succeeded and Failed when it did not. The 201 is still returned after a failed post.
{
"id": "c4a760a8-db2a-4c5e-9f1a-8d3e6b7c9a01",
"soldToCode": "DIST001",
"shipToCode": "DIST001_1",
"shipToName": "Peenya Depot",
"street": "42 Peenya Industrial Area",
"city": "Bengaluru",
"state": "Karnataka",
"pincode": "560058",
"gstRegistrationNumber": "29ABCDE1234F1Z5",
"contactPerson": "Ravi Kumar",
"contactPhone": "9800112233",
"status": "Active",
"syncStatus": "Synced",
"createdAt": "2026-11-06T04:30:00Z",
"updatedAt": "2026-11-06T04:30:00Z"
}
A later retry is POST /api/ship-tos/c4a760a8-db2a-4c5e-9f1a-8d3e6b7c9a01/sync-to-salesforce. The {id} is the ERP row id, not DIST001_1. Success is HTTP 200:
A Salesforce failure on this retry is HTTP 500 internal_error with message internal server error. The row's syncStatus is Failed. POST /api/ship-tos/sync-unsynced runs the same post for every row that is not Synced, and answers { "synced": 1, "failed": 0 }.
POST /sobjects/Ship_To__c¶
POST /services/data/v67.0/sobjects/Ship_To__c
Authorization: Bearer {access token}
Content-Type: application/json
Ship_To_Code__c is not in this body. The parent is the Sold To code.
{
"Sold_To__r": {
"Sold_To_Code__c": "DIST001"
},
"Ship_To_Name__c": "Peenya Depot",
"Shipping_Street__c": "42 Peenya Industrial Area",
"Shipping_City__c": "Bengaluru",
"Shipping_State__c": "Karnataka",
"Shipping_Pincode__c": "560058",
"GST_Registration_Number__c": "29ABCDE1234F1Z5",
"Contact_Person__c": "Ravi Kumar",
"Contact_Phone__c": "9800112233",
"Origin__c": "ERP",
"Status__c": "Active"
}
| Salesforce field | Example | Where ERP got it |
|---|---|---|
Sold_To__r.Sold_To_Code__c |
DIST001 |
the Sold To in the URL |
Ship_To_Name__c |
Peenya Depot |
shipToName |
Shipping_Street__c |
42 Peenya Industrial Area |
shippingAddress.street |
Shipping_City__c |
Bengaluru |
shippingAddress.city |
Shipping_State__c |
Karnataka |
shippingAddress.state |
Shipping_Pincode__c |
560058 |
shippingAddress.pincode |
GST_Registration_Number__c |
29ABCDE1234F1Z5 |
gstRegistrationNumber |
Contact_Person__c |
Ravi Kumar |
contactPerson. Omitted when blank |
Contact_Phone__c |
9800112233 |
contactPhone. Omitted when blank |
Origin__c |
ERP |
literal |
Status__c |
Active |
literal |
Salesforce answers HTTP 201:
ERP reads that body only to confirm the call succeeded. a0S000000000002AAA is not written onto the local row. ShipTo_AfterSave sees origin ERP, status Active, and a blank code, assigns Ship_To_Code__c (also DIST001_1 when Salesforce has no earlier Ship To for DIST001), and does not post the record to ERP.
The outbound log reference is soldToCode=DIST001 name="Peenya Depot" pincode=560058 status=Active. GSTIN and phone are not on that line.