OptiWMS API 1.0.0. Every operation and store callback from the OpenAPI document.
Base URL https://api.optiwms.com/store/v1/. Field names are camelCase on the OptiWMS API; dashboard notification webhooks use snake_case and a separate signing scheme (see Webhooks).
Calls into OptiWMS
Signed requests your store sends to api.optiwms.com.
Answers when the signature verifies, with the integration's name and
the warehouse its orders go to. Make this call work before any other:
a 401 here means the signing is wrong, not the data.
`warehouse` is null when no warehouse is chosen for the integration.
Orders then go to the organization's first warehouse, so ask an
administrator to choose one in the dashboard before you send orders.
Response 200
The signature verified.
Field
Type
Required
Description
integration
object
yes
warehouse
object
yes
The warehouse this integration's orders go to; null when none is chosen.
The integration ID is unknown, or the signature or timestamp did not
verify. The body is empty on purpose. Check the integration ID, the
secret, the full path you signed (encoded as sent), the exact body
bytes and your clock; the signature checker on the integration page
shows which.
Response 410
The integration is disabled or archived. The body is empty. Stop
sending; an administrator can turn it back on in the dashboard.
Response 429
More than 300 calls in a minute for this integration. Wait the seconds in `Retry-After`, then send again.
Field
Type
Required
Description
error
object
yes
Response 429: rateLimited
{
"error": {
"code": "RATE_LIMITED",
"message": "This store has sent more than 300 calls in a minute. Wait 42 seconds (the Retry-After header), then send the call again.",
"details": [],
"requestId": "3f6c2b1e-8d4a-4c1f-9b7e-2a5d6e8f9a10"
}
}
Response 500
A problem on OptiWMS's side; nothing was changed. Send the call again in a minute; if it keeps failing, contact support with the request id.
Field
Type
Required
Description
error
object
yes
Response 500: internal
{
"error": {
"code": "INTERNAL",
"message": "OptiWMS could not complete this call because of a problem on its side. Send the call again in a minute; if it keeps failing, contact OptiWMS support with this request id.",
"details": [],
"requestId": "3f6c2b1e-8d4a-4c1f-9b7e-2a5d6e8f9a10"
}
}
Sends up to 250 variants. Send a variant whenever it is created or
changes in your store; sending one that has not changed is safe and
answers `unchanged`, so a retry after a timeout does no harm.
OptiWMS matches each variant to its own products by SKU. A SKU it
already holds is linked to that product; a new SKU creates a product.
A variant without a SKU is created under a placeholder SKU and
linked by its variantId, so orders for it still import. Draft and
archived variants are skipped unless the integration is set to
include unpublished products. When product sync is off for the
integration in the dashboard, every variant is skipped.
The answer lists, for each variant, what happened, in the order sent.
A SKU OptiWMS already holds for a different product is skipped and
raised as a question in the dashboard for staff to settle.
Request body
Field
Type
Required
Description
variants
array
yes
Request example: A tee in two sizes and a gift card
Every variant was handled; `results` says how, in the order sent.
Field
Type
Required
Description
results
array
yes
Response 200: Two variants created, the gift card skipped
{
"results": [
{
"variantId": "301",
"outcome": "created"
},
{
"variantId": "302",
"outcome": "created"
},
{
"variantId": "250",
"outcome": "skipped",
"reason": "Not shipped. Gift cards, digital products and services are not warehouse stock."
}
]
}
Response 200: The same call sent again
{
"results": [
{
"variantId": "301",
"outcome": "unchanged"
},
{
"variantId": "302",
"outcome": "unchanged"
},
{
"variantId": "250",
"outcome": "skipped",
"reason": "Not shipped. Gift cards, digital products and services are not warehouse stock."
}
]
}
Response 400
The body is not valid. Nothing was changed; fix the fields listed
in `details` and send the whole call again. More than 250
variants is also refused here: split them over several calls.
Field
Type
Required
Description
error
object
yes
Response 400: invalid
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Some fields of the request body are missing or not valid. Fix the fields listed in details and send the call again.",
"details": [
{
"path": "variants[0].variantId",
"message": "Required: your store's id for this variant; for a product sold in one form, send the product id again."
},
{
"path": "variants[0].status",
"message": "Required: one of active, draft or archived."
}
],
"requestId": "3f6c2b1e-8d4a-4c1f-9b7e-2a5d6e8f9a10"
}
}
Response 401
The integration ID is unknown, or the signature or timestamp did not
verify. The body is empty on purpose. Check the integration ID, the
secret, the full path you signed (encoded as sent), the exact body
bytes and your clock; the signature checker on the integration page
shows which.
Response 410
The integration is disabled or archived. The body is empty. Stop
sending; an administrator can turn it back on in the dashboard.
Response 413
The body is over 1 MiB. A request that declares its length gets this
small JSON body and no request id; one sent without a length gets an
empty body. Send fewer variants per call.
Field
Type
Required
Description
error
string
yes
Response 413: tooLarge
{
"error": "request body too large: this endpoint accepts at most 1 MiB"
}
Response 429
More than 300 calls in a minute for this integration. Wait the seconds in `Retry-After`, then send again.
Field
Type
Required
Description
error
object
yes
Response 429: rateLimited
{
"error": {
"code": "RATE_LIMITED",
"message": "This store has sent more than 300 calls in a minute. Wait 42 seconds (the Retry-After header), then send the call again.",
"details": [],
"requestId": "3f6c2b1e-8d4a-4c1f-9b7e-2a5d6e8f9a10"
}
}
Response 500
A problem on OptiWMS's side; nothing was changed. Send the call again in a minute; if it keeps failing, contact support with the request id.
Field
Type
Required
Description
error
object
yes
Response 500: internal
{
"error": {
"code": "INTERNAL",
"message": "OptiWMS could not complete this call because of a problem on its side. Send the call again in a minute; if it keeps failing, contact OptiWMS support with this request id.",
"details": [],
"requestId": "3f6c2b1e-8d4a-4c1f-9b7e-2a5d6e8f9a10"
}
}
Mark variants or products as removed from your store
Call this when variants or whole products are deleted in your store.
OptiWMS keeps its products and their stock (the goods are still on
the shelves) and stops sending stock levels for them. Ids OptiWMS
has never seen are ignored, so sending a delete twice is safe.
Send `variantIds`, `productIds` or both, up to 250 of each. A product
id removes every variant of that product.
Request body
Field
Type
Required
Description
variantIds
array
no
productIds
array
no
Request example: One variant and one whole product
Done. `removed` counts the variants OptiWMS knew and has now marked removed.
Field
Type
Required
Description
removed
integer
yes
The variants OptiWMS knew and has now marked removed.
Response 200: removeVariants
{
"removed": 2
}
Response 400
The body is not valid. Nothing was changed; fix the fields listed in `details` and send again.
Field
Type
Required
Description
error
object
yes
Response 400: invalid
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Some fields of the request body are missing or not valid. Fix the fields listed in details and send the call again.",
"details": [
{
"path": "variantIds",
"message": "Send at least one id in variantIds or productIds."
}
],
"requestId": "3f6c2b1e-8d4a-4c1f-9b7e-2a5d6e8f9a10"
}
}
Response 401
The integration ID is unknown, or the signature or timestamp did not
verify. The body is empty on purpose. Check the integration ID, the
secret, the full path you signed (encoded as sent), the exact body
bytes and your clock; the signature checker on the integration page
shows which.
Response 410
The integration is disabled or archived. The body is empty. Stop
sending; an administrator can turn it back on in the dashboard.
Response 413
The body is over 1 MiB. A request that declares its length gets this
small JSON body and no request id; one sent without a length gets an
empty body. Send fewer variants per call.
Field
Type
Required
Description
error
string
yes
Response 413: tooLarge
{
"error": "request body too large: this endpoint accepts at most 1 MiB"
}
Response 429
More than 300 calls in a minute for this integration. Wait the seconds in `Retry-After`, then send again.
Field
Type
Required
Description
error
object
yes
Response 429: rateLimited
{
"error": {
"code": "RATE_LIMITED",
"message": "This store has sent more than 300 calls in a minute. Wait 42 seconds (the Retry-After header), then send the call again.",
"details": [],
"requestId": "3f6c2b1e-8d4a-4c1f-9b7e-2a5d6e8f9a10"
}
}
Response 500
A problem on OptiWMS's side; nothing was changed. Send the call again in a minute; if it keeps failing, contact support with the request id.
Field
Type
Required
Description
error
object
yes
Response 500: internal
{
"error": {
"code": "INTERNAL",
"message": "OptiWMS could not complete this call because of a problem on its side. Send the call again in a minute; if it keeps failing, contact OptiWMS support with this request id.",
"details": [],
"requestId": "3f6c2b1e-8d4a-4c1f-9b7e-2a5d6e8f9a10"
}
}
What OptiWMS holds for an order this integration sent, and where it
is. Use it to recover after a lost answer (did the order arrive, did
it ship) and to learn when a released order is `pending` again.
`status` is one of `pending` (waiting for the warehouse), `picking`,
`packing`, `partially_shipped`, `shipped` or `canceled`.
`shipments` lists every parcel that has left, with its tracking and
the lines it carried. It reads only orders this integration sent; an
order another integration sent answers 404.
Parameters
Name
In
Required
Description
orderId
path
yes
Your store's id for the order, percent-encoded in the path.
The integration ID is unknown, or the signature or timestamp did not
verify. The body is empty on purpose. Check the integration ID, the
secret, the full path you signed (encoded as sent), the exact body
bytes and your clock; the signature checker on the integration page
shows which.
Response 404
OptiWMS holds no order with this id from this integration
(`ORDER_NOT_FOUND`). If you expected it, send it with
`PUT /orders/{orderId}`; it is safe to send an order again.
Field
Type
Required
Description
error
object
yes
Response 404: unknown
{
"error": {
"code": "ORDER_NOT_FOUND",
"message": "OptiWMS holds no order #9999 from this store. Send it with PUT orders/{orderId} if it should ship.",
"details": [],
"requestId": "3f6c2b1e-8d4a-4c1f-9b7e-2a5d6e8f9a10"
}
}
Response 410
The integration is disabled or archived. The body is empty. Stop
sending; an administrator can turn it back on in the dashboard.
Response 429
More than 300 calls in a minute for this integration. Wait the seconds in `Retry-After`, then send again.
Field
Type
Required
Description
error
object
yes
Response 429: rateLimited
{
"error": {
"code": "RATE_LIMITED",
"message": "This store has sent more than 300 calls in a minute. Wait 42 seconds (the Retry-After header), then send the call again.",
"details": [],
"requestId": "3f6c2b1e-8d4a-4c1f-9b7e-2a5d6e8f9a10"
}
}
Response 500
A problem on OptiWMS's side; nothing was changed. Send the call again in a minute; if it keeps failing, contact support with the request id.
Field
Type
Required
Description
error
object
yes
Response 500: internal
{
"error": {
"code": "INTERNAL",
"message": "OptiWMS could not complete this call because of a problem on its side. Send the call again in a minute; if it keeps failing, contact OptiWMS support with this request id.",
"details": [],
"requestId": "3f6c2b1e-8d4a-4c1f-9b7e-2a5d6e8f9a10"
}
}
Send an order once it is paid and ready to ship, and again whenever
it changes. The body is always the whole current order, never a
change list. Send only orders that are ready to ship: an order your
store has not been paid for is simply not sent yet.
What OptiWMS does with the body:
- A new order is imported: 201 `created`.
- The same as the last version you sent: 200 `unchanged`. Only what
the warehouse acts on counts as a change: the lines (id, SKU or
variantId, quantity), the delivery address, the customer's name,
email and phone, and the shipping method's code and name. A
different note, price, total or `updatedAt` alone answers
`unchanged` and leaves the order as it is. The comparison is with
the last version you sent, not with the order as OptiWMS holds it.
- Older than the version OptiWMS has applied (its `updatedAt` is
earlier): 200 `stale`, nothing changes.
- Changed, and the warehouse has not started on it: applied (lines
rebuilt, address and customer refreshed). 200 `updated`.
- Changed, and the warehouse has started on it (the order is in a
pick, wave or pack, has a shipping label, or has been handed to a
shipping platform): 409
`ORDER_IN_FULFILLMENT`. Nothing on the order changes, and OptiWMS
raises an Order edited task naming what your store wanted
changed, so the warehouse sees it even if your code only logs the
409. When staff cancel the pick, `GET /orders/{orderId}` shows
`pending` again; then send the order again and it applies as an
update.
- Changed, and shipped: 409 `ORDER_SHIPPED`. Changed, and canceled
in OptiWMS: 409 `ORDER_CANCELED`.
- Canceled with `POST /orders/{orderId}/cancel` before OptiWMS ever
saw it: not imported, 200 `canceled`.
Lines whose SKU OptiWMS does not know are imported as held lines and
raised as product questions in the dashboard; the rest of the order
goes ahead. An order carries at most 250 lines.
Parameters
Name
In
Required
Description
orderId
path
yes
Your store's id for the order, as your store writes it. Percent-encode
it in the path (`#1001` travels as `%231001`) and sign the encoded
path.
Request body
Field
Type
Required
Description
number
string
yes
The order number your staff and customers see, such as `#1001`.
createdAt
string
no
An ISO 8601 time with its offset.
updatedAt
string
no
An ISO 8601 time with its offset.
currency
string
yes
The ISO 4217 code of every amount in the order, such as `AUD`.
customer
object
no
shipTo
object
no
shipping
object
no
The shipping method the customer chose. OptiWMS maps `code` and `name` to a carrier service in the dashboard's shipping settings.
The order was known. `status` says what happened: `unchanged`
(nothing the warehouse acts on changed), `stale` (older than the
version applied), `updated` (the change was applied) or
`canceled` (canceled before OptiWMS saw it; not imported).
The body is not valid. Nothing was imported or changed; fix the fields listed in `details` and send the order again.
Field
Type
Required
Description
error
object
yes
Response 400: invalid
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Some fields of the request body are missing or not valid. Fix the fields listed in details and send the call again.",
"details": [
{
"path": "number",
"message": "Required: the order number your staff and customers see, such as #1001."
},
{
"path": "currency",
"message": "Required: the three-letter ISO 4217 currency code in capitals, such as AUD."
},
{
"path": "lines[0].quantity",
"message": "Send a quantity of at least 1; leave out a line with nothing to ship."
}
],
"requestId": "3f6c2b1e-8d4a-4c1f-9b7e-2a5d6e8f9a10"
}
}
Response 401
The integration ID is unknown, or the signature or timestamp did not
verify. The body is empty on purpose. Check the integration ID, the
secret, the full path you signed (encoded as sent), the exact body
bytes and your clock; the signature checker on the integration page
shows which.
Response 409
The order changed, but OptiWMS cannot apply the change. Nothing on
the order changed.
- `ORDER_IN_FULFILLMENT`: the warehouse has started on the order.
OptiWMS has raised an Order edited task for staff. Once they
cancel the pick, `GET /orders/{orderId}` shows `pending`; send
the order again then.
- `ORDER_SHIPPED`: the order has shipped. Arrange any change with
the customer outside OptiWMS.
- `ORDER_CANCELED`: the order is canceled in OptiWMS and will not
ship; OptiWMS has sent your store the orderCancel call. Treat it
as canceled, and contact the warehouse if it should ship after
all.
Field
Type
Required
Description
error
object
yes
Response 409: inFulfillment
{
"error": {
"code": "ORDER_IN_FULFILLMENT",
"message": "The warehouse has started on this order, so the change cannot apply yet. An Order edited task now tells the warehouse what your store wanted changed (the lines); when staff release the order (GET /orders/{orderId} shows pending), send it again.",
"details": [],
"requestId": "3f6c2b1e-8d4a-4c1f-9b7e-2a5d6e8f9a10"
}
}
Response 409: shipped
{
"error": {
"code": "ORDER_SHIPPED",
"message": "This order has shipped, so the change to its delivery address was not applied. Arrange the change with the customer directly.",
"details": [],
"requestId": "3f6c2b1e-8d4a-4c1f-9b7e-2a5d6e8f9a10"
}
}
Response 409: orderCanceled
{
"error": {
"code": "ORDER_CANCELED",
"message": "This order is canceled in OptiWMS and will not ship, so the change was not applied. Treat it as canceled in your store, and contact the warehouse if it should ship after all.",
"details": [],
"requestId": "3f6c2b1e-8d4a-4c1f-9b7e-2a5d6e8f9a10"
}
}
Response 410
The integration is disabled or archived. The body is empty. Stop
sending; an administrator can turn it back on in the dashboard.
Response 413
The body is over 1 MiB. A request that declares its length gets this
small JSON body and no request id; one sent without a length gets an
empty body. Send fewer variants per call.
Field
Type
Required
Description
error
string
yes
Response 413: tooLarge
{
"error": "request body too large: this endpoint accepts at most 1 MiB"
}
Response 429
More than 300 calls in a minute for this integration. Wait the seconds in `Retry-After`, then send again.
Field
Type
Required
Description
error
object
yes
Response 429: rateLimited
{
"error": {
"code": "RATE_LIMITED",
"message": "This store has sent more than 300 calls in a minute. Wait 42 seconds (the Retry-After header), then send the call again.",
"details": [],
"requestId": "3f6c2b1e-8d4a-4c1f-9b7e-2a5d6e8f9a10"
}
}
Response 500
A problem on OptiWMS's side; nothing was changed. Send the call again in a minute; if it keeps failing, contact support with the request id.
Field
Type
Required
Description
error
object
yes
Response 500: internal
{
"error": {
"code": "INTERNAL",
"message": "OptiWMS could not complete this call because of a problem on its side. Send the call again in a minute; if it keeps failing, contact OptiWMS support with this request id.",
"details": [],
"requestId": "3f6c2b1e-8d4a-4c1f-9b7e-2a5d6e8f9a10"
}
}
Cancels the order in OptiWMS, under the same rule as a change:
- Not started in the warehouse: canceled, 200 `canceled`.
- Already canceled: 200 `unchanged`.
- Never sent to OptiWMS: the cancel is recorded, so the order is not
imported if it arrives later. 200 `canceled`.
- Started in the warehouse: 409 `ORDER_IN_FULFILLMENT`. Ask the
warehouse to cancel the pick, then send the cancel again.
- Shipped: 409 `ORDER_SHIPPED`.
The body is optional. `reason` is kept with the cancel record of an
order OptiWMS has not received yet, so staff see why a later create
was not imported; for an order OptiWMS holds, the cancel itself is
what staff see and the reason is not stored.
Parameters
Name
In
Required
Description
orderId
path
yes
Your store's id for the order, as your store writes it. Percent-encode
it in the path (`#1001` travels as `%231001`) and sign the encoded
path.
Request body
Field
Type
Required
Description
reason
string
no
Why the order was canceled, shown to staff.
Request example: An order the warehouse has not started on
{
"reason": "Customer asked to cancel"
}
Request example: An order OptiWMS has not received yet
{
"reason": "Payment reversed"
}
Request example: The same cancel sent twice
{
"reason": "Customer asked to cancel"
}
Request example: An order being picked
{
"reason": "Customer asked to cancel"
}
Request example: An order that has shipped
{
"reason": "Customer asked to cancel"
}
Request example: A reason that is not text
{
"reason": 42
}
Response 200
`canceled`: the order is canceled now (or will not be imported). `unchanged`: it was already canceled.
Field
Type
Required
Description
status
string (canceled, unchanged)
yes
Response 200: canceled
{
"status": "canceled"
}
Response 200: canceledBeforeImport
{
"status": "canceled"
}
Response 200: alreadyCanceled
{
"status": "unchanged"
}
Response 400
The body is not valid. Nothing was canceled; fix the fields listed in `details` and send again.
Field
Type
Required
Description
error
object
yes
Response 400: invalid
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Some fields of the request body are missing or not valid. Fix the fields listed in details and send the call again.",
"details": [
{
"path": "reason",
"message": "Send the reason as text, or leave it out."
}
],
"requestId": "3f6c2b1e-8d4a-4c1f-9b7e-2a5d6e8f9a10"
}
}
Response 401
The integration ID is unknown, or the signature or timestamp did not
verify. The body is empty on purpose. Check the integration ID, the
secret, the full path you signed (encoded as sent), the exact body
bytes and your clock; the signature checker on the integration page
shows which.
Response 409
The order cannot be canceled in OptiWMS. Nothing changed.
- `ORDER_IN_FULFILLMENT`: the warehouse has started on the order.
Ask the warehouse to cancel the pick in OptiWMS, then send the
cancel again.
- `ORDER_SHIPPED`: the order has shipped; handle it as a return.
Field
Type
Required
Description
error
object
yes
Response 409: inFulfillment
{
"error": {
"code": "ORDER_IN_FULFILLMENT",
"message": "The warehouse has started on this order, so it was not canceled. Ask the warehouse to cancel the pick in OptiWMS, then send the cancel again.",
"details": [],
"requestId": "3f6c2b1e-8d4a-4c1f-9b7e-2a5d6e8f9a10"
}
}
Response 409: shipped
{
"error": {
"code": "ORDER_SHIPPED",
"message": "This order has shipped, so it was not canceled. Handle it as a return.",
"details": [],
"requestId": "3f6c2b1e-8d4a-4c1f-9b7e-2a5d6e8f9a10"
}
}
Response 410
The integration is disabled or archived. The body is empty. Stop
sending; an administrator can turn it back on in the dashboard.
Response 413
The body is over 1 MiB. A request that declares its length gets this
small JSON body and no request id; one sent without a length gets an
empty body. Send fewer variants per call.
Field
Type
Required
Description
error
string
yes
Response 413: tooLarge
{
"error": "request body too large: this endpoint accepts at most 1 MiB"
}
Response 429
More than 300 calls in a minute for this integration. Wait the seconds in `Retry-After`, then send again.
Field
Type
Required
Description
error
object
yes
Response 429: rateLimited
{
"error": {
"code": "RATE_LIMITED",
"message": "This store has sent more than 300 calls in a minute. Wait 42 seconds (the Retry-After header), then send the call again.",
"details": [],
"requestId": "3f6c2b1e-8d4a-4c1f-9b7e-2a5d6e8f9a10"
}
}
Response 500
A problem on OptiWMS's side; nothing was changed. Send the call again in a minute; if it keeps failing, contact support with the request id.
Field
Type
Required
Description
error
object
yes
Response 500: internal
{
"error": {
"code": "INTERNAL",
"message": "OptiWMS could not complete this call because of a problem on its side. Send the call again in a minute; if it keeps failing, contact OptiWMS support with this request id.",
"details": [],
"requestId": "3f6c2b1e-8d4a-4c1f-9b7e-2a5d6e8f9a10"
}
}
Calls OptiWMS makes to your store
POSTs to your registered base URL, signed the same way over the path your server receives.
OptiWMS calls POST {your base URL}/stock: a stock level changed
Sent whenever the stock OptiWMS can sell for a variant changes, after
the integration's buffer stock. `available` is the absolute figure to
set, never a change, so a late or repeated call is harmless. Calls
are retried with backoff until your endpoint accepts them, and a
newer level replaces one still waiting.
Find the variant by `variantId` when the call carries one: it is the
`variantId` you sent with `PUT /products`. A variant you sent without
a SKU gets a SKU OptiWMS makes up, which your store does not know, so
`sku` alone cannot find it. `variantId` is absent only for a product
that never came from `PUT /products`.
Answer any 2xx within 10 seconds to accept, with a JSON body (`{}` is
enough) or with 204 and no body. A 200 with an empty body counts as
no answer. Any other answer, or no answer in time, is retried. A 2xx
whose body is the error envelope (`{"error": {"code", "message"}}`,
optionally with `retryAfterSeconds`) counts as a failure.
Request body
Field
Type
Required
Description
sku
string
yes
The variant's SKU. For a variant you sent without one, a SKU OptiWMS made up; find the variant by `variantId` instead.
variantId
string
no
An id as your store writes it.
available
integer
yes
The units you may sell, after the integration's buffer stock. Set your store's count to this figure.
locationCode
string
no
Your store's code for the location the level is for, when the integration maps an OptiWMS warehouse to one of your store's locations. Absent otherwise.
OptiWMS calls POST {your base URL}/shipments: a shipment left the warehouse
Sent when a shipment of an order leaves the warehouse, listing the
lines (by your line id) and quantities it carried, so an order
shipped in several shipments sends one call per shipment.
`shipmentId` is OptiWMS's id for the shipment; keep it, because a
later tracking change names it. A shipment that went out in several
parcels is one call: `trackingNumber` is the first parcel's and
`moreTracking` lists the others.
Rarely, units packed after the first call (a remainder) are sent in
a second call with the same `shipmentId`, listing only the units it
adds. Every call carries `X-Idempotency-Key`, the same on each retry
of that call and different for the next one, so use it, not
`shipmentId`, to recognize a call you already applied.
An order that ships short and is closed with units left over is not
a store call: the shipments list only what shipped, and the
`order.short_shipped` notification webhook tells your system the
rest will not ship.
Answer any 2xx within 10 seconds to accept, with a JSON body (`{}` is
enough) or with 204 and no body; anything else is retried. When your
store keeps its own id for the shipment, answer with it as
`shipmentId`, and later tracking calls name your id instead of
OptiWMS's.
Request body
Field
Type
Required
Description
orderId
string
yes
An id as your store writes it.
shipmentId
string
yes
An id as your store writes it.
trackingNumber
string
yes
The first parcel's tracking number. Empty when the shipment left without tracking.
trackingUrl
string
yes
The first parcel's tracking page. Empty when there is none.
carrier
string
yes
The carrier's name. Empty when the shipment left without tracking.
shippedAt
string
yes
An ISO 8601 time with its offset.
lines
array
yes
moreTracking
array
no
The other parcels of a shipment that went out in several, each tracking number once. Absent for a single parcel.
OptiWMS calls POST {your base URL}/shipments/{shipmentId}/tracking: a parcel's tracking changed
Sent when the label of a parcel already reported is replaced and its
tracking changes, or when its tracking link arrives after the
number. `{shipmentId}` in the path is the id from the earlier
shipments call (yours, when you answered with one), percent-encoded.
`previousTrackingNumber` is the number this one replaces, so a
shipment of several parcels changes the right one; replace that
number in your store, or the shipment's only number when it is
absent.
Answer any 2xx within 10 seconds to accept, with a JSON body (`{}` is
enough) or with 204 and no body; anything else is retried.
Request body
Field
Type
Required
Description
trackingNumber
string
yes
The parcel's tracking number now.
trackingUrl
string
yes
Its tracking page. Empty when there is none.
carrier
string
yes
previousTrackingNumber
string
no
The number this one replaces; the same number when only the tracking page arrived. Absent when OptiWMS does not know it.
OptiWMS calls POST {your base URL}/orders/{orderId}/cancel: the warehouse canceled an order
Sent when staff cancel an order in OptiWMS. The warehouse will not
ship it: treat the order as canceled in your store. `{orderId}` in
the path is your store's order id, percent-encoded. Answer 2xx for
an order your store already shows as canceled too.
Answer any 2xx within 10 seconds to accept, with a JSON body (`{}` is
enough) or with 204 and no body; anything else is retried.
Request body
Field
Type
Required
Description
reason
string
no
Why the warehouse canceled the order.
Example: cancel
{
"reason": "Canceled in OptiWMS by the warehouse"
}
Connect your own store
Register the integration in the dashboard, then start with GET /ping.