Creating Customer Shipments through the API

Does anyone know what endpoints I should be going through to create Customer Shipment Entry ShipDtl lines through the REST API?

I am able to generate a new PackNum through the endpoint:


but when trying to create new lines using:


I am getting “200: Success” responses from the server but no lines are being created.

If anyone has successfully done this and could point me in the right direction, it would be greatly appreciated.

Use Epicor Functions if you are on a high enough version. That said, are you on a high enough version?
Keep in mind that GetNew(whatever) creates the dataset but does not commit it to the database. Following the trace, to the letter, will give you what you need to orchestrate this.


Hi, thanks for the response.

We are 10.2.700, so can use functions. I’m looking at the trace of adding a New Line to a shipment, and it looks like:


So all of these calls need to happen in that order to add a ShipDtl line?

Cool, that’s definitely what I’d recommend (using functions). So your function will be the endpoint you call from your application, something basic like “CreateCustomerShipmentLine” with a few parameters necessary to look up the info you need to use inside your function.
Then, the meat of the calls and orchestration happens inside the function. Use the widgets in the function to handle each one of those calls you mentioned. It takes a little getting used to but it’s oh so easy once you figure it out.
Yes, all those calls are needed to create an order line. Remember how many things are being checked and set in the background. It’s not a simple process.

Alright, you have me convinced. We had hoped to start building a C# library of API calls outside of Epicor should we ever need this functionality elsewhere, but if it’s going to save a huge chunk of time to just use widgets in a function, maybe we should do that instead.

Thanks for your help!

1 Like

Yes definitely. This is the way!

I know this is an older thread but I’m running into the same thing. Is there any way to do this directly via the rest api through “/api/v2/Erp.BO.CustShipSvc/CustShips” instead of creating a function to run through the business objects? My undertstanding is that a post to the endpoint is essentially a call to updateExt so it should work. However I’m getting the same behavior as OP where the header is being created but the lines are missing. Any advice? Thanks.

I have a function that ships SOs using the CustShip BO with the following methods in the same order as below:


  • GetNewShipHead
  • GetHeadOrderInfo
  • GetLegalNumGenOpts
  • CheckPCBinOutLocation
  • UpdateMaster


  • GetRows (without lines)
  • GetNewOrdrShipDtl
  • GetOrderInfo (first line only)
  • GetOrderLineInfo
  • GetOrderRelInfo
  • GetPartInfo
  • GetWhseInfo
  • ValidateBinCode
  • GetQtyInfo
  • CheckPCBinOutLocation
  • UpdateMaster

When adding lines, the important thing is that you should never have any lines in your dataset except the new one. That’s why adding the first line works and the next ones don’t. When adding second/third/etc line, you need to remove the previous lines from the dataset.
So, instead of GetByID which gets all lines, I use GetRows with the line parameter ‘PackLine = 0’ to get the whole dataset but without the lines. And only then I call GetNewOrdrShipDtl. I hope this makes sense.

LE: see below what I mean. @josecgomez uses csts.ShipDtl.Clear after GetByID there which does the same thing.

I wrote directly against the BO’s before the api existed. This is to compare against Dragos:


  • new CustShipDataSet
  • GetNewShipHead
  • GetHeaderOrderInfo
  • BuildShipToCustomerList
  • BuildShipToList
  • UpdateMaster

Pre-Looping through lines

  • PackOutDataSet = POGetNew()
  • POGetDtlList
  • PreCreateMassShipDtl
  • CreateMassShipDtl
  • BuildShipToList
  • MarkShipmentLines

Looped through to find bins for parts
Looped through and calculated weights of parts
Looped through to calculate size and how many boxes
Looped through boxes to get tracking information and shipping label from UPS

Finished with a UpdateMaster, which included all lines.

Set ReadyToInvoice = true

one more Update Master ( do not remember why I had to have the set and second update )

Used the CreateMassShipDtl to create all of the detail lines.

Worked for us. By the time I left ( after 4 years ) we had shipped close to 250,000 packages through the program without having to touch UPS or Epicor. Process would print a pack label, then the shipping label. Meaning shipping just used the pack label to know what went in what box. Then placed both labels and shipped.

1 Like