What you can do
Send items from production out to an external service vendor straight from your ERP: four /ERP/ServiceOrder/ endpoints create a service order, update the quantities on it as items ship and come back, move it through its statuses, and report what happened. One call can carry a whole order with every item on it.
The interface creates and updates. No endpoint deletes a service order — an order is stopped by setting its status to Cancelled, and deleted only in the Admin Portal under Order lists > Purchase orders.
Endpoints
| Method | Endpoint | What it does | Answers with |
|---|---|---|---|
| POST | [AP_base_uri]/ERP/ServiceOrder/Create |
Queues a new service order together with the items to be serviced. | A request GUID |
| POST | [AP_base_uri]/ERP/ServiceOrder/UpdateQuantity |
Queues ordered, received, and scrapped quantity changes on items in an existing order. | A request GUID |
| POST | [AP_base_uri]/ERP/ServiceOrder/UpdateOrder |
Queues status, shipping, reference, and note changes on an existing order. | A request GUID |
| GET | [AP_base_uri]/ERP/ServiceOrder/GetRequestResult |
Returns the outcome of any of the three calls above, identified by its GUID. | The result object |
[AP_base_uri] is the host your Admin Portal runs on, without the portal path. If you open the portal at https://solutionaddress.com/adminportal/yourcompany, the base address is https://solutionaddress.com. See the CRIBWISE REST API endpoint overview for the full endpoint list.
The ERP system authenticates, writes with the three POST endpoints, and reads the outcome back with GetRequestResult.
Note: These endpoints work on orders of type Service, which go to an external service vendor. When an item’s service vendor is internal, CRIBWISE uses a service list instead, which has no statuses and no REST interface of its own — see Understanding service lists. Ordinary purchase orders have their own interface — see How to manage purchase orders with the REST API.
Before you start
- An API key, exchanged for a bearer token that every call carries in its
Authorizationheader — see How to authenticate with the REST API. - The IDs in your payload must already exist in CRIBWISE. Vendor, stock, device, item, and order template values are validated against the database on every call.
- Decide whether the order is device level (one device, set on the order) or stock level (one stock, with the device set per item). You cannot set a device in both places.
- The items must be available for service: in a service location, or marked for service if serialized, with service allowed on the item definition. The quantity you ask for cannot exceed the quantity available for service when the call runs.
- All quantities are in the item’s dispense unit of measure, not its purchase unit of measure — see How to configure units of measure.
- All dates and times are UTC.
Important: A
200fromCreate,UpdateQuantity, orUpdateOrdermeans the request was queued, not that the order changed. Validation errors are reported only byGetRequestResult, so an integration that stops at the200will miss every one of them.
Quick start
Experienced users — create and send a service order in 5 steps:
- Exchange your API key for a bearer token.
- POST the order and the items to be serviced to
[AP_base_uri]/ERP/ServiceOrder/Create. - Read the request GUID from the
200response. - GET
/ERP/ServiceOrder/GetRequestResult?requestGuid={GUID}untilStatusisCompleted, and store the returned order and item IDs. - POST
Status: "Active"to/ERP/ServiceOrder/UpdateOrderto send the order to the vendor.
Need more detail? Follow the full steps below.
Steps
Step 1 — Collect the values your payload has to match
Every reference in the payload is checked against the database, so gather them first. All of them are visible in the Admin Portal.
| Payload value | Where it comes from |
|---|---|
VendorId |
Data management > Vendors, the vendor ID on the vendor detail. Use the vendor that performs the service. |
StockName |
Data management > Stock. This is the stock’s name, not a numeric ID. |
DeviceId |
Data management > Devices, the device ID on the device detail. |
ItemId |
Data management > Items, the Item ID on the item detail. |
SerialNumber |
The serial number of the serialized item. It has to be available for service in the device you name. |
PdfTemplateName, ExcelTemplateName |
The name of an order template, needed only when you send the order as a PDF or an Excel file. |
The New order form is the manual equivalent of ServiceOrder/Create and a good way to see where each value lands. Setting Order type to Service turns the second tab into Items to service, which is where the ServiceOrderItems array ends up.
The New order form with Order type set to Service. The Items to service and Send options tabs stay dimmed until the order is saved.
| Admin Portal field | Payload field | |
|---|---|---|
| 1 | Order type | Fixed by the endpoint. Anything under /ERP/ServiceOrder/ works on orders of type Service. |
| 2 | Vendor | VendorId |
| 3 | Stock | StockName |
| 4 | Device | DeviceId |
| 5 | Items to service | ServiceOrderItems |
| 6 | Send options | SendOptions |
| Custom order ID prefix | CustomIdPrefix |
|
| Consignment | IsConsignment |
|
| Purchase order reference | Reference |
|
| Custom Ship to ID | CustomShipToId |
|
| Notes | Notes |
|
| Order ID | Assigned by CRIBWISE. Read it from GetRequestResult and use it as OrderId in later calls. |
Vendor and Stock are the two fields the Admin Portal marks as mandatory on a new order.
Step 2 — Create the service order
POST the order and its items to [AP_base_uri]/ERP/ServiceOrder/Create. The response is a request GUID; the order itself does not exist yet.
The status you create the order in
| Status | What creating the order does |
|---|---|
| omitted | The order is created as New. Nothing is sent and no transactions are raised. |
New |
Same as omitting it. |
Suggested |
The order is created as a suggestion. Nothing is sent and no transactions are raised. |
Active |
Raises the purchase transactions for every ordered item and can send the order to the vendor, if sending is configured. |
Cancelled |
Does everything Active does, then raises the cancelling transactions on top. |
Warning: Creating an order directly as Active sends it to the vendor in the same call. Use New or Suggested while you are testing an integration, and switch the status with
UpdateOrderonce you are sure the order is right.
Send options
SendOptions holds three objects. Channel chooses how the order leaves CRIBWISE, and FTP and Email choose the file formats for those two channels. If you switch on the PDF or the Excel format, you must name the matching order template as well.
Note:
FTPandPdfTemplateNameandExcelTemplateName.
Serialized items
A serialized item goes on the order one serial number at a time: give each line a SerialNumber and set its TotalQuantity to 1. Every serial number the order will ever carry has to be in this call, because UpdateQuantity cannot add serial numbers later.
Step 3 — Update quantities as items move
POST changed quantities to [AP_base_uri]/ERP/ServiceOrder/UpdateQuantity. Send only the values you are changing; OrderId is always mandatory. The total quantity you ask for cannot exceed the quantity available for service when the call runs.
Which quantity can change in which status
| Field | Can be changed while the order is |
|---|---|
TotalQuantity |
New, Suggested |
ReceivedQuantity |
Active |
ScrappedQuantity |
Active |
Two ways to point at a line
A line is identified either by the business data on it or by its technical ID. Use one or the other, never both.
| Reference | Send | Leave out | When to use it |
|---|---|---|---|
| By business data | ItemId, plus DeviceId on stock level orders, plus SerialNumber for serialized items |
Id |
The normal choice. It works from data your ERP already holds. |
| By technical ID | Id, the line ID from the Create result, in the form ServiceListItem123456 |
ItemId, DeviceId, SerialNumber |
Obsolete. Kept only for backward compatibility — do not build new integrations on it. |
Step 4 — Move the order through its statuses
POST status and shipping changes to [AP_base_uri]/ERP/ServiceOrder/UpdateOrder. This is the call that sends an order to the vendor, records the shipment, and cancels an order you no longer want.
Status accepts Suggested, Active, and Cancelled only. New is set by CRIBWISE when the interface creates an order, and Closed is set by CRIBWISE once every item on the order has been restocked or scrapped. Neither can be set through the interface.
Which status changes are allowed
| From | Can move to |
|---|---|
| New | Suggested, Active, Cancelled |
| Suggested | Active, Cancelled |
| Active | Cancelled |
| Closed | Nothing — the order is final |
| Cancelled | Nothing — the order is final |
Which field can change in which status
| Field | Can be changed while the order is |
|---|---|
Status |
New, Suggested, Active |
ShippingDate |
Active |
ReceivedByVendorDate |
Active |
TrackingNumber |
Active |
Reference |
New, Suggested, Active |
Notes |
Any status, including Closed and Cancelled |
OrderId |
Never — it identifies the order |
Step 5 — Read the request result
GET [AP_base_uri]/ERP/ServiceOrder/GetRequestResult?requestGuid={GUID}. This is the only place validation errors and new object IDs are reported, so a service order integration is not finished until it reads this endpoint.
| Parameter | Value |
|---|---|
requestGuid |
The GUID returned by the Create, UpdateQuantity, or UpdateOrder call. |
The result carries a status for the request as a whole, then the order and each of its lines with a status of their own.
| Request status | What it means |
|---|---|
| Created | The request arrived but is not in the task queue yet. |
| Ready | The request is in the task queue, waiting to run. |
| Scheduled | The request is held for later execution. Like Created and Ready, it means the work has not run yet. |
| Running | The changes are being applied. |
| Completed | Every change in the request has finished. Read the object statuses to see what each one did. |
| Failed | The request could not be performed. |
| Object status | What it means |
|---|---|
| Created | The object was created. |
| Updated | The object was updated. |
| Deleted | The object was deleted. |
| None | Nothing happened to the object, either because it failed validation or because the request asked for no change to it. Any validation errors are listed against the object in Errors. |
Tip: A request can report Completed while an object inside it sits at None. Always read the object statuses, not just the request status.
{
"Message": "string",
"Status": "Completed",
"ServiceOrder": {
"Id": "ERP_5-453-8907",
"Status": "Created",
"Errors": [],
"ServiceOrderItems": [
{
"Id": "ServiceListItem123456",
"ItemId": "5725474",
"Status": "Created",
"Errors": []
}
]
}
}
Where the order shows up in the Admin Portal
Service orders created over the interface are ordinary orders in CRIBWISE. They are listed under Order lists > Purchase orders together with purchase orders, and the Type column tells the two apart.
Service orders share the Purchase orders list with purchase orders. The Type column separates them, and the status filter decides which orders are listed at all.
That filter matters while you are testing. It defaults to New, Suggested, and Active, so an order your integration has already cancelled or closed is simply missing from the list until you widen it.
The five order statuses in the Admin Portal are the same five the interface works with.
Field reference
String limits are the longest value CRIBWISE accepts. Numbers are integers unless stated otherwise. “Must exist” means the value is checked against the CRIBWISE database, and the call fails validation if it is not found.
Order — Create
| Field | Type and limit | Must exist | What it is |
|---|---|---|---|
VendorId |
string, 50 | Yes | The vendor ID from the vendor detail. This is the service vendor the items go to. |
StockName |
string, 50 | Yes | The name of the stock the items sit in, not a numeric ID. |
DeviceId |
string, 50 | Yes | The device ID from the device detail. Set it here for a device level order, or per item for a stock level order. |
Status |
string: Suggested, New, Active, Cancelled |
– | The status the order is created in. Leave it out to create the order as New. |
IsConsignment |
boolean | – | Marks the order as a consignment order. |
Reference |
string, 400 | – | Your own reference for the order. Shown as Purchase order reference in the Admin Portal. |
Notes |
string, 4000 | – | Free text notes on the order. |
CustomIdPrefix |
string, 10 | – | A prefix for the generated order ID. Letters and underscores only (a-z, A-Z, _). |
CustomShipToId |
string, 60 | – | The ship-to ID passed on to the vendor. |
SendOptions |
object | – | How, and in which format, to send the order to the vendor. |
ServiceOrderItems |
array | – | The lines to be serviced. |
SendOptions — Create
| Field | Type and limit | What it is |
|---|---|---|
Channel.IsB2B, Channel.IsFtp, Channel.IsEmail |
boolean | The channels the order is sent on. |
FTP.IsXml, FTP.IsPdf, FTP.IsExcel |
boolean | The formats written to the FTP server. |
FTP.PdfTemplateName, FTP.ExcelTemplateName |
string, 50 | The order templates used for the PDF and the Excel file. Must exist, and mandatory as soon as the matching format is switched on. |
Email.IsXml, Email.IsPdf, Email.IsExcel |
boolean | The formats attached to the email. |
Email.PdfTemplateName, Email.ExcelTemplateName |
string, 50 | The order templates used for the attachments. Must exist, and mandatory as soon as the matching format is switched on. |
ServiceOrderItems — Create
| Field | Type and limit | Must exist | What it is |
|---|---|---|---|
ItemId |
string, 50 | Yes | The item ID from the item detail. |
DeviceId |
string, 50 | Yes | The device this line is serviced from. Needed on stock level orders; leave it out when the device is set on the order. |
TotalQuantity |
integer | – | How much to send for service, in the item’s dispense unit of measure. Set it to 1 per serial number for a serialized item. |
SerialNumber |
string, 50 | Yes | The serial number to send for service. Mandatory for serialized items, and it has to be available for service in that device. |
Note |
string, 4000 | – | Free text note on the line. |
LineReference |
string, 400 | – | Your own reference for the line. |
Example request
{
"VendorId": "V-1001",
"StockName": "Central stock",
"DeviceId": "DEV-01",
"Status": "New",
"IsConsignment": false,
"Reference": "ERP-SO-88421",
"Notes": "Regrinding, standard geometry.",
"CustomIdPrefix": "ERP_",
"CustomShipToId": "SHIPTO-7",
"SendOptions": {
"Channel": {
"IsB2B": false,
"IsFtp": false,
"IsEmail": true
},
"Email": {
"IsXml": false,
"IsPdf": true,
"IsExcel": false,
"PdfTemplateName": "Service order PDF",
"ExcelTemplateName": ""
}
},
"ServiceOrderItems": [
{
"ItemId": "5725474",
"DeviceId": "",
"TotalQuantity": 4,
"SerialNumber": "",
"Note": "Second regrind.",
"LineReference": "ERP-SO-88421-10"
}
]
}
UpdateQuantity
| Field | Type and limit | What it is |
|---|---|---|
OrderId |
string, 50 | The order ID from the order detail. Mandatory, and it must exist. |
ServiceOrderItems[].Id |
string, 50 | The technical line ID, used instead of ItemId, DeviceId, and SerialNumber. |
ServiceOrderItems[].ItemId |
string, 50 | The item ID of the ordered item, used instead of Id. |
ServiceOrderItems[].DeviceId |
string, 50 | The target device, on stock level orders. Used instead of Id. |
ServiceOrderItems[].SerialNumber |
string, 50 | The serial number, for serialized items only. Used instead of Id. |
ServiceOrderItems[].TotalQuantity |
integer | The quantity sent for service, in the dispense unit of measure. |
ServiceOrderItems[].ReceivedQuantity |
integer | The quantity that has come back from the vendor. |
ServiceOrderItems[].ScrappedQuantity |
integer | The quantity the vendor scrapped instead of returning. |
Example request
{
"OrderId": "ERP_5-453-8907",
"ServiceOrderItems": [
{
"ItemId": "5725474",
"DeviceId": "DEV-01",
"SerialNumber": "",
"ReceivedQuantity": 3,
"ScrappedQuantity": 1,
"TotalQuantity": 4
}
]
}
UpdateOrder
This endpoint takes the same payload as its purchase order counterpart, and the contract marks both OrderId and Status as required — so include the status in every call, even when all you are changing is a date or a note.
| Field | Type and limit | What it is |
|---|---|---|
OrderId |
string, 50 | The order ID from the order detail. Required, and it must exist. |
Status |
string: Suggested, Active, Cancelled |
The status to move the order to. Required. |
ShippingDate |
date and time, UTC | When the items were shipped to the vendor. |
ReceivedByVendorDate |
date and time, UTC | When the vendor received them. |
TrackingNumber |
string, 50 | The carrier’s tracking number. |
Reference |
string, 400 | Your own reference for the order. |
Notes |
string, 4000 | Free text notes on the order. |
CustomShipToId |
string, 60 | The ship-to ID passed on to the vendor. |
Example request
{
"OrderId": "ERP_5-453-8907",
"Status": "Active",
"ShippingDate": "2026-08-25T11:19:49.957Z",
"ReceivedByVendorDate": "2026-08-27T08:02:11.000Z",
"TrackingNumber": "1Z999AA10123456784",
"Reference": "ERP-SO-88421",
"Notes": "Collected by the vendor's courier."
}
Check the contract on your own installation
Your Admin Portal host serves a Swagger page for these interfaces at [AP_base_uri]/ERP/swagger, and the raw definition at [AP_base_uri]/ERP/swagger/docs/v1. It lists the endpoints and the exact contract your version exposes, which is the quickest way to settle a question about a property name.
Tip: A property the contract does not list is dropped without an error. If a value never arrives in CRIBWISE and the request result shows no error against it, compare your payload with
ServiceOrderDto,ServiceOrderQuantityDto, orPurchaseOrderChangeDtoon that page — the last one is shared with the purchase order interface, which is why it carries no service-specific name.
Next steps
- Get the items out of the device — an operator has to pick the ordered items before they can go to the vendor. See How to pick items for a service order.
- Watch the order in the Admin Portal — the History tab of the order logs every status change your integration makes. See How to view and filter purchase orders.
- Let CRIBWISE raise the orders instead — scheduled service scripts create service orders from the items due for service, so your ERP only has to receive them. See How to set up scheduled purchase and service scripts.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
The call answered 200 but no order exists. |
The request is still queued, or it failed validation. A 200 only confirms that the request was accepted. |
GET GetRequestResult with the GUID and read the request status, then the object statuses and Errors. |
The order is reported as None with an error against StockName. |
A stock ID or a misspelled name was sent. The field takes the stock’s name. | Copy the exact name from Data management > Stock. |
| An item is rejected as not available for service. | The item is not in a service location, is not marked for service, its item definition does not allow service, or the quantity asked for exceeds what is available. | Check the item and the quantity available for service in that device, then resend the line. |
| A quantity update is accepted but nothing changes. | The field cannot be changed while the order is in its current status. | Check the quantity table in step 3: TotalQuantity only while the order is New or Suggested, ReceivedQuantity and ScrappedQuantity only while it is Active. |
A new serial number sent to UpdateQuantity is ignored. |
Serial numbers can only be set when the order is created. | Create a second service order for the extra serial numbers. |
| The order was created but never reached the vendor. | The order is still New or Suggested, or it carries no send options. | Set Status to Active with UpdateOrder, and check that SendOptions names a channel and a template. |
| The order is not in the Admin Portal order list. | The list filters on New, Suggested, and Active by default. | Widen the status filter above the list, then select Search. |
| A value never arrives in CRIBWISE and no error is reported against it. | The property is not in the contract, so it was dropped silently. | Compare your payload with the DTOs on [AP_base_uri]/ERP/swagger. |
Related articles
- CRIBWISE REST API endpoint overview — every endpoint in the ERP REST interfaces, and how a call is authenticated.
- How to authenticate with the REST API — how to create an API key and exchange it for a bearer token.
- How to manage purchase orders with the REST API — the same four endpoints for purchase orders, with their own payload.
- Understanding purchasing and service workflows — how CRIBWISE chooses between a purchase order, a service order, a service list, and a transfer list.
- Understanding service lists — what happens instead when the service vendor is internal.
- How to pick items for a service order — how an operator gets the ordered items out of the device.
- How to configure units of measure — the dispense unit that every service order quantity is expressed in.



