Articles on: Yanet Auto Purchase Orders

Create Purchase Orders via API

Overview

Yanet Auto Purchase Orders provides a Public API that allows external systems to create Purchase Orders programmatically.
This is useful when you want to connect Yanet Auto Purchase Orders with another system and automatically create Purchase Orders based on data from that system.

Note: The Public API currently supports creating Purchase Orders. Other API operations are not covered by this documentation.

Endpoint: POST /api/public/purchase-orders


1. Overview

Property

Value

Method

POST

Endpoint

/api/public/purchase-orders

Authentication

Client credentials

Content-Type

application/json

Maximum POs / request

100

Purchase Orders created through this endpoint are automatically recorded with:

source = "public_api"



2. Authentication

Before making API requests, generate your API credentials from:
Settings → Manage key
Each request must include the following headers:

Header

Required

Description

X-Client-ID

Yes

Shop client ID

X-Client-Secret

Yes

Shop client secret

X-Shop-Domain

Yes

Shopify shop domain, e.g. your-store.myshopify.com


Step 1 — Open Settings

Open Yanet Auto Purchase Orders and go to Settings.


Step 2 — Open API Access

Select API Access from the Settings menu.


Step 3 — Generate API Credentials

Click Generate new key to generate your Client ID and Client Secret.


Step 4 — Copy Your Credentials

Copy the Client ID and Client Secret and use them to authenticate API requests.

Keep your Client Secret secure and do not share it publicly.


Example
X-Client-ID: YOUR_CLIENT_ID
X-Client-Secret: YOUR_CLIENT_SECRET
X-Shop-Domain: your-store.myshopify.com


Authentication errors — 401 Unauthorized

Error

Description

Missing X-Client-ID header

X-Client-ID is missing or empty

Missing X-Client-Secret header

X-Client-Secret is missing or empty

Missing X-Shop-Domain header

X-Shop-Domain is missing or empty

Invalid X-Shop-Domain: "..." is not a valid Shopify shop domain

The shop domain does not pass Shopify domain validation

Shop not found for domain "..."

No shop exists for the specified domain

Shop "..." is inactive or uninstalled

The shop exists but is not active

API credentials are not configured for shop "...". Generate keys in Settings → Manage key.

API keys have not been generated for the shop

Invalid X-Client-ID

The client ID does not match the shop's stored credentials

Invalid X-Client-Secret

The client ID is valid, but the client secret does not match

Shop record for "..." is missing an ID

Unexpected shop configuration/data issue



3. Request Body

The API supports three request formats.

Use this format when creating one or multiple Purchase Orders.

{
"purchase_orders": [
{
"...": "PO 1"
},
{
"...": "PO 2"
}
]
}


3.2 Raw array
[
{
"...": "PO 1"
},
{
"...": "PO 2"
}
]


3.3 Single Purchase Order — Legacy

A single PO can also be sent directly as the request body.

{
"...": "single PO fields"
}

Recommendation: Use the wrapped purchase_orders format for new integrations. It provides a consistent structure for both single-PO and batch requests.


4. Purchase Order Fields


4.1 Required Fields

Field

Type

Required

Description

supplier_name

string

Yes

Existing supplier name in the app. Matching is case-insensitive.

destination

string

Yes

Shopify Location ID. Accepts the GID or numeric ID format used by the app.

items

array

Yes

Purchase order line items. Must contain at least one item.


Supplier field compatibility

For backward compatibility, you may use supplier instead of supplier_name.

{
"supplier": "Acme Supplies"
}

In this API, supplier is interpreted as a supplier name, not a supplier ID.
Resolution priority:

supplier_name → supplier

If both are provided, supplier_name takes priority.


4.2 Line Items — items[]

Each Purchase Order must contain at least one line item.

Required fields

Field

Type

Required

Description

product_id

string

Yes

Shopify Product ID

variant_id

string

Yes

Shopify Variant ID

product_title

string

Yes

Product title

variant_title

string

Yes

Variant title

quantity

number

Yes

Quantity to purchase. Must be ≥ 1.

cost

number

Yes

Unit cost. Must be ≥ 0.


Optional fields

Field

Type

Description

sku

string

Product SKU

supplier_sku

string

Supplier SKU

price

number

Price. Must be ≥ 0.

compareAtPrice

number

Compare-at price. Must be ≥ 0.

tax

number

Tax percentage. Must be between 0 and 100.

image_url

string

Product image URL

accepted_quantity

number

Accepted quantity. Must be ≥ 0.

rejected_quantity

number

Rejected quantity. Must be ≥ 0.


4.3 Optional Purchase Order Fields

Field

Type

Description

reference_number

string

External or display reference

sequence_number

number

PO sequence number. Must be ≥ 1.

status

string

draft, ordered, partial_received, completed, cancelled, or closed

estimated_arrival

ISO date

Estimated arrival date

estimated_ship

ISO date

Estimated shipping date

invoice_date

ISO date

Invoice date

shipping_carrier

string

Shipping carrier

tracking_number

string

Tracking number

additional_note

string

Additional notes

tags

string[]

PO tags

payment_status

string

pending, partial, or paid

amount_paid

number

Amount paid. Must be ≥ 0.

paid_on

ISO date

Payment date

payment_due

ISO date

Payment due date

payment_note

string

Payment note

payment_method

string

Payment method

payment_terms

string

Payment terms

additional_costs

array

Additional costs associated with the PO


4.4 Additional Costs — additional_costs[]

Each additional cost must contain:

Field

Type

Required

Description

name

string

Yes

Cost name

value

string

Yes

Cost description/value

cost

number

Yes

Cost amount. Must be ≥ 0.

Example:

{
"additional_costs": [
{
"name": "Shipping",
"value": "Express",
"cost": 50
}
]
}


4.5 Server-managed Fields

The following fields should not be provided by the client:

Field

Behavior

shopId

Automatically resolved from X-Shop-Domain

source

Automatically set to public_api

supplier as an ID

Supplier is resolved from the supplier name



5. Response

The endpoint uses partial success for batch requests.
A request can return 200 OK even when some Purchase Orders fail.
Always check:

  • success — number of successfully created POs
  • failed — number of failed POs
  • created — details of successfully created POs
  • errors — errors for POs that could not be created


Example response
{
"success": 1,
"failed": 1,
"created": [
{
"id": "674a1b2c3d4e5f678901234",
"po_number": "PO-042",
"reference_number": "EXT-1001",
"sequence_number": 42,
"supplier": "6655aabbccddeeff00112233",
"supplier_name": "Acme Supplies",
"destination": "gid://shopify/Location/123456789",
"status": "ordered",
"payment_status": "pending",
"tracking_number": "",
"estimated_arrival": "2026-09-01T00:00:00.000Z",
"estimated_ship": null,
"invoice_date": null,
"subtotal": 1000,
"tax_total": 0,
"additional_costs_total": 50,
"total": 1050,
"item_count": 1,
"source": "public_api",
"created_at": "2026-08-21T07:00:00.000Z",
"updated_at": "2026-08-21T07:00:00.000Z",
"shipping_carrier": "",
"additional_note": "",
"tags": [],
"amount_paid": 0,
"paid_on": null,
"payment_due": null,
"payment_note": "",
"payment_method": "",
"payment_terms": "",
"items": [
{
"product_id": "gid://shopify/Product/111",
"variant_id": "gid://shopify/ProductVariant/222",
"product_title": "T-Shirt",
"variant_title": "M / Black",
"sku": "TS-M-BLK",
"supplier_sku": "ACME-TS-01",
"quantity": 10,
"accepted_quantity": 0,
"rejected_quantity": 0,
"cost": 100,
"price": 0,
"tax": 0,
"image_url": ""
}
],
"additional_costs": [
{
"name": "Shipping",
"value": "Express",
"cost": 50
}
]
}
],
"errors": [
"EXT-1002: Supplier not found for name \"Unknown Vendor\""
]
}


Response fields

Field

Type

Description

success

number

Number of POs created successfully

failed

number

Number of POs that failed

created

array

Details of successfully created POs

errors

string[]

Per-PO error messages. Uses reference_number or PO #n to identify the failed PO.



6. Errors

6.1 Request-level errors — 400 Bad Request

Request-level errors prevent the request from being processed.

Error

Description

purchase_orders is required and must be a non-empty array

Request body is empty or no Purchase Orders could be parsed

You can create at most 100 purchase orders per request

The request contains more than 100 POs

Shop not resolved from X-Shop-Domain

The shop could not be resolved after authentication


6.2 Per-PO errors

Per-PO errors are returned inside the errors[] array. Other valid POs in the same request are still processed.

Error

Description

supplier_name is required (or supplier as supplier name)

Supplier name is missing

destination is required

Destination is missing

items is required and must be non-empty

items is missing or empty

Supplier not found for name "..."

No matching supplier exists in the shop


Batch behavior

For example, if a request contains 3 POs and 1 fails:

{
"success": 2,
"failed": 1,
"created": ["PO 1", "PO 3"],
"errors": [
"EXT-1002: Supplier not found for name \"Unknown Vendor\""
]
}

The successful POs are still created.



7. cURL Examples

7.1 Create Multiple Purchase Orders
curl -X POST "https://your-app-host.com/api/public/purchase-orders" \
-H "Content-Type: application/json" \
-H "X-Client-ID: YOUR_CLIENT_ID" \
-H "X-Client-Secret: YOUR_CLIENT_SECRET" \
-H "X-Shop-Domain: your-store.myshopify.com" \
-d '{
"purchase_orders": [
{
"supplier_name": "Acme Supplies",
"destination": "gid://shopify/Location/123456789",
"reference_number": "EXT-1001",
"status": "ordered",
"estimated_arrival": "2026-09-01",
"additional_note": "Created via public API",
"tags": [
"api",
"wholesale"
],
"items": [
{
"product_id": "gid://shopify/Product/111",
"variant_id": "gid://shopify/ProductVariant/222",
"product_title": "T-Shirt",
"variant_title": "M / Black",
"sku": "TS-M-BLK",
"quantity": 10,
"cost": 100,
"tax": 0
}
],
"additional_costs": [
{
"name": "Shipping",
"value": "Express",
"cost": 50
}
]
}
]
}'


7.2 Create a Single Purchase Order

The recommended format can also be used for a single PO:

curl -X POST "https://your-app-host.com/api/public/purchase-orders" \
-H "Content-Type: application/json" \
-H "X-Client-ID: YOUR_CLIENT_ID" \
-H "X-Client-Secret: YOUR_CLIENT_SECRET" \
-H "X-Shop-Domain: your-store.myshopify.com" \
-d '{
"purchase_orders": [
{
"supplier_name": "Acme Supplies",
"destination": "gid://shopify/Location/123456789",
"status": "draft",
"items": [
{
"product_id": "gid://shopify/Product/111",
"variant_id": "gid://shopify/ProductVariant/222",
"product_title": "T-Shirt",
"variant_title": "M / Black",
"quantity": 5,
"cost": 100
}
]
}
]
}'



8. JavaScript Example

const BASE_URL = 'https://po.yanet.io';

const headers = {
'Content-Type': 'application/json',
'X-Client-ID': 'YOUR_CLIENT_ID',
'X-Client-Secret': 'YOUR_CLIENT_SECRET',
'X-Shop-Domain': 'your-store.myshopify.com',
};

const response = await fetch(
`${BASE_URL}/api/public/purchase-orders`,
{
method: 'POST',
headers,
body: JSON.stringify({
purchase_orders: [
{
supplier_name: 'Acme Supplies',
destination: 'gid://shopify/Location/123456789',
reference_number: 'EXT-1001',
status: 'ordered',
items: [
{
product_id: 'gid://shopify/Product/111',
variant_id: 'gid://shopify/ProductVariant/222',
product_title: 'T-Shirt',
variant_title: 'M / Black',
sku: 'TS-M-BLK',
quantity: 10,
cost: 100,
},
],
},
],
}),
}
);

const result = await response.json();

console.log('Created:', result.success);
console.log('Failed:', result.failed);
console.log('Errors:', result.errors);
console.log('Created POs:', result.created);



9. Integration Guidelines

Before integrating, make sure that:

  1. The supplier already exists in Yanet. Supplier matching is performed by name and is case-insensitive.
  2. The destination is valid for the Shopify shop and uses a Location ID recognized by the app.
  3. A maximum of 100 POs can be submitted in a single request.
  4. Batch requests support partial success. A failed PO does not prevent other POs from being created.
  5. After every request, check success, failed, and errors.
  6. Each create operation can be recorded in API Call History when API logging is enabled.



10. Quick Reference

Endpoint
POST /api/public/purchase-orders


Required headers
Content-Type: application/json
X-Client-ID: YOUR_CLIENT_ID
X-Client-Secret: YOUR_CLIENT_SECRET
X-Shop-Domain: your-store.myshopify.com


Minimal request
{
"purchase_orders": [
{
"supplier_name": "Acme Supplies",
"destination": "gid://shopify/Location/123456789",
"items": [
{
"product_id": "gid://shopify/Product/111",
"variant_id": "gid://shopify/ProductVariant/222",
"product_title": "T-Shirt",
"variant_title": "M / Black",
"quantity": 10,
"cost": 100
}
]
}
]
}


Success indicators
HTTP 200
success > 0
failed = 0

For batch requests, HTTP 200 does not necessarily mean every PO was created successfully. Always inspect success, failed, and errors.

Updated on: 25/08/2026

Was this article helpful?

Share your feedback

Cancel

Thank you!