The PrepWorx API lets you read your inventory and shipments, create, update and cancel inbound shipments, and create, update, track and cancel FBA outbound shipments. This page covers every available endpoint, authentication, warehouses, rate limits and errors.
All API requests require an API key. Send it in the x-api-key header on every request:
| Header | Value |
|---|---|
x-api-key | Your API key (e.g. pw_aa4_abc123...) |
Contact PrepWorx to turn on API access for your account. Your API key then appears in the PrepWorx portal under Settings → Integrations, where you can also regenerate or revoke it. Keep it confidential: anyone with the key can act on your account. Use it only from your own server, never in a web page or app your customers can see.
https://us-central1-prepworx-app.cloudfunctions.net
GET endpoints take query parameters. POST endpoints take a JSON body with Content-Type: application/json. Times are ISO 8601 in UTC.
curl -H "x-api-key: YOUR_KEY" \
"https://us-central1-prepworx-app.cloudfunctions.net/v1ListOutbounds?status=pending"
Limits apply per account and per endpoint, counted over a rolling hour. Over the limit, the API returns 429 Too Many Requests.
| Endpoint | Limit |
|---|---|
| Read (GET) endpoints | 300 requests per hour |
v1GetOutbound | 600 requests per hour |
createInboundShipment | 100 requests per hour |
v1UpdateInbound | 100 requests per hour |
v1CancelInbound | 100 requests per hour |
v1CreateFbaOutbound | 30 requests per hour |
v1UpdateOutbound | 30 requests per hour |
v1CancelOutbound | 60 requests per hour |
PrepWorx has two warehouses. Every inventory record, inbound and outbound belongs to one of them, identified by location:
| location | Warehouse |
|---|---|
1 | Independence, Oregon |
2 | Salem, Oregon |
location: everything goes to and ships from your home warehouse.location on createInboundShipment (where you're shipping to) and on v1CreateFbaOutbound (where it ships from). Only the stock at that warehouse counts toward an outbound.location out always means your home warehouse.400 and code UNKNOWN_LOCATION. The message lists the warehouses you can use.location (the number) and warehouse (its name). Records saved before warehouses were added report your home warehouse.?location=1 or ?location=2 to return one warehouse only.GET /getInventory
Returns all inventory items on your account. Optional ?location=1 or 2.
{
"success": true,
"count": 42,
"data": [
{ "id": "abc123", "asin": "B08N5WRWNW", "name": "Product Name",
"quantity": 100, "quantity_pending": 12, "total_on_hand": 112,
"location": 1, "warehouse": "Independence", "owner": "AA4" }
]
}
| Field | Description |
|---|---|
quantity | Units available to send |
quantity_pending | Units reserved by open outbound shipments (still in the warehouse) |
total_on_hand | quantity + quantity_pending: every unit physically at that warehouse |
location, warehouse | Which warehouse the stock is at |
Stock is kept per warehouse. If you use both, an ASIN stocked at both appears twice, once per warehouse; add them up for your total.
Inbound shipments are shipments you send to PrepWorx.
GET /getInboundShipments
| Parameter | Required | Description |
|---|---|---|
status | Optional | Filter by status (pending, processing, completed) |
location | Optional | 1 or 2: one warehouse only |
GET /getInboundShipment?id=<shipment id>
Each item includes units (expected) and units_received (counted so far by PrepWorx), so you can follow partial receiving. units minus units_received is what is still to arrive. The shipment includes location and warehouse.
POST /createInboundShipment
{
"reference": "PO-12345",
"origin": "Supplier Name",
"arrival": "2026-02-01",
"packages": 5,
"location": 2,
"shipment_notes": "Handle with care",
"tracking_numbers": ["1Z999AA10123456784"],
"items": [
{ "name": "Product Name", "asin": "B08N5WRWNW", "upc": "012345678901",
"units": 100, "purchase_price": 12.99, "notes": "Fragile" }
]
}
| Field | Required | Description |
|---|---|---|
reference | Yes | Your internal reference (e.g. PO number) |
origin | Yes | Where the shipment is coming from |
arrival | Yes | Expected arrival date (YYYY-MM-DD) |
packages | Yes | Number of packages/boxes, at least 1 |
items | Yes | Up to 500 items: name, asin and units required; upc, purchase_price, notes optional |
location | Optional | Warehouse you're shipping to: 1 or 2. Left out = your home warehouse |
tracking_numbers | Optional | List of carrier tracking numbers |
shipment_notes | Optional | Notes for the warehouse |
If an item's upc is blank, PrepWorx fills it in automatically where it can. Returns status 201; keep the id to look the shipment up later.
{ "success": true, "message": "Inbound shipment created",
"id": "Xy12AbC3dE4fGh5IjK6l", "shipment_id": "Xy12AbC3dE4fGh5IjK6l" }
POST /v1UpdateInbound
Changes an inbound shipment before PrepWorx starts receiving it. Send the id plus only the fields you want to change; anything you leave out stays as it is.
{
"id": "Xy12AbC3dE4fGh5IjK6l",
"packages": 6,
"tracking_numbers": ["1Z999AA10123456784", "1Z999AA10123456785"],
"items": [
{ "name": "Product Name", "asin": "B08N5WRWNW", "units": 120 },
{ "name": "Second Product", "asin": "B07XJ8C8F5", "units": 24 }
]
}
| Field | Required | Description |
|---|---|---|
id | Yes | The inbound shipment ID |
reference | Optional | Your internal reference |
origin | Optional | Where the shipment is coming from |
arrival | Optional | Expected arrival date (YYYY-MM-DD) |
packages | Optional | Number of packages/boxes, at least 1 |
shipment_notes | Optional | Notes, up to 1,000 characters |
tracking_numbers | Optional | The full list of tracking numbers (replaces the old list) |
items | Optional | The FULL new item list, same format as create. Include every item you are still sending; an item left out is removed. Each ASIN once. |
Works only while the shipment's status is draft or pending and no units have been received. After that the API returns 409 and changes go through PrepWorx. Status, received counts and the warehouse can't be changed through the API. Returns the updated shipment in data.
POST /v1CancelInbound
Cancels an inbound shipment PrepWorx hasn't started receiving (status draft or pending, no units received). The shipment is removed. After receiving starts, the API returns 409; contact PrepWorx instead.
Request: { "id": "Xy12AbC3dE4fGh5IjK6l" }
Response: { "success": true, "id": "Xy12AbC3dE4fGh5IjK6l", "cancelled": true }
The v1 outbound endpoints create FBA outbounds, change or cancel them before the warehouse starts work, and follow them through to shipment. All of them return outbounds in this shape. Fields with no value yet are null.
| Field | Type | Description |
|---|---|---|
id | string | PrepWorx outbound ID |
reference | string | Your reference |
workflow | string | Workflow name shown in the PrepWorx portal |
status | string | See Statuses below |
type | string | fba, fbm or standard |
location | number | Warehouse it ships from: 1 or 2 |
warehouse | string | Independence or Salem |
cancellable | boolean | true while the warehouse hasn't started, so cancel and update will succeed |
items[].msku | string | Your seller SKU |
items[].asin | string | ASIN |
items[].fnsku | string | FNSKU |
items[].name | string | Product name |
items[].units_requested | number | Units on the outbound |
items[].units_sent | number | Units shipped and billed |
amazon.inbound_plan_id | string | Amazon inbound plan ID (wf…). amazon is null for non-FBA outbounds |
amazon.shipments[] | list | One entry per Amazon shipment, filled in once Amazon assigns destinations |
.amazon_shipment_id | string | Shipment ID as Seller Central shows it (FBA15…) |
.amazon_internal_shipment_id | string | Amazon's API shipment ID (sh…) |
.destination_fulfillment_center | string | Amazon warehouse code, e.g. SMF3 |
.box_count | number | Boxes in that shipment |
.carrier | string | Carrier name |
.amazon_partnered_carrier | boolean | true for Amazon's partnered carrier |
.tracking_numbers | list | Tracking numbers |
timestamps.created_at | string | Created |
timestamps.updated_at | string | Last changed |
timestamps.processing_at | string | Packing finished, moved to shipping |
timestamps.shipped_at | string | Left the warehouse |
timestamps.finalized_at | string | Shipped and billed |
| Status | Meaning |
|---|---|
pending | Waiting for, or in, picking and packing |
processing | Packed; Amazon placement, carrier and labels in progress |
final | Shipped and billed |
hold | Paused by PrepWorx; we'll contact you |
void | Cancelled by PrepWorx |
For receiving progress at Amazon (units checked in, discrepancies), use the amazon_shipment_id in Seller Central or with Amazon's Selling Partner API.
GET /v1ListOutbounds
Returns your outbound shipments, newest first.
| Parameter | Required | Description |
|---|---|---|
status | Optional | Only this status, e.g. pending |
location | Optional | 1 or 2: one warehouse only |
updated_since | Optional | Only outbounds changed at or after this time, e.g. 2026-10-01T00:00:00Z |
limit | Optional | How many to return: default 100, maximum 500 |
{
"success": true,
"count": 1,
"total": 1,
"data": [ { "id": "lT5CoV3gB07nqp7ONTbM", "reference": "PO-2001", "status": "pending",
"location": 1, "warehouse": "Independence", ... } ]
}
count is how many are in data; total is how many matched before limit.
GET /v1GetOutbound?id=<outbound id>
Returns one outbound shipment. An ID that doesn't exist, or isn't yours, returns 404.
{
"success": true,
"data": {
"id": "lT5CoV3gB07nqp7ONTbM",
"reference": "PO-2001",
"workflow": "PO-2001",
"status": "processing",
"type": "fba",
"location": 1,
"warehouse": "Independence",
"cancellable": false,
"items": [
{ "msku": "1066366763", "asin": "B083RTRBZ6", "fnsku": "X004DG3LS1",
"name": "On Women's Cloud X Sneakers", "units_requested": 12, "units_sent": 0 }
],
"amazon": {
"inbound_plan_id": "wf52047ba8-4a53-4c9e-a7b6-91e34fafbd62",
"shipments": [
{ "amazon_shipment_id": "FBA15XXXXXXX", "amazon_internal_shipment_id": "sh8f2c...",
"destination_fulfillment_center": "SMF3", "box_count": 2, "carrier": "UPS",
"amazon_partnered_carrier": true, "tracking_numbers": ["1Z999AA10123456784"] }
]
},
"timestamps": {
"created_at": "2026-10-06T21:07:13.614Z", "updated_at": "2026-10-07T18:02:40.100Z",
"processing_at": "2026-10-07T17:55:12.000Z", "shipped_at": null, "finalized_at": null
}
}
}
POST /v1CreateFbaOutbound
Creates an FBA outbound at PrepWorx and its inbound plan in your Seller Central, in one call. The SKUs must already exist as FBA listings in your Seller Central; create new listings in the PrepWorx portal or Seller Central first. Stock is reserved for the outbound as soon as it's created.
{
"reference": "PO-2001",
"location": 1,
"items": [
{ "msku": "1066366763", "quantity": 12 },
{ "msku": "SKU-ABC", "quantity": 4, "expiration": "2027-06-30" }
]
}
| Field | Required | Description |
|---|---|---|
reference | Yes | Your reference, up to 100 characters. Also used as the Amazon plan name |
items[].msku | Yes | Your seller SKU, exactly as in Seller Central. Each SKU once per request; up to 200 SKUs |
items[].quantity | Yes | Whole number, at least 1 |
items[].expiration | Optional | YYYY-MM-DD, at least 120 days out. If Amazon requires a date for a product and you don't send one, PrepWorx uses a date two years out |
location | Optional | Warehouse it ships from: 1 or 2. Left out = your home warehouse |
PrepWorx checks these in order. The first problem stops the request, and nothing is created at Amazon:
location if sent.reference. This makes a retry after a timeout safe.Timing. Amazon takes 30 seconds to a few minutes to build a plan; keep the request open for up to 9 minutes. If your connection drops, retry with the same reference: if the first request went through, you receive DUPLICATE_REFERENCE with its existing_id instead of a second plan.
Returns status 201. data is a list: when Amazon requires some items to ship separately (often hazmat), split is true and data holds one outbound per group.
{
"success": true,
"split": false,
"message": "FBA outbound created.",
"data": [ { "id": "lT5CoV3gB07nqp7ONTbM", "reference": "PO-2001", "status": "pending",
"location": 1, "warehouse": "Independence", "cancellable": true,
"amazon": { "inbound_plan_id": "wf52047ba8-...", "shipments": [] }, ... } ]
}
POST /v1UpdateOutbound
Changes the items on an FBA outbound the warehouse hasn't started: add SKUs, change quantities or remove SKUs. PrepWorx then builds a new Amazon inbound plan with the new items, automatically. items is the FULL new list, in the same format as create: to add a SKU, send the current lines plus the new one; to change a quantity, send that line with the new quantity; leave a line out to remove it.
{
"id": "lT5CoV3gB07nqp7ONTbM",
"items": [
{ "msku": "1066366763", "quantity": 15 },
{ "msku": "SKU-ABC", "quantity": 4, "expiration": "2027-06-30" },
{ "msku": "SKU-NEW", "quantity": 6 }
]
}
| Field | Required | Description |
|---|---|---|
id | Yes | The outbound ID |
items[].msku | Yes | Your seller SKU, exactly as in Seller Central. Each SKU once; up to 200 SKUs. Each product (ASIN) may appear on one line only |
items[].quantity | Yes | Whole number, at least 1 |
items[].expiration | Optional | YYYY-MM-DD, at least 120 days out. If Amazon requires a date and you don't send one, PrepWorx uses a date two years out |
cancellable is true (nothing picked, packed, shipped or billed). After that the API returns 409; contact PrepWorx.409 with AMAZON_BUSY; try again in 2 minutes.Returns status 200. The new Amazon plan takes about 2 minutes. Until then amazon is null; call v1GetOutbound afterwards to get the new inbound_plan_id. The previous plan stays unused in your Send to Amazon list. If the items you send match what is already on the outbound, nothing changes and changed is false.
{
"success": true,
"changed": true,
"message": "Outbound updated. A new Amazon plan is being built ...",
"amazon_status": "queued",
"data": { "id": "lT5CoV3gB07nqp7ONTbM", "status": "pending", "amazon": null, ... }
}
POST /v1CancelOutbound
Cancels an outbound the warehouse hasn't started. Its reserved stock goes back to available immediately. It works only while cancellable is true: status pending, nothing picked, no packing or shipping started, nothing billed. After that, contact PrepWorx.
Request: { "id": "lT5CoV3gB07nqp7ONTbM" }
Response: { "success": true, "id": "lT5CoV3gB07nqp7ONTbM", "cancelled": true }
The Amazon inbound plan isn't cancelled; it stays unused in your Send to Amazon list, and you can cancel it in Seller Central. To change the items instead of cancelling, use v1UpdateOutbound.
GET /getOutboundShipments (optional status, location) and GET /getOutboundShipment?id= still work for existing integrations, and include location and warehouse. For new integrations use v1ListOutbounds and v1GetOutbound: they return the stable, documented fields above, including Amazon shipment IDs and tracking.
There are no webhooks. Call v1ListOutbounds?updated_since=<time of your last check> every few minutes; one call returns every outbound that changed.
Errors include an error message written for people. v1 endpoints and warehouse checks also include a code your integration can act on.
| Status | Meaning |
|---|---|
| 400 Bad Request | Missing or invalid parameters |
| 401 Unauthorized | Invalid or missing API key |
| 403 Forbidden | You do not have access to this resource |
| 404 Not Found | Resource not found |
| 405 Method Not Allowed | Wrong method (GET instead of POST, or the reverse) |
| 409 Conflict | Duplicate reference, not enough stock, or a shipment that can no longer be changed or cancelled |
| 422 Unprocessable | A SKU isn't in your Seller Central or has no FNSKU yet |
| 429 Too Many Requests | Rate limit exceeded |
| 500 Server Error | Internal server error; contact support |
| Code | Status | Meaning |
|---|---|---|
UNKNOWN_LOCATION | 400 | location isn't one of your warehouses; the message lists the ones you can use |
AMAZON_NOT_CONNECTED | 400 | Your Amazon account isn't connected to PrepWorx |
LOCATION_NOT_CONFIGURED | 400 | Your PrepWorx warehouse isn't set; contact PrepWorx |
PREP_DETAILS_FAILED, PLAN_FAILED | 400 | Amazon refused the plan; error gives Amazon's reason, suggestions may follow |
AMAZON_REAUTH_REQUIRED | 401 | Amazon no longer accepts our authorization; reconnect in Settings → Integrations |
DUPLICATE_REFERENCE | 409 | An open outbound already uses this reference; existing_id is its ID |
INSUFFICIENT_STOCK | 409 | Not enough stock at that warehouse; shortfalls lists msku, asin, requested (extra_requested for v1UpdateOutbound) and available |
SKU_NOT_READY | 422 | not_found lists SKUs missing from your Seller Central; no_fnsku lists SKUs without an FNSKU |
DUPLICATE_ASIN | 400 / 409 | v1UpdateOutbound: the same product (ASIN) is on two lines. Put it on one line |
AMAZON_BUSY | 409 | v1UpdateOutbound: the Amazon plan is being built right now. Try again in 2 minutes |
CHANGED | 409 | v1UpdateOutbound: the outbound changed while your request was running. Fetch it and resend |
| Date | Change |
|---|---|
| Oct 22, 2026 | Multiple warehouses: optional location on createInboundShipment and v1CreateFbaOutbound; location and warehouse on every record you read; ?location= filter on list endpoints and getInventory; new error UNKNOWN_LOCATION. Integrations that don't send location work exactly as before. |
| Oct 8, 2026 | Added v1UpdateInbound, v1CancelInbound and v1UpdateOutbound |
| Oct 6, 2026 | Added v1ListOutbounds, v1GetOutbound, v1CancelOutbound and v1CreateFbaOutbound |
For API support, contact us at [email protected] or through Discord.