An advance ship notice (ASN) is a vendor's declaration of what is on its way against a confirmed production order. The brand accepts the declaration, and the brand or its 3PL then raises the goods receipt the warehouse counts against.
The same endpoints serve both sides. A vendor login may create, announce, update and cancel its own notices; accepting a notice and receiving against it are brand actions.
$ curl https://api.uphance.com/inbound_shipment_notices \
-H "Authorization: Bearer ACCESS_TOKEN"
For POST, PUT and PATCH requests also send Content-Type: application/json.
The notice lifecycle
A notice moves through four states:
draft : editable, and invisible to the brand. Quantities can be changed freely.
announced : the declaration is frozen. A change from here means a new, superseding notice.
accepted : the brand has agreed. The promised date becomes the plan's date, and a goods receipt may now be raised.
cancelled : retired. The quantity returns to what may still be announced.
A fifth state, superseded, is set on a notice that a revision replaced.
Check what may be announced
Returns one row per SKU on the order, with the quantity still available to announce already netted against every other open notice. The response also carries the product identifier, colour and size for each SKU, so it doubles as the lookup you need to build a notice.
$ curl https://api.uphance.com/production_orders/PRODUCTION_ORDER_ID/announceable_quantities \
-H "Authorization: Bearer ACCESS_TOKEN"
Optional parameters:
excluding_notice_id (integer): exclude one notice from the netting. Pass the id of the draft you are editing, or the figures will shrink by the declaration you are about to resend. An id that does not belong to this order is ignored.
Example response:
{
"production_order_id": 3312,
"announceable_quantities": [
{
"sku_id": 8821,
"sku_number": "SHIRT-01-NAVY-M",
"product_identifier": "SHIRT-01",
"colour": "Navy",
"size": "M",
"remaining": 500
}
]
}
Create an advance ship notice
Creates a notice against a confirmed production order. The notice is created as a draft; nothing is communicated to the brand until it is announced.
$ curl -X POST https://api.uphance.com/production_orders/PRODUCTION_ORDER_ID/inbound_shipment_notices \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d @notice.json
Example Request Body:
{
"announce": true,
"inbound_shipment_notice": {
"reference": "ASN-4471",
"warehouse_id": 12,
"promised_in_warehouse_date": "2026-12-01",
"carrier_name": "Maersk",
"bill_of_lading": "MAEU123456",
"tracking_number": "1Z999AA10123456784"
},
"lines": [
{ "sku_id": 8821, "declared_quantity": 300 },
{
"product_identifier": "SHIRT-01",
"colour": "Navy",
"size": "L",
"declared_quantity": 200
}
]
}
Each entry in lines identifies a SKU in one of two ways: by sku_id, or by the product_identifier, colour and size triple, which is matched against the order's own lines case- and whitespace-insensitively. A line that matches nothing on the order is rejected and the whole request fails, so a successful response means every line you sent was recorded.
Set announce to true to create and announce in a single request; If the announcement is refused, the notice is not created at all — you receive the refusal rather than a stranded draft. announce sits at the top level of the body, not inside
inbound_shipment_notice.
warehouse_id and promised_in_warehouse_date are filled in from the production order when omitted.
Example response:
{
"inbound_shipment_notice": {
"id": 4471,
"reference": "ASN-4471",
"status": "announced",
"display_name": "ASN-4471",
"production_order_id": 3312,
"production_order_number": 876,
"line_group_id": null,
"manufacturer_id": null,
"manufacturer_name": null,
"warehouse_id": 12,
"warehouse_name": "Rotterdam DC",
"container_id": null,
"promised_in_warehouse_date": "2026-12-01T00:00:00.000Z",
"tracking_number": "1Z999AA10123456784",
"bill_of_lading": "MAEU123456",
"carrier_name": "Maersk",
"notes": null,
"keyed_on_behalf": true,
"announced_at": "2026-08-27T08:32:57.000Z",
"accepted_at": null,
"cancelled_at": null,
"superseded_by_id": null,
"created_at": "2026-08-27T08:32:57.000Z",
"updated_at": "2026-08-27T08:32:57.000Z",
"declared_quantity": 500,
"received_quantity": 0,
"outstanding_quantity": 500,
"receipt_count": 0,
"receipted_quantity": 0,
"uncounted_quantity_by_sku_id": { "8821": 300, "8822": 200 },
"receipts": [],
"lines": [
{
"id": 15571,
"sku_id": 8821,
"sku_number": "SHIRT-01-NAVY-M",
"ean": "5060123456789",
"product_identifier": "SHIRT-01",
"colour": "Navy",
"size": "M",
"declared_quantity": 300
}
]
}
}
List all advance ship notices
Returns the notices for the current organisation, ordered by promised date with undated notices last. A vendor login sees only its own company's notices. Results are limited to 50 notices per page.
$ curl https://api.uphance.com/inbound_shipment_notices?window=overdue \
-H "Authorization: Bearer ACCESS_TOKEN"
Optional parameters:
status(string): one ofdraft,announced,accepted,superseded,cancelled. An unrecognised value is ignored.window(string):overduereturns announced or accepted notices past their promised date that are still short.weekreturns open notices arriving in the next seven days.warehouse_id(integer): notices arriving into one warehouse.production_order_id(integer): notices against one production order.q(string): matches the notice reference.since_id(integer): notices with an id higher than this.since_created_at(date): notices created after this date.page(integer): page of results.
Each notice in the list carries declared_quantity, received_quantity, outstanding_quantity and receipt_count, so a list request is enough to find shipments that are short. The declaration lines, the receipts and the receive prefill are returned only when retrieving a single notice.
Example response:
{
"inbound_shipment_notices": [
{
"id": 4471,
"reference": "ASN-4471",
"status": "accepted",
"display_name": "ASN-4471",
"production_order_id": 3312,
"production_order_number": 876,
"warehouse_id": 12,
"warehouse_name": "Rotterdam DC",
"promised_in_warehouse_date": "2026-12-01T00:00:00.000Z",
"tracking_number": "1Z999AA10123456784",
"bill_of_lading": "MAEU123456",
"carrier_name": "MSC",
"keyed_on_behalf": true,
"announced_at": "2026-08-27T08:32:57.000Z",
"accepted_at": "2026-08-27T08:32:58.000Z",
"cancelled_at": null,
"declared_quantity": 250,
"received_quantity": 0,
"outstanding_quantity": 250,
"receipt_count": 0
}
],
"meta": {
"current_page": 1,
"next_page": null,
"prev_page": null,
"total_pages": 1,
"total_count": 1
}
}
Retrieve a single advance ship notice
Returns everything the list returns, plus the declaration lines, the receipts raised against the notice, and the quantities still to count.
$ curl https://api.uphance.com/inbound_shipment_notices/NOTICE_ID \
-H "Authorization: Bearer ACCESS_TOKEN"
Example response:
{
"inbound_shipment_notice": {
"id": 4471,
"status": "accepted",
"declared_quantity": 250,
"received_quantity": 0,
"outstanding_quantity": 250,
"receipt_count": 1,
"receipted_quantity": 250,
"uncounted_quantity_by_sku_id": { "8821": 250 },
"receipts": [
{
"id": 9032,
"delivery_number": "876_A",
"in_warehouse_date": "2026-12-01T00:00:00.000Z",
"declared_quantity": 250,
"counted_quantity": 0,
"checked_in": false,
"external_reference": "PO876-ARRIVAL-1"
}
],
"lines": [
{
"id": 15571,
"sku_id": 8821,
"sku_number": "SHIRT-01-NAVY-M",
"ean": "5060123456789",
"product_identifier": "SHIRT-01",
"colour": "Navy",
"size": "M",
"declared_quantity": 250
}
]
}
}
received_quantity is what has been counted on the movements ledger. receipted_quantity is what receipts claim, whether counted or not — a receipt can sit uncounted for days while the goods are in transit, so the two figures answer different questions.
Update an advance ship notice
Changes a notice that is still a draft. Announcing freezes the declaration, so an announced notice cannot be updated.
$ curl -X PATCH https://api.uphance.com/inbound_shipment_notices/NOTICE_ID \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d @changes.json
Example Request Body:
{
"inbound_shipment_notice": { "carrier_name": "MSC" },
"lines": [ { "sku_id": 8821, "declared_quantity": 250 } ]
}To take a declaration down to nothing but keep the line, send declared_quantity as 0. To remove a line entirely, send "_destroy": true with its sku_id.
Discard an advance ship notice
Deletes a notice that is still a `draft`. Use cancel for a notice that has been announced.
$ curl -X DELETE https://api.uphance.com/inbound_shipment_notices/NOTICE_ID \
-H "Authorization: Bearer ACCESS_TOKEN"
Example response:
{ "inbound_shipment_notice": { "id": 4471, "status": "deleted" } }
Announce an advance ship notice
Freezes the declaration and notifies the brand. Where a 3PL integration is connected, the notice is pushed to it at this point. The request takes no body, and sending it twice cannot announce, notify or push twice.
$ curl -X PUT https://api.uphance.com/inbound_shipment_notices/NOTICE_ID/announce \
-H "Authorization: Bearer ACCESS_TOKEN"
An announcement is refused in three ways, and the status code distinguishes them:
422— the notice declares nothing. Add quantities and send the request again.503with aRetry-Afterheader — another request reached the notice first and it is still a draft. Send the identical request again.409— the notice has already been announced. Do not retry.
Accept an advance ship notice
Records the brand's agreement to the declaration, and makes the vendor's promised date the plan's date. Acceptance can re-chain dates on the production order and open a commit-date-change approval. The request takes no body.
Accepting is a brand action. A vendor login receives 403.
$ curl -X PUT https://api.uphance.com/inbound_shipment_notices/NOTICE_ID/accept \
-H "Authorization: Bearer ACCESS_TOKEN"
A notice that is not announced returns 409 — another request has already accepted or cancelled it, and retrying will not help.
Cancel an advance ship notice
Retires a notice and returns its quantity to what may still be announced. The request takes no body.
A vendor login may cancel its own notice while it is draft or announced. Once the brand has accepted, only a brand login may cancel it.
$ curl -X PUT https://api.uphance.com/inbound_shipment_notices/NOTICE_ID/cancel \
-H "Authorization: Bearer ACCESS_TOKEN"
A notice with a goods receipt against it cannot be cancelled and returns 422: that stock has been counted, so the declaration underneath it cannot be voided.
Receive an advance ship notice
Raises a goods receipt from the announcement. A notice may be received by several receipts when a shipment arrives split
Receiving is a brand action. A vendor login receives 403. The notice must be accepted; if goods arrive before anyone has accepted, accept the notice first.
$ curl -X POST https://api.uphance.com/inbound_shipment_notices/NOTICE_ID/receive \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d @receipt.json
Example Request Body:
{
"quantities": { "8821": 250 },
"external_reference": "PO876-ARRIVAL-1"
}
Optional parameters:
quantities(object): the units arriving on this receipt, keyed by SKU id. Anything the notice did not declare is ignored. Omit it to receive whatever is still uncounted.external_reference(string): your own reference for this arrival. Send one.
When external_reference is sent, a repeat of the same request returns the receipt it already raised — 201 for a new receipt, 200 for one that already exists. The reference is scoped to the notice.
The receipt is returned uncounted. Count it in with the Goods Receipts API
Example response:
{
"goods_receipt": {
"id": 9032,
"in_warehouse_date": "2026-12-01T00:00:00.000Z",
"organisation_id": 1,
"production_order_id": 3312,
"production_order_number": 876,
"warehouse": "Rotterdam DC",
"delivery_name": "A",
"vendor": "Acme Garments Ltd",
"status": "not checked in",
"total_quantity": 250,
"reference": "ASN-4471",
"tracking_number": "1Z999AA10123456784",
"carrier": "MSC",
"source": "vendor_asn",
"inbound_shipment_notice_id": 4471,
"external_reference": "PO876-ARRIVAL-1",
"line_items": []
}
}
Find goods receipts raised from an advance ship notice
Every goods receipt records where it came from, so there is no need to keep your own mapping between announcements and receipts. Add asn=true to list only receipts raised from an advance ship notice.
$ curl https://api.uphance.com/goods_receipts?asn=true \
-H "Authorization: Bearer ACCESS_TOKEN"
Each receipt carries source ( vendor_asn for a receipt raised from a notice),
inbound_shipment_notice_id, and the external_reference it was raised with.
Errors
Every error returns an `error` message. The status code carries the meaning:
403— your login may not take this action, or the features this API needs are not enabled.404— no such notice, including a notice belonging to another vendor.409— the notice is not in a state this action can act on. Retrying will not help.422— the request could not be accepted. Correct it and send it again.503— a temporary collision. Send the identical request again after theRetry-Afterdelay.
Reference supporting endpoints
GET /production_orders— the orders you may announce against.GET /production_orders/PRODUCTION_ORDER_ID— one order, with its lines and SKUs.GET /warehouses— warehouse ids forwarehouse_id.GET /manufacturers— manufacturer ids formanufacturer_id.
