Platform · Preview

REST API Reference

The Hygrade REST API gives you programmatic access to orders, catalog, customers, and users. JSON over HTTPS, OAuth 2.0 bearer authentication, predictable resource URLs, and first-class pagination.

!

Preview release. The Hygrade REST API is currently in limited preview. Endpoints marked Preview may change before general availability. Production rollout is targeted for Q3 2026 — early-access customers are welcome to build against the current surface with a signed preview agreement.

Base URL

Base URL
PRODhttps://api.hygradebusiness.com/v1/
TESThttps://api.test.hygradebusiness.com/v1/
OpenAPI spec
PRODhttps://api.hygradebusiness.com/v1/openapi.json
TESThttps://api.test.hygradebusiness.com/v1/openapi.json

Authentication

All requests require an OAuth 2.0 bearer token. Use the Client Credentials grant for server-to-server integrations, or the Authorization Code flow for user-delegated access.

Authenticated request
curl https://api.hygradebusiness.com/v1/orders \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsI..." \
  -H "Accept: application/json"

Idempotency. For any POST endpoint that creates a resource, include an Idempotency-Key header with a unique value (UUID recommended). Retries with the same key within 24 hours return the original response.

Conventions

Pagination

List endpoints are cursor-paginated. Pass limit (default 25, max 100) and starting_after.

Response envelope
{
  "object": "list",
  "url": "/v1/orders",
  "has_more": true,
  "next_cursor": "ord_8c3e47a9b1f240d6",
  "data": [ /* items */ ]
}

Errors

Errors return a machine-readable code and a human-readable message. The HTTP status is significant.

422 Unprocessable Entity
{
  "error": {
    "type": "invalid_request",
    "code": "missing_required_field",
    "message": "The field 'shipping_address.postal_code' is required.",
    "param": "shipping_address.postal_code",
    "request_id": "req_93f0c2a7d4e1b82c"
  }
}

Rate limits

All tokens are limited to 120 requests per second, bursting to 240. Responses include X-RateLimit-Remaining and X-RateLimit-Reset headers. Over-limit returns 429 with Retry-After.

Versioning

The API is versioned in the URL (/v1/). Breaking changes are released under a new version. Additive changes — new fields, new endpoints — may ship on /v1/ without warning; write parsers that ignore unknown fields.


Orders

Place, retrieve, and cancel orders. An Order consists of one or more OrderItems and, for approval-enabled accounts, passes through an approval chain before fulfillment.

List orders

GET /v1/orders
cust_idstring
Filter to orders for a specific customer account. For multi-account clients.
statusenum
One of pending_approval, approved, in_production, shipped, delivered, cancelled.
created_afterISO 8601
Inclusive lower bound for order creation timestamp.
limitinteger
Page size. Default 25, max 100.

Retrieve an order

GET /v1/orders/{id}
Example response
{
  "id": "ord_8c3e47a9b1f240d6",
  "object": "order",
  "cust_id": "ACME001",
  "ordered_by": { "login": "jdoe", "name": "Jane Doe" },
  "status": "approved",
  "submitted_at": "2026-04-12T18:22:03Z",
  "approved_at":  "2026-04-12T19:01:47Z",
  "shipping_address": {
    "attention": "Jane Doe",
    "street_1":  "4420 Industrial Blvd",
    "city":      "Cincinnati",
    "region":    "OH",
    "postal_code": "45241",
    "country":   "US"
  },
  "cost_center": "CC-4420",
  "po_number":   "PO-2026-0881",
  "items": [
    {
      "id": "oi_1a7e3b82",
      "item_code": "FM-0014-LT",
      "description": "Letterhead — 500 ct, #10 stock",
      "quantity": 3,
      "unit_price": { "amount": 2450, "currency": "USD" },
      "line_total": { "amount": 7350, "currency": "USD" }
    }
  ],
  "subtotal":   { "amount": 7350, "currency": "USD" },
  "tax":        { "amount":  514, "currency": "USD" },
  "shipping":   { "amount": 1200, "currency": "USD" },
  "total":      { "amount": 9064, "currency": "USD" }
}

Create an order

POST /v1/orders
Request
curl -X POST https://api.hygradebusiness.com/v1/orders \
  -H "Authorization: Bearer eyJhbGci..." \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "cust_id": "ACME001",
    "shipping_address_id": "addr_1c9d2f3b",
    "cost_center": "CC-4420",
    "po_number": "PO-2026-0881",
    "items": [
      { "item_code": "FM-0014-LT", "quantity": 3 }
    ]
  }'

Cancel an order

POST /v1/orders/{id}/cancel

Only permitted for orders in pending_approval or approved status. Orders in production cannot be cancelled through the API — contact client services.


Catalog

Read the product catalog available to a given customer account. Catalog visibility is scoped per-account — the same item may appear with different pricing or availability for different customers.

List items

GET /v1/catalog/items
cust_idstringrequired
Return the catalog as it appears to this customer account.
category_idstring
Filter to items in a specific catalog category.
qstring
Full-text query across item name, description, and SKU.
availableboolean
When true, exclude items that are discontinued or out of stock.

Retrieve an item

GET /v1/catalog/items/{id}
Example item
{
  "id": "itm_5e2c8d14",
  "object": "catalog_item",
  "item_code": "FM-0014-LT",
  "name": "Letterhead — #10 stock",
  "description": "Full-color letterhead printed on 24lb cotton stock.",
  "category": { "id": "cat_forms", "name": "Forms & Stationery" },
  "flags": ["form", "imprint"],
  "images": [
    "https://cdn.hygradebusiness.com/catalog/ACME001/fm-0014-lt-1.png"
  ],
  "pricing": [
    { "min_qty":   1, "unit_price": { "amount": 2450, "currency": "USD" } },
    { "min_qty":  10, "unit_price": { "amount": 2175, "currency": "USD" } },
    { "min_qty": 100, "unit_price": { "amount": 1890, "currency": "USD" } }
  ],
  "available": true,
  "lead_time_days": 5
}

Customers

Customer accounts represent the companies Hygrade sells to. Most integrations scope requests to a single account via cust_id. Parent/child account hierarchies are supported for enterprise customers with multiple subsidiaries.

List customer accounts

GET /v1/customers

Retrieve an account

GET /v1/customers/{cust_id}
Example customer
{
  "id": "ACME001",
  "object": "customer",
  "name": "Acme Corporation",
  "parent_cust_id": null,
  "created_at": "2023-11-14T00:00:00Z",
  "addresses": [
    {
      "id": "addr_1c9d2f3b",
      "type": "shipping",
      "label": "HQ - Cincinnati",
      "street_1": "4420 Industrial Blvd",
      "city": "Cincinnati",
      "region": "OH",
      "postal_code": "45241",
      "country": "US",
      "default": true
    }
  ],
  "approval_required_over": { "amount": 50000, "currency": "USD" },
  "billing_terms": "NET30"
}

Users

Shopper records. For most customers, this endpoint is fed by SCIM provisioning; you can also create and update users directly if you’re not running SCIM.

List users

GET /v1/users

Retrieve a user

GET /v1/users/{login}

Create a user

POST /v1/users

Update a user

PATCH /v1/users/{login}

Deactivate a user

POST /v1/users/{login}/deactivate

Approvals

Query and act on orders pending approval. Approval chains are configured per customer account; the API exposes read access to the chain and write access to approvers’ own pending queues.

List pending approvals

GET /v1/approvals?approver={login}

Approve an order

POST /v1/approvals/{approval_id}/approve

Reject an order

POST /v1/approvals/{approval_id}/reject
POST body
{
  "reason": "Over budget for this quarter. Resubmit after 2026-07-01."
}

SDKs

Official SDKs are being published as the API moves toward general availability. Until then, generate client code from the OpenAPI spec.

LanguagePackageStatus
Node.js / TypeScript@hygrade/apiPreview
PHPhygrade/api-phpPreview
Pythonhygrade-apiBeta (Q3 2026)
Gogithub.com/hygrade/go-apiBeta (Q3 2026)

Prefer push over poll. If you plan to poll /v1/orders for status changes, subscribe to webhooks instead — you’ll see state transitions within seconds, and your rate-limit budget stays free for other work.