Warehouse / Guides

Create products and orders

Sync products from your webshop and send orders to PackCloud for fulfilment.

Use the Organization API

Product catalogue and order intake belong to the Organization API. Your webshop or integration creates the commercial records there; PackCloud then allocates the resulting work to a warehouse.

These examples use the Organization endpoint, not the Warehouse endpoint. Switch the schema selector to Organization API when you open the linked reference pages.
https://api.pack.cloud/v1/organizations/{organizationId}/graphql

Build the intake flow

Keep the PackCloud IDs returned by each mutation. An order line refers to a PackCloud product ID, so products must be synchronized before their first order arrives.

  1. Resolve the PackCloud brand ID for the webshop or sales channel.
  2. Create each sellable product variant and store its returned product ID.
  3. Create the order with at least one line and the recipient address.
  4. Check both top-level GraphQL errors and the mutation payload's user errors.
  5. Store the returned order and line IDs for later updates, holds, or cancellation.

Create a product

Create one PackCloud product for each sellable variant. Use a stable code from your ecommerce system, but keep your own mapping to the returned PackCloud ID: product codes are not unique.

  • name is required by runtime validation.
  • When you add a barcode, send both barcode and quantity.
  • Barcode values must be distinct and cannot already belong to another active product.
  • Send money amounts as decimal strings and currency codes as uppercase ISO 4217 codes.
productCreateReference
mutation ProductCreate($input: ProductCreateInput!) {
productCreate(input: $input) {
product {
id
name
code
type
barcodes {
barcode
quantity
}
}
userErrors {
field
message
}
}
}
Variables
{
"input": {
"name": "Canvas backpack – green",
"brandName": "Acme Outdoor",
"code": "BAG-CANVAS-GREEN",
"type": "STANDARD",
"barcodes": [
{
"barcode": "8712345678906",
"quantity": 1
}
],
"price": {
"currency": "EUR",
"value": "59.95"
},
"weight": {
"value": 750,
"unit": "G"
}
}
}
Response
{
"data": {
"productCreate": {
"product": {
"id": "cf695726-3f50-4aa0-b686-d45f55042bfa",
"name": "Canvas backpack – green",
"code": "BAG-CANVAS-GREEN",
"type": "STANDARD",
"barcodes": [
{
"barcode": "8712345678906",
"quantity": 1
}
]
},
"userErrors": []
}
}
}

A successful result has an empty userErrors array and a non-null product.id. Persist that ID before accepting orders for the product.

Create an order

Replace the example brand and product UUIDs with IDs from the same organization. For delivery orders, include a recipient address. If billing details are omitted, PackCloud uses the recipient address as the billing address.

brandIdA brand in the selected organization.
linesAt least one line with productId, quantityOrdered, and name.
recipientAddressRequired for delivery; local pickup can omit it.
referenceOptional external reference, limited to 25 characters and not unique.
orderCreateReference
mutation OrderCreate($input: OrderCreateInput!) {
orderCreate(input: $input) {
order {
id
reference
status
lines(first: 10) {
edges {
node {
id
name
quantityOrdered
product {
id
}
}
}
}
}
userErrors {
field
message
}
}
}
Variables
{
"input": {
"brandId": "f3c82a83-27e9-4e8f-8148-468bc65827c7",
"reference": "WEB-10482",
"recipientAddress": {
"name": "Alex de Vries",
"address": "Keizersgracht",
"houseNumber": "391 A",
"postalCode": "1016 EJ",
"city": "Amsterdam",
"countryCode": "NL",
"email": "alex@example.com"
},
"lines": [
{
"productId": "37aed8af-184d-4dc3-bf75-92db8fdcf3db",
"quantityOrdered": 2,
"name": "Canvas backpack – green",
"price": {
"currency": "EUR",
"value": "59.95"
}
}
]
}
}
Response
{
"data": {
"orderCreate": {
"order": {
"id": "8c76f46e-2149-49d4-b028-9e2d281bdb67",
"reference": "WEB-10482",
"status": "CREATED",
"lines": {
"edges": [
{
"node": {
"id": "a6acb575-aab8-4676-a2ce-2d7f1d88a0d1",
"name": "Canvas backpack – green",
"quantityOrdered": 2,
"product": {
"id": "37aed8af-184d-4dc3-bf75-92db8fdcf3db"
}
}
}
]
}
},
"userErrors": []
}
}
}

Address format checks are strict by default. PackCloud validates country-specific postal codes, email, phone, state code and VAT formats when supplied. Setting strictValidation: false relaxes the format checks, but name, street, city and country remain required.

Handle mutation results

A mutation can return HTTP 200 and still be unsuccessful. Treat the write as complete only when userErrors is empty and the expected object ID is present.

{
"data": {
"orderCreate": {
"order": null,
"userErrors": [
{
"field": ["input", "lines", "0", "productId"],
"message": "The selected product is invalid."
}
]
}
}
}

The field path tells you which input failed. Also handle top-level errors for invalid GraphQL documents, authentication problems, and unexpected server errors.

Continue the order lifecycle

Retry without creating duplicates

Neither create mutation accepts an idempotency key. Product codes and order references are also not unique. A blind retry after a timeout can therefore create a duplicate.

  1. Record a local pending write against your ecommerce product or order ID.
  2. Send the create mutation once.
  3. Persist the PackCloud ID as soon as it is returned.
  4. After an ambiguous timeout, reconcile by your mapping and code or reference before retrying.

Use productUpdate or orderUpdate once you have a PackCloud ID. Do not use another create mutation to synchronize a known record.