Getting Started

The KSS API provides programmatic access to product catalog, inventory, customer, invoice, and pricing data. All requests are made over HTTPS and return JSON responses.

OpenAPI JSON specification

Import an OpenAPI specification into Postman

There are two environments, each backed by its own isolated database and requiring a separate API key.

Production
api.kssdata.com
Live data. Use production API keys only. Data is updated continuously
Test
api.test.kssdata.com
Safe for development and integration testing. Data is updated every Sunday morning
API keys are environment-scoped. A production key will be rejected by the test environment and vice versa. Never use production keys in development or CI pipelines.

All endpoints are versioned under /api/v2. A full request to the products endpoint looks like:

https
GET https://api.kssdata.com/api/{{version}}/products?States=CA&Statuses=1
x-api-key: your-api-key

Authentication

Every request must include your API key in the x-api-key request header. Requests without a valid key return 401 Unauthorized.

http header
x-api-key: your-api-key
Key Types

Employee — Full access to all endpoints and all data across any state or customer.

Customer — Access is scoped to the customer accounts associated with the key. Requests for data outside that scope are silently filtered or return 403.

Supplier — Access is scoped to the supplier accounts associated with the key. Some endpoints are unavailable to Supplier keys entirely, noted per endpoint below.

Idempotency

For POST and PATCH requests, you may send an Idempotency-Key request header to make retries safe after a timeout or lost response.

Use a unique key for each logical operation, such as a UUID generated by your client. If the same API key sends the same idempotency key with the same method, path, query, and body, the API returns the original response instead of running the operation again.

Do not reuse a key for a different operation. Reusing a key with a different request returns 409 IDEMPOTENCY_KEY_REUSED. A retry while the original request is still processing returns 409 IDEMPOTENCY_KEY_IN_PROGRESS.

request headers
POST /api/{{version}}/purchases
x-api-key: your-api-key
Idempotency-Key: 9f30f7f5-7e08-4f6a-a60c-8f7d11e9c702
Exact retries replay the stored response. Replayed responses include Idempotency-Replayed: true. Keep your own idempotency keys long enough to cover your retry window.

Rate Limiting

Rate limits are enforced per API key. Each key has a configurable maximum requests per hour. When the limit is reached, the API returns 429 Too Many Requests.

Every response reports your current standing so you can pace requests before you are throttled:

RateLimit-Limit
The maximum number of requests allowed in the current window.
RateLimit-Remaining
Requests you have left before hitting the limit. 0 means the next request may be rejected.
RateLimit-Reset
Seconds until your remaining count recovers.
Retry-After
On a 429 only: seconds to wait before retrying.

When you receive a 429, wait the number of seconds given in Retry-After before sending another request rather than retrying immediately.

If you are building a sync process that requires high request volume, contact KSS to discuss your needs.

response headers
RateLimit-Limit: 1000
RateLimit-Remaining: 847
RateLimit-Reset: 2934
Use pagination and filtering. Fetching only the data you need — by state, supplier, or customer — is the most effective way to reduce request volume.

Pagination

All list endpoints support pagination via Page and PageSize query parameters. The default page size is 50. The maximum page size is 500.

Paginated responses wrap results in a Data array alongside Page and PageSize fields. A HasNextPage boolean indicates whether more results exist beyond the current page.

example request
GET /api/{{version}}/products?States=CA&Page=2&PageSize=100
json
{
  "Data": [ ... ],
  "Page": 2,
  "PageSize": 100,
  "HasNextPage": true
}

Errors

The API uses standard HTTP status codes. Error responses include a JSON body with an error field describing the issue.

400 Bad Request
Missing or invalid parameter.
401 Unauthorized
Missing or invalid API key.
403 Forbidden
Your key does not have access to this resource.
404 Not Found
The endpoint does not exist.
429 Too Many Requests
Rate limit exceeded.
500 Server Error
Unexpected server error. Contact KSS support.
error response
{
  "Error": "InvoiceIDs parameter is required"
}

Response Headers

Alongside the rate limit headers, every response includes the following.

Request tracing

Each response carries an X-Request-Id header uniquely identifying that request. Include this value when contacting KSS support so we can locate the exact request in our logs.

If you send your own X-Request-Id on a request, we echo it back unchanged (when it is a short alphanumeric token), letting you correlate a request across your systems and ours.

Conditional requests

Responses include an ETag validator. To avoid re-downloading data that has not changed, send the ETag from a previous response back on your next request using the If-None-Match header. If the data is unchanged, the API returns 304 Not Modified with an empty body; otherwise it returns the full response with a new ETag.

Responses are marked private and must not be shared between different API keys in a downstream cache.

conditional request
GET /api/{{version}}/products?States=CA
x-api-key: your-api-key
If-None-Match: W/"a1b2c3d4e5f6..."

Endpoints

Purchases
GET
/purchases
Not available to Customer keys Paginated Beta

Returns purchase orders filtered by purchase ID, vendor, location, status, and date range. purchase_transactions are included by default; send include_transactions=false to return headers only. Omitting statuses returns everything: purchases the ERP has posted, and the purchase orders originated here (including drafts that have not been submitted yet). Filtering statuses to InProgress and/or Submitted returns only the purchase orders originated here; filtering to other statuses returns only ERP-posted purchases; combining both kinds of status returns both sources merged into one paginated list. Not accessible to Customer API keys.

Parameters
Name Type Required Description
purchase_ids
query
string optional
Comma-separated list of purchase identifiers to filter by. Each value may be a numeric ERP purchase_id or a purchase_global_id.
vendor_ids
query
string optional
Comma-separated list of vendor IDs to filter by.
location_ids
query
string optional
Comma-separated list of destination location IDs to filter by.
statuses
query
string optional
Comma-separated list of purchase statuses to filter by. Omitted, returns purchase orders from every status and both sources. InProgress and Submitted select the purchase orders originated here; other statuses select ERP-posted purchases; combining both kinds returns both sources merged into one list.
start_date
query
date optional
ISO 8601 date string. Returns posted purchases with a post_date on or after this date, and API-originated drafts with a delivery_date on or after this date.
end_date
query
date optional
ISO 8601 date string. Returns posted purchases with a post_date on or before this date, and API-originated drafts with a delivery_date on or before this date.
include_transactions
query
boolean optional
Line items are included by default. Send false to omit purchase_transactions from each purchase.
page
query
number optional
Page number to retrieve. Defaults to 1.
page_size
query
number optional
Number of rows to return per page. Defaults to 50; maximum is 500.

Supports Page and PageSize query parameters. Default page size: 50. Maximum page size: 500 — larger values are reduced to 500.

Responses
Status Description
200
OK
400
The request is missing required input or contains invalid input.
401
The request is missing a valid API key.
403
The API key is not authorized to access this resource.
429
Rate limit exceeded.
500
Unexpected server error.
Example Response
json
{
  "data": [
    {
      "purchase_id": 70001,
      "receive_date": "2026-06-02T06:00:00.000Z",
      "shipment_num": "Example PO 70001",
      "shipment_id": 72001,
      "to_location_id": 40001,
      "to_location_name": "Alameda",
      "vendor_name": "EXAMPLE DISTRIBUTORS LLC (Example Location)",
      "vendor_id": 50001,
      "post_date": "2026-06-02T06:00:00.000Z",
      "status": "Verified",
      "po_num": "Example PO 70001",
      "freight": "0.00",
      "tax": "0.00",
      "other_cost": "0.00",
      "total": "35726.38",
      "total_cases": "184.00",
      "public_pdf_link": null,
      "purchase_pdf_url_api_key_id": 94001,
      "memo": null,
      "last_edit_time": null,
      "last_calc_time": "2026-06-04T10:20:14.000Z",
      "time_updated": "2026-08-21T18:06:57.930Z",
      "invoice_date": "2026-06-01T06:00:00.000Z",
      "due_date": "2026-08-30T06:00:00.000Z",
      "terms": "Driver Accounts",
      "term_id": 80002,
      "time_created": "2026-06-15T22:09:09.921Z",
      "purchase_global_id": "00000AAAAAFFFFF00000AAAAAF",
      "receiving_num": null,
      "purchase_transactions": [
        {
          "purchase_trans_id": 71001,
          "purchase_id": 70001,
          "product_id": 30006,
          "ordered": "10",
          "num_units": "120",
          "fob": "12.50",
          "deposit_cost": "0.00",
          "ext_price": "1500.00",
          "expiration_date": "2026-01-01T00:00:00.000Z",
          "code_date": "2025-01-15T00:00:00.000Z",
          "batch_code": "BCH-001",
          "laid_in_cost": "13.00",
          "pallet_tag": null,
          "cases": "10",
          "weight": "120.00",
          "time_updated": "2025-03-02T10:00:00.000Z"
        }
      ]
    },
    {
      "purchase_id": null,
      "receive_date": null,
      "shipment_num": null,
      "shipment_id": null,
      "to_location_id": 40002,
      "to_location_name": null,
      "vendor_name": null,
      "vendor_id": 50002,
      "post_date": null,
      "status": "InProgress",
      "po_num": "PO-2026-00000",
      "freight": "0.00",
      "tax": "0.00",
      "other_cost": "0.00",
      "total": "0.00",
      "total_cases": "30",
      "public_pdf_link": null,
      "purchase_pdf_url_api_key_id": null,
      "memo": "Acme Brands - Submitted via KSS Live by Jamie Example",
      "last_edit_time": null,
      "last_calc_time": null,
      "time_updated": "2026-08-13T15:04:05.000Z",
      "invoice_date": null,
      "due_date": null,
      "terms": null,
      "term_id": null,
      "time_created": "2026-08-13T15:04:05.000Z",
      "purchase_global_id": "11111BBBBBEEEEE11111BBBBBE",
      "receiving_num": null,
      "purchase_transactions": [
        {
          "id": 71101,
          "product_id": 30008,
          "num_units": 288,
          "batch_code": "B-1042",
          "expiration_date": "2027-01-15",
          "needs_activation": false,
          "activation_task_id": null
        }
      ]
    }
  ],
  "page": 1,
  "page_size": 50,
  "has_next_page": false
}
POST
/purchases
Not available to Customer keys Beta

Creates a purchase order. By default the purchase is created as an editable draft; pass submit=true as a query parameter to create and submit it in a single call. The response carries the new purchase's global ID, and a Location header pointing at the purchase, which is how you address it for later reads, edits, and submission. Not accessible to Customer API keys.

Callout:
po_num must be unique for the vendor, and that is what makes a retry safe: if a request times out after the purchase was already created, sending it again with the same po_num returns 409 DUPLICATE_PO_NUMBER instead of creating a second purchase order. The error's detail names the existing purchase's global ID, so you can go read it directly rather than searching for it.
Parameters
Name Type Required Description
Idempotency-Key
header
string optional
Optional for POST and PATCH requests. Send a unique key for each logical mutation so an exact retry can replay the original response instead of running the operation again.
Prefer
header
string optional
Use return=minimal to omit the response body; return=representation is the default. Use handling=lenient to ignore unrecognized fields where supported.
submit
query
boolean optional
When true, creates the purchase directly in Submitted status after validating it is ready to submit.
Request Body
Field Type Required Description
vendor_id
body
number required
The vendor the purchase order is placed with.
to_location_id
body
number required
The location receiving the purchase.
supplier_id
body
number required
The supplier the purchase is for. Must be one of your authorized suppliers.
supplier_name
body
string optional
Supplier name used in the purchase memo. Falls back to the vendor's name when omitted.
delivery_date
body
date required
Requested delivery date as YYYY-MM-DD.
po_num
body
string required
Your purchase order number. Must be unique for the vendor.
purchase_transactions
body
object[] optional
created_by_user_id
body
number optional
Honored for Employee keys only; other keys use the key's own user.
application/json
{
  "vendor_id": 50002,
  "to_location_id": 40002,
  "supplier_id": 20001,
  "supplier_name": "Acme Brands",
  "delivery_date": "2026-08-20",
  "po_num": "PO-2026-00000",
  "purchase_transactions": [
    {
      "product_id": 30008,
      "cases": 12,
      "batch_code": "B-1042",
      "expiration_date": "2027-01-15"
    },
    {
      "product_id": 30009,
      "units": 48
    }
  ]
}
Field Definitions
Field Description
purchase_global_id
The purchase's permanent identifier. Use it to read, edit, submit, or delete the purchase.
purchase_id
The numeric ERP purchase ID. Null until a purchase originated here has synced into the ERP.
status
InProgress for an editable draft, Submitted once it has been handed off for import.
total_cases
Total case count across all line items.
Responses
Status Description
201
Created. If Prefer: return=minimal is sent, the Location header is returned with no response body.
400
Validation failed.
401
The request is missing a valid API key.
403
The API key is not authorized to access this resource.
409
The request conflicts with an existing purchase or idempotency key.
413
The purchase body is too large.
415
The request content type is not supported.
422
The request is well-formed but could not be accepted.
429
Rate limit exceeded.
500
Unexpected server error.
201 Response Headers
Name Type Description
Location
string
Canonical URL for the created purchase, addressed by purchase_global_id.
Idempotency-Replayed
string
true when this response was replayed from a previous request with the same Idempotency-Key.
Preference-Applied
string
Echoes honored Prefer tokens, such as return=minimal or handling=lenient.
Example Response
json
{
  "data": {
    "purchase_id": null,
    "receive_date": null,
    "shipment_num": null,
    "shipment_id": null,
    "to_location_id": 40002,
    "to_location_name": null,
    "vendor_name": null,
    "vendor_id": 50002,
    "post_date": null,
    "status": "InProgress",
    "po_num": "PO-2026-00000",
    "freight": "0.00",
    "tax": "0.00",
    "other_cost": "0.00",
    "total": "0.00",
    "total_cases": "30",
    "public_pdf_link": null,
    "purchase_pdf_url_api_key_id": null,
    "memo": "Acme Brands - Submitted via KSS Live by Jamie Example",
    "last_edit_time": null,
    "last_calc_time": null,
    "time_updated": "2026-08-13T15:04:05.000Z",
    "invoice_date": null,
    "due_date": null,
    "terms": null,
    "term_id": null,
    "time_created": "2026-08-13T15:04:05.000Z",
    "purchase_global_id": "11111BBBBBEEEEE11111BBBBBE",
    "receiving_num": null
  }
}
POST
/purchases/validate
Not available to Customer keys Beta

Validates a purchase order without creating anything, returning whether it is acceptable and its computed totals. Validates against the rules that apply at submit time: the purchase must have at least one line item, every quantity must be positive, and batch codes must be present where the vendor requires them, po_num must be unique for the vendor. Not accessible to Customer API keys.

Parameters
Name Type Required Description
Prefer
header
string optional
Use return=minimal to omit the response body; return=representation is the default. Use handling=lenient to ignore unrecognized fields where supported.
Request Body
Field Type Required Description
vendor_id
body
number required
The vendor the purchase order is placed with.
to_location_id
body
number required
The location receiving the purchase.
supplier_id
body
number required
The supplier the purchase is for. Must be one of your authorized suppliers.
supplier_name
body
string optional
Supplier name used in the purchase memo. Falls back to the vendor's name when omitted.
delivery_date
body
date required
Requested delivery date as YYYY-MM-DD.
po_num
body
string required
Your purchase order number. Must be unique for the vendor.
purchase_transactions
body
object[] optional
created_by_user_id
body
number optional
Honored for Employee keys only; other keys use the key's own user.
application/json
{
  "vendor_id": 50002,
  "to_location_id": 40002,
  "supplier_id": 20001,
  "supplier_name": "Acme Brands",
  "delivery_date": "2026-08-20",
  "po_num": "PO-2026-00000",
  "purchase_transactions": [
    {
      "product_id": 30008,
      "cases": 12,
      "batch_code": "B-1042",
      "expiration_date": "2027-01-15"
    },
    {
      "product_id": 30009,
      "units": 48
    }
  ]
}
Field Definitions
Field Description
valid
True when the purchase passed every validation check.
total_cases
Total case count derived across all line items.
Responses
Status Description
200
Validation result.
400
Validation failed.
401
The request is missing a valid API key.
403
The API key is not authorized to access this resource.
409
The purchase conflicts with an existing purchase.
413
The request body is too large.
415
The request content type is not supported.
422
The request is well-formed but could not be accepted.
429
Rate limit exceeded.
500
Unexpected server error.
Example Response
json
{
  "data": {
    "valid": true,
    "total_cases": 30
  }
}
GET
/purchases/{purchaseID}
Not available to Customer keys Beta

Returns a single purchase order. purchase_transactions are included by default; send include_transactions=false to return the purchase header only. Accepts either the purchase's global ID or its numeric ERP purchase ID, and resolves a purchase order originated here as readily as one the ERP has posted. A global ID resolves for the whole life of the purchase: while it is still a draft that has not reached the ERP, and afterwards once the ERP has posted it, so the URL returned when a purchase is created never stops working. The numeric ERP purchase ID resolves the ERP-posted purchase, and also resolves a purchase order originated here once it carries that ID.

Parameters
Name Type Required Description
purchaseID
path
string required
The purchase's global ID or its numeric ERP purchase ID. Either resolves a purchase order originated here as well as one the ERP has posted.
include_transactions
query
boolean optional
Line items are included by default. Send false to omit purchase_transactions.
Responses
Status Description
200
OK
400
The request is missing required input or contains invalid input.
401
The request is missing a valid API key.
403
The API key is not authorized to access this resource.
404
The requested resource was not found.
429
Rate limit exceeded.
500
Unexpected server error.
Example Response
json
{
  "data": {
    "purchase_id": 70001,
    "receive_date": "2026-06-02T06:00:00.000Z",
    "shipment_num": "Example PO 70001",
    "shipment_id": 72001,
    "to_location_id": 40001,
    "to_location_name": "Alameda",
    "vendor_name": "EXAMPLE DISTRIBUTORS LLC (Example Location)",
    "vendor_id": 50001,
    "post_date": "2026-06-02T06:00:00.000Z",
    "status": "Verified",
    "po_num": "Example PO 70001",
    "freight": "0.00",
    "tax": "0.00",
    "other_cost": "0.00",
    "total": "35726.38",
    "total_cases": "184.00",
    "public_pdf_link": null,
    "purchase_pdf_url_api_key_id": 94001,
    "memo": null,
    "last_edit_time": null,
    "last_calc_time": "2026-06-04T10:20:14.000Z",
    "time_updated": "2026-08-21T18:06:57.930Z",
    "invoice_date": "2026-06-01T06:00:00.000Z",
    "due_date": "2026-08-30T06:00:00.000Z",
    "terms": "Driver Accounts",
    "term_id": 80002,
    "time_created": "2026-06-15T22:09:09.921Z",
    "purchase_global_id": "00000AAAAAFFFFF00000AAAAAF",
    "receiving_num": null,
    "purchase_transactions": [
      {
        "purchase_trans_id": 71001,
        "purchase_id": 70001,
        "product_id": 30006,
        "ordered": "10",
        "num_units": "120",
        "fob": "12.50",
        "deposit_cost": "0.00",
        "ext_price": "1500.00",
        "expiration_date": "2026-01-01T00:00:00.000Z",
        "code_date": "2025-01-15T00:00:00.000Z",
        "batch_code": "BCH-001",
        "laid_in_cost": "13.00",
        "pallet_tag": null,
        "cases": "10",
        "weight": "120.00",
        "time_updated": "2025-03-02T10:00:00.000Z"
      }
    ]
  }
}
PATCH
/purchases/{purchaseGlobalID}
Not available to Customer keys Beta

Updates a draft purchase order. Send only the fields you want to change; anything you omit is left as it is. Only drafts can be edited: a purchase that has already been submitted returns 409. Not accessible to Customer API keys.

Callout:
Including purchase_transactions replaces every line item on the purchase with the array you send, and an empty array removes them all. Leave the field out entirely to keep the existing line items. Status is never set here, use the submit action instead.
Parameters
Name Type Required Description
Idempotency-Key
header
string optional
Optional for POST and PATCH requests. Send a unique key for each logical mutation so an exact retry can replay the original response instead of running the operation again.
purchaseGlobalID
path
string required
The global ID of the draft purchase to update.
Prefer
header
string optional
Use return=minimal to omit the response body; return=representation is the default. Use handling=lenient to ignore unrecognized fields where supported.
Request Body
Field Type Required Description
vendor_id
body
number optional
The vendor the purchase order is placed with.
to_location_id
body
number optional
The location receiving the purchase.
delivery_date
body
date optional
Requested delivery date as YYYY-MM-DD.
po_num
body
string optional
Your purchase order number. Must remain unique for the vendor.
purchase_transactions
body
object[] optional
When present, replaces all line items on the draft purchase.
application/json
{
  "delivery_date": "2026-08-22",
  "po_num": "PO-2026-00000-REV2",
  "purchase_transactions": [
    {
      "product_id": 30008,
      "cases": 15,
      "batch_code": "B-1042",
      "expiration_date": "2027-01-15"
    }
  ]
}
Responses
Status Description
200
Updated draft purchase with the updated representation.
204
Updated draft purchase. Returned when Prefer: return=minimal is sent.
400
Validation failed.
401
The request is missing a valid API key.
403
The API key is not authorized to access this resource.
404
Purchase not found.
409
The purchase cannot be edited in its current state.
413
The request body is too large.
415
Unsupported request content type.
422
The request is well-formed but could not be accepted.
429
Rate limit exceeded.
500
Unexpected server error.
200 Response Headers
Name Type Description
Idempotency-Replayed
string
true when this response was replayed from a previous request with the same Idempotency-Key.
Preference-Applied
string
Echoes any honored Prefer tokens, such as return=minimal or handling=lenient.
Example Response
json
{
  "data": {
    "purchase_id": null,
    "receive_date": null,
    "shipment_num": null,
    "shipment_id": null,
    "to_location_id": 40002,
    "to_location_name": null,
    "vendor_name": null,
    "vendor_id": 50002,
    "post_date": null,
    "status": "InProgress",
    "po_num": "PO-2026-00000-REV2",
    "freight": "0.00",
    "tax": "0.00",
    "other_cost": "0.00",
    "total": "0.00",
    "total_cases": "45",
    "public_pdf_link": null,
    "purchase_pdf_url_api_key_id": null,
    "memo": "Acme Brands - Submitted via KSS Live by Jamie Example",
    "last_edit_time": null,
    "last_calc_time": null,
    "time_updated": "2026-08-13T16:20:11.000Z",
    "invoice_date": null,
    "due_date": null,
    "terms": null,
    "term_id": null,
    "time_created": "2026-08-13T15:04:05.000Z",
    "purchase_global_id": "11111BBBBBEEEEE11111BBBBBE",
    "receiving_num": null
  }
}
DELETE
/purchases/{purchaseGlobalID}
Not available to Customer keys Beta

Deletes a draft purchase order. Responds 204 with no body. Only drafts can be deleted: a purchase that has already been submitted returns 409, and a purchase that does not exist or has already been deleted returns 404. Not accessible to Customer API keys.

Parameters
Name Type Required Description
purchaseGlobalID
path
string required
The global ID of the draft purchase to delete.
Responses
Status Description
204
No Content
400
The request is missing required input or contains invalid input.
401
The request is missing a valid API key.
403
The API key is not authorized to access this resource.
404
Purchase not found.
409
The purchase cannot be deleted in its current state.
429
Rate limit exceeded.
500
Unexpected server error.
POST
/purchases/{purchaseGlobalID}/submit
Not available to Customer keys Beta

Submits a draft purchase order, handing it off for import. The purchase's own contents are re-checked at this point: it must have at least one line item, every quantity must be positive, and batch codes must be present where the vendor requires them. A purchase that has already been submitted returns 409. A successful submit starts the import to the ERP in the background; the response does not wait for it to finish. Not accessible to Customer API keys.

Parameters
Name Type Required Description
Idempotency-Key
header
string optional
Optional for POST and PATCH requests. Send a unique key for each logical mutation so an exact retry can replay the original response instead of running the operation again.
purchaseGlobalID
path
string required
The global ID of the draft purchase to submit.
Prefer
header
string optional
Use return=minimal to omit the response body; return=representation is the default. Use handling=lenient to ignore unrecognized fields where supported.
Responses
Status Description
200
Submitted purchase with the updated representation.
204
Submitted purchase. Returned when Prefer: return=minimal is sent.
400
Validation failed.
401
The request is missing a valid API key.
403
The API key is not authorized to access this resource.
404
Purchase not found.
409
The purchase cannot be submitted in its current state.
429
Rate limit exceeded.
500
Unexpected server error.
200 Response Headers
Name Type Description
Idempotency-Replayed
string
true when this response was replayed from a previous request with the same Idempotency-Key.
Preference-Applied
string
Echoes any honored Prefer tokens, such as return=minimal or handling=lenient.
Example Response
json
{
  "data": {
    "purchase_id": null,
    "receive_date": null,
    "shipment_num": null,
    "shipment_id": null,
    "to_location_id": 40002,
    "to_location_name": null,
    "vendor_name": null,
    "vendor_id": 50002,
    "post_date": null,
    "status": "Submitted",
    "po_num": "PO-2026-00000",
    "freight": "0.00",
    "tax": "0.00",
    "other_cost": "0.00",
    "total": "0.00",
    "total_cases": "30",
    "public_pdf_link": null,
    "purchase_pdf_url_api_key_id": null,
    "memo": "Acme Brands - Submitted via KSS Live by Jamie Example",
    "last_edit_time": null,
    "last_calc_time": null,
    "time_updated": "2026-08-13T17:02:44.000Z",
    "invoice_date": null,
    "due_date": null,
    "terms": null,
    "term_id": null,
    "time_created": "2026-08-13T15:04:05.000Z",
    "purchase_global_id": "11111BBBBBEEEEE11111BBBBBE",
    "receiving_num": null
  }
}
Purchase Transactions
GET
/purchaseTrans
Not available to Customer keys Paginated Beta

Returns purchase order line items for one or more purchases. purchase_ids is required. Not accessible to Customer API keys.

Parameters
Name Type Required Description
purchase_ids
query
string required
Comma-separated list of purchase IDs to retrieve line items for.
page
query
number optional
Page number to retrieve. Defaults to 1.
page_size
query
number optional
Number of rows to return per page. Defaults to 50; maximum is 500.

Supports Page and PageSize query parameters. Default page size: 50. Maximum page size: 500 — larger values are reduced to 500.

Responses
Status Description
200
OK
400
The request is missing required input or contains invalid input.
401
The request is missing a valid API key.
403
The API key is not authorized to access this resource.
429
Rate limit exceeded.
500
Unexpected server error.
Example Response
json
{
  "data": [
    {
      "purchase_trans_id": 71001,
      "purchase_id": 70002,
      "product_id": 30006,
      "ordered": "10",
      "num_units": "120",
      "fob": "12.50",
      "deposit_cost": "0.00",
      "ext_price": "1500.00",
      "expiration_date": "2026-01-01T00:00:00.000Z",
      "code_date": "2025-01-15T00:00:00.000Z",
      "batch_code": "BCH-001",
      "laid_in_cost": "13.00",
      "pallet_tag": null,
      "cases": "10",
      "weight": "120.00",
      "time_updated": "2025-03-02T10:00:00.000Z"
    }
  ],
  "page": 1,
  "page_size": 50,
  "has_next_page": false
}