Skip to main content

Purchase Invoice API

The Purchase Invoice API allows you to create purchase invoices that can either create new products or update existing products with additional inventory. This endpoint supports file uploads for product variant images and handles brand creation automatically.
This endpoint uses multipart/form-data format to support file uploads. Make sure to include the proper headers when making requests.

Endpoint Details

Endpoint: POST /purchase-invoices
Content-Type: multipart/form-data
Base URL: https://jethings-backend.fly.dev

Required Headers

x-store-id: <store_id>
Authorization: Bearer <token>

Request Structure

The request uses multipart/form-data format with:
  • jsonData: A JSON string containing the purchase invoice data
  • Files: Product variant images uploaded with specific field names

Action Types

The API supports two action types:
Use CREATE when introducing a brand new product to your inventory.
{
  "actionType": "CREATE",
  "warehouseId": "uuid",
  "supplierId": "uuid",
  "purchaseDate": "2024-01-15",
  "referenceNumber": "REF-001",
  "amountPaid": 100.80,
  "isShipped": false,
  "isPaid": false,
  "productTypeId": "uuid",
  "product": {
    "title": "Product Name",
    "ref": "PROD-001",
    "description": "Product description",
    "brandName": "Nike"
  },
  "variants": [
    {
      "itemName": "Blue T-Shirt",
      "color": "Blue",
      "pointer": [
        { "qty": 49, "value": 30, "barcode": "PSH-BLUE-30" }
      ]
    }
  ],
  "barcodes": ["B001", "B002"]
}
Required fields for CREATE:
  • actionType: "CREATE"
  • product.title: Product name
  • variants: Array of variant objects
  • warehouseId, supplierId, purchaseDate, referenceNumber, amountPaid, productTypeId, isShipped, isPaid

Data Structures

Product Object

The product object is used in CREATE actions to define product details.
FieldTypeRequiredDescription
titlestring✅ YesProduct title/name (e.g., “Premium T-Shirt”)
refstringNoProduct reference code (e.g., “TSH-001”)
descriptionstringNoProduct description
brandIdstring (UUID)NoUUID of an existing brand
brandNamestringNoBrand name (will create brand if it doesn’t exist)
For brand selection, you can use either brandId (existing brand) or brandName (auto-create brand). If both are provided, brandName takes precedence.

Variant Structure

The variants array contains items and their sizes with quantities.
FieldTypeRequiredDescription
itemIdstringNoFor UPDATE only: UUID of existing item to add inventory to
itemNamestring✅ YesName for the item variant (e.g., “Blue T-Shirt”, “Red Shirt”)
colorstring✅ YesColor variant (e.g., “Blue”, “Green”, “Red”)
pointerarray✅ YesArray of pointer values (sizes, etc.)

Pointer Structure

Each pointer represents a size with quantity:
{
  "qty": 49,              // Quantity for this size
  "value": 30,            // Pointer value (e.g., size 30)
  "barcode": "PSH-BLUE-30" // Optional barcode for this pointer
}

File Upload Mechanism

Naming Convention

Product variant images must be uploaded using this naming pattern:
Upload images for all variants:
variant_0_images: [image1.jpg, image2.jpg]
variant_1_images: [image1.jpg, image2.jpg]
variant_2_images: [image1.jpg]

Multiple Images per Variant

You can upload multiple images for each variant by sending multiple files with the same field name:
variant_0_images: [image1.jpg, image2.jpg, image3.jpg]
variant_1_images: [image1.jpg, image2.jpg]

Supported Image Formats

  • jpg, jpeg, png, gif, webp

Complete Examples

This section provides detailed examples for both CREATE and UPDATE action types.

CREATE Action Examples

Example 1: CREATE - New Product with Brand Creation

This example creates a new product with auto-brand creation.
Use when: You’re introducing a brand new product to your inventory that doesn’t exist yet.
curl -X POST https://jethings-backend.fly.dev/purchase-invoices \
  -H "x-store-id: x1vt8qlr0l7ju7tbe2an6ov0" \
  -H "Authorization: Bearer <token>" \
  -F 'jsonData={"actionType":"CREATE","warehouseId":"x1vt8qlr0l7ju7tbe2an6ov0","supplierId":"cjdtw2flpntu6jmsh0row6yc","purchaseDate":"2024-01-15","referenceNumber":"REF-2024-001","amountPaid":100.80,"isShipped":false,"isPaid":false,"productTypeId":"ywb1l1vyre5nm27n2fr8vpwz","product":{"title":"Premium Cotton T-Shirt","ref":"TSH-001","description":"High-quality cotton t-shirt with premium finish","brandName":"Nike"},"variants":[{"itemName":"Blue T-Shirt","pointer":[{"qty":49,"value":30,"barcode":"PSH-BLUE-30"}],"color":"Blue"},{"itemName":"Green T-Shirt","pointer":[{"qty":49,"value":30,"barcode":"PSH-GREEN-30"}],"color":"Green"}],"barcodes":["0988-TY","09877-GB"]}' \
  -F '[email protected]' \
  -F '[email protected]' \
  -F '[email protected]'
Success Response:
{
  "purchaseInvoice": {
    "id": "invoice-uuid",
    "supplierId": "cjdtw2flpntu6jmsh0row6yc",
    "storeId": "x1vt8qlr0l7ju7tbe2an6ov0",
    "supplierInvoiceNo": "REF-2024-001",
    "priceList": "default",
    "postingTime": "2024-01-15T10:00:00.000Z",
    "warehouseId": "x1vt8qlr0l7ju7tbe2an6ov0",
    "amountPaid": 100.80,
    "createAt": "2024-01-15T10:00:00.000Z"
  },
  "product": {
    "success": true,
    "message": "Product and items created successfully",
    "product": {
      "id": "product-uuid",
      "title": "Premium Cotton T-Shirt",
      "ref": "TSH-001",
      "description": "High-quality cotton t-shirt with premium finish",
      "brandId": "brand-uuid"
    },
    "items": [
      {
        "item": {
          "id": "item-uuid-1",
          "productId": "product-uuid"
        },
        "itemVariants": [
          {
            "pointer": 30,
            "color": "Blue",
            "qty": 49,
            "barcode": "PSH-BLUE-30"
          }
        ],
        "images": [
          {
            "success": true,
            "filename": "blue-image-1.jpg",
            "url": "https://storage.example.com/products/items/image.jpg"
          }
        ]
      }
    ]
  }
}

Example 2: CREATE - Using Existing Brand

This example creates a new product using an existing brand ID instead of creating a new brand.
Use when: Creating a new product and want to link to an existing brand in your system.
curl -X POST https://jethings-backend.fly.dev/purchase-invoices \
  -H "x-store-id: x1vt8qlr0l7ju7tbe2an6ov0" \
  -H "Authorization: Bearer <token>" \
  -F 'jsonData={"actionType":"CREATE","warehouseId":"x1vt8qlr0l7ju7tbe2an6ov0","supplierId":"cjdtw2flpntu6jmsh0row6yc","purchaseDate":"2024-01-15","referenceNumber":"REF-2024-002","amountPaid":150.50,"isShipped":false,"isPaid":false,"productTypeId":"ywb1l1vyre5nm27n2fr8vpwz","product":{"title":"Premium Jeans","ref":"JEAN-001","description":"Classic fit jeans","brandId":"existing-brand-uuid"},"variants":[{"itemName":"Blue Jeans","color":"Blue","pointer":[{"qty":30,"value":32,"barcode":"JEAN-BLUE-32"}]}]}' \
  -F '[email protected]'

UPDATE Action Examples

Example 3: UPDATE - Add Inventory to Existing Item

Use this when adding more stock to an existing color/variant.
Use when: Adding inventory to an existing item variant. No file uploads needed.
curl -X POST https://jethings-backend.fly.dev/purchase-invoices \
  -H "x-store-id: x1vt8qlr0l7ju7tbe2an6ov0" \
  -H "Authorization: Bearer <token>" \
  -F 'jsonData={"actionType":"UPDATE","productId":"a7hkmoj8p142p2vtp450byk2","warehouseId":"x1vt8qlr0l7ju7tbe2an6ov0","supplierId":"cjdtw2flpntu6jmsh0row6yc","purchaseDate":"2024-01-15","referenceNumber":"REF-2024-003","amountPaid":100.80,"isShipped":false,"isPaid":false,"productTypeId":"ywb1l1vyre5nm27n2fr8vpwz","variants":[{"itemId":"existing-blue-item-uuid","itemName":"Blue T-Shirt","color":"Blue","pointer":[{"qty":49,"value":30}]}]}'
Note: No file uploads needed when using itemId for existing items.

Example 4: UPDATE - Create New Item (Different Color)

Use this when adding a new color variant to an existing product.
Use when: Creating a new item variant (new color) for an existing product. Requires file uploads.
curl -X POST https://jethings-backend.fly.dev/purchase-invoices \
  -H "x-store-id: x1vt8qlr0l7ju7tbe2an6ov0" \
  -H "Authorization: Bearer <token>" \
  -F 'jsonData={"actionType":"UPDATE","productId":"a7hkmoj8p142p2vtp450byk2","warehouseId":"x1vt8qlr0l7ju7tbe2an6ov0","supplierId":"cjdtw2flpntu6jmsh0row6yc","purchaseDate":"2024-01-15","referenceNumber":"REF-2024-004","amountPaid":75.25,"isShipped":false,"isPaid":false,"productTypeId":"ywb1l1vyre5nm27n2fr8vpwz","variants":[{"itemName":"Red T-Shirt","color":"Red","pointer":[{"qty":25,"value":30,"barcode":"PSH-RED-30"}]}]}' \
  -F '[email protected]'
Note: When creating a new item (different color) in UPDATE action, you must provide itemName and upload images using variant_0_images.

Example 5: UPDATE - Mixed (Existing + New Items)

Adding inventory to Blue item and creating Red and Green items.
Use when: Adding inventory to existing items AND creating new item variants in the same request.
curl -X POST https://jethings-backend.fly.dev/purchase-invoices \
  -H "x-store-id: x1vt8qlr0l7ju7tbe2an6ov0" \
  -H "Authorization: Bearer <token>" \
  -F 'jsonData={"actionType":"UPDATE","productId":"a7hkmoj8p142p2vtp450byk2","warehouseId":"x1vt8qlr0l7ju7tbe2an6ov0","supplierId":"cjdtw2flpntu6jmsh0row6yc","purchaseDate":"2024-01-15","referenceNumber":"REF-2024-005","amountPaid":200.00,"isShipped":false,"isPaid":false,"productTypeId":"ywb1l1vyre5nm27n2fr8vpwz","variants":[{"itemId":"existing-blue-item-uuid","itemName":"Blue T-Shirt","color":"Blue","pointer":[{"qty":30,"value":30}]},{"itemName":"Red T-Shirt","color":"Red","pointer":[{"qty":25,"value":30,"barcode":"PSH-RED-30"}]},{"itemName":"Green T-Shirt","color":"Green","pointer":[{"qty":20,"value":30,"barcode":"PSH-GREEN-30"}]}]}' \
  -F '[email protected]' \
  -F '[email protected]'
The file indices (variant_0_images, variant_1_images) correspond to NEW items only (Red and Green), not the existing Blue item.

Response Structure

Success Response

{
  "purchaseInvoice": {
    "id": "invoice-uuid",
    "supplierId": "cjdtw2flpntu6jmsh0row6yc",
    "storeId": "x1vt8qlr0l7ju7tbe2an6ov0",
    "supplierInvoiceNo": "REF-2024-001",
    "priceList": "default",
    "postingTime": "2024-01-15T10:00:00.000Z",
    "dueTime": "2024-01-15T00:00:00.000Z",
    "updateStock": true,
    "warehouseId": "x1vt8qlr0l7ju7tbe2an6ov0",
    "amountPaid": 100.80,
    "createAt": "2024-01-15T10:00:00.000Z",
    "updateAt": "2024-01-15T10:00:00.000Z"
  },
  "purchaseInvoiceItems": [
    {
      "id": "item-1-uuid",
      "purchaseInvoiceId": "invoice-uuid",
      "itemVariantId": "variant-1-uuid",
      "quantity": 49,
      "unitPrice": 2.06,
      "totalPrice": 101.06,
      "isActive": true,
      "createdAt": "2024-01-15T10:00:00.000Z",
      "updatedAt": "2024-01-15T10:00:00.000Z"
    }
  ],
  "product": {
    "success": true,
    "message": "Product and items created successfully",
    "product": {
      "id": "product-uuid",
      "storeId": "x1vt8qlr0l7ju7tbe2an6ov0",
      "productTypeId": "ywb1l1vyre5nm27n2fr8vpwz",
      "brandId": "brand-uuid",
      "title": "Premium Cotton T-Shirt",
      "ref": "TSH-001",
      "description": "High-quality cotton t-shirt with premium finish",
      "isActive": true,
      "createdAt": "2024-01-15T10:00:00.000Z",
      "updatedAt": "2024-01-15T10:00:00.000Z"
    },
    "items": [
      {
        "item": {
          "id": "item-uuid-1",
          "productId": "product-uuid",
          "description": "Item variant 1",
          "isActive": true
        },
        "itemVariants": [
          {
            "itemVariant": {
              "id": "item-variant-uuid"
            },
            "pointer": 30,
            "color": "Blue",
            "qty": 49,
            "barcode": "PSH-BLUE-30"
          }
        ],
        "images": [
          {
            "success": true,
            "filename": "blue-image-1.jpg",
            "url": "https://storage.example.com/products/items/image.jpg"
          }
        ]
      }
    ]
  }
}

Error Responses

400 Bad Request

{
  "statusCode": 400,
  "message": "Product type not found",
  "error": "Bad Request"
}

403 Forbidden

{
  "statusCode": 403,
  "message": "You do not have access to this store",
  "error": "Forbidden"
}

404 Not Found

{
  "statusCode": 404,
  "message": "Item with id xyz not found",
  "error": "Not Found"
}

Important Notes

CREATE vs UPDATE

  • Creates a new product and its items/variants
  • All variants get new items with the provided itemName
  • Requires uploading images for all variants
  • Use when introducing completely new products
  • Updates an existing product
  • Can add to existing items (with itemId) or create new items (without itemId)
  • Only upload images for new items (without itemId)
  • Use when restocking existing products

itemName Field

  • Always required for all variants in both CREATE and UPDATE actions
  • This name is stored in the itemVariant.name column in the database
  • Examples: “Blue T-Shirt”, “Red Shirt”, “Green Variant”

itemId Usage in UPDATE

With itemId

Add inventory to an existing item
No file uploads needed

Without itemId

Create a new item
Requires file uploads

File Upload Rules

Upload images for ALL variants:
variant_0_images: [variant-0-img1.jpg, variant-0-img2.jpg]
variant_1_images: [variant-1-img1.jpg]
variant_2_images: [variant-2-img1.jpg, variant-2-img2.jpg]

Stock Management

  • Quantities (qty in pointer) automatically update warehouse stock
  • Stock is distributed across warehouse bins
  • updateStock: true enables real-time stock updates

Brand Handling

{
  "product": {
    "title": "Product Name",
    "brandId": "existing-brand-uuid"
  }
}
Use brandId to reference an existing brand

Barcode Assignment

The API supports two methods for barcode assignment:
  1. Individual barcodes in pointer values - Specific to each size
  2. Global barcodes array - Applied to all item variants
Both methods work simultaneously.

Summary

1

Choose Action Type

Select CREATE for new products or UPDATE for existing products
2

Prepare Data

Structure your JSON data with product info, variants, and inventory details
3

Upload Files

Follow the naming convention for variant images based on your action type
4

Send Request

Use multipart/form-data with proper headers
5

Handle Response

Receive complete purchase invoice, product, and stock information
This API provides a flexible way to manage purchase invoices while automatically handling product creation, variant management, inventory updates, and file uploads. Choose the appropriate action type based on whether you’re introducing a new product (CREATE) or restocking an existing one (UPDATE).