Skip to main content

List orders

Read the seller’s order history, newest first, with the same filters the Hoard dashboard exposes. Each order can optionally embed its line items.
This endpoint is mounted at /api/orders, not /api/v1/orders — the /api/v1/orders POST is a separate upload surface (see below). Bearer authentication is supported (Authorization: Bearer YOUR_API_KEY) for AI assistants and integrations.

Line items

By default, each order in the response carries up to 20 line items, sorted by id ascending. The response also includes items_truncated and items_total_count so the caller knows whether they got every item.
  • ?items_per_order=N — change the cap. Clamped to 0..200. 0 omits items entirely (legacy callers that only need order headers).
  • ?items=full — return every line item on every order. Use this when building a packing slip or auditing a refund. Pairs poorly with very wide pages — prefer per_page=10&items=full over per_page=200&items=full.
When items are returned, each item has this shape: Refund, discount, tax, and internal id fields are intentionally omitted from the embedded line-item shape. If you need per-line refund detail, the dashboard exposes it on the individual order page. Order-level refund fields are present on each order header: refund_type (full / partial), refund_origin (who initiated it, e.g. tcgplayer), refund_amt (refunded dollars as a USD string), refund_reason, and refund_note. All are null when the order was not refunded; refund_amt being absent means “not refunded”, distinct from a $0 refund. refund_reason and refund_note are buyer/marketplace-authored free text — on this read surface they are length-bounded and stripped of control / zero-width characters.

Other filters

All standard order filters work — pass any combination:
  • page (default 1), per_page (default 50, max 200)
  • sort = date | total | buyer | status | number (default date), direction = asc | desc (default desc)
  • status — one status, or status[]=Completed&status[]=Refunded for many
  • search — order number or buyer name (case-insensitive substring)
  • date_from, date_toYYYY-MM-DD window on order_date
  • product_line — restrict to orders containing at least one item in the given game
  • refund=true — only refunded orders
  • unfeedbacked=true — only orders with no seller feedback yet
  • shipping_type = pwe | tracked | expedited
  • ship_mark=pending — only orders the seller has marked Shipped that have not yet synced back from TCGplayer (the “pushing to TCGplayer” working set). Each order row carries shipped_marked_at (timestamp, null if never marked) and marked_shipped_pending (boolean, true while the optimistic mark is still ahead of the synced status).
  • pull_session — a pull session id, or one of: active (the open session), none (available to pull — excludes dismissed orders), dismissed (orders excluded from pulls). Each order row includes pull_dismissed_at (timestamp, null when the order is still pullable).

Example response

curl example


Upload orders

Upload parsed order data from TCGplayer’s order export. The request is shape-validated synchronously and queued for upsert in a background job — the response is 202 Accepted and the database write happens asynchronously. Orders are upserted by (user_id, order_number) so re-uploading the same orders is safe.
The endpoint accepts both raw JSON and gzip-compressed JSON. For large batches (typically the first full-history upload), gzip is preferred — set Content-Type: application/gzip and gzip the JSON body. The server transparently decompresses gzip and falls back to raw bytes when the body is not gzip-encoded. Request body:

Order object fields

Response:
HTTP status is 202 Accepted — the server has validated the payload shape and enqueued the upsert. The count field reflects the number of orders in the request (not the number of new rows — duplicates are updated in place). If an active Pull session exists, the same upload also checks refreshed orders against Pull eligibility. Orders that are now cancelled, shipped, refunded, or otherwise no longer pullable stay in the session but are marked for review so the tablet queue can warn the puller instead of silently dropping work.

curl example

For a large batch, gzip the JSON first:

Error responses

Notes

  • Hoard parses TCGplayer’s order export CSV and converts it to this JSON format
  • First sync sends full order history (from January 2020)
  • Subsequent syncs send a rolling window of recent orders to keep their status current; older history is sent once and not re-sent every sync
  • Focused refresh_orders tasks reuse the same upload endpoint after Hoard fetches updated orders
  • Order upload is non-fatal. If it fails, the inventory sync still completes.
  • Active Pull sessions keep their snapshot stable; refreshed orders that drift out of eligibility are flagged in the Pull queue.

Upload order refunds

Upload parsed refund rows from TCGplayer’s order export. The request is shape-validated synchronously and queued for upsert in a background job — the response is 202 Accepted and the database write happens asynchronously. Refund rows are upserted by (user_id, order_number), either creating new orders or enriching existing ones with refund metadata.
The endpoint accepts both raw JSON and gzip-compressed JSON. For large batches, set Content-Type: application/gzip and gzip the JSON body. The server transparently decompresses gzip and falls back to raw bytes when the body is not gzip-encoded. Request body:
Response:
HTTP status is 202 Accepted — the server has validated the payload shape and enqueued the upsert. The count field reflects the number of refund rows in the request.

curl example

For a large batch, gzip the JSON first:

Error responses


Upload order line items

Upload parsed line items for existing orders. The request is shape-validated synchronously and queued for upsert in a background job — the response is 202 Accepted and the database write happens asynchronously. Items are upserted by (order_id, sku_id). Items whose order_number has no matching order owned by the user are silently skipped, and multiple sku-less rows per order are allowed.
The endpoint accepts both raw JSON and gzip-compressed JSON. The same gzip fallback rules as /api/v1/orders apply. Request body:
Response:

curl example

For a large batch, gzip the JSON first:

Error responses


Upload order shipping

Upload shipping enrichment (carrier, address, tracking, weight) for existing orders. The request is shape-validated synchronously and queued for a bulk SQL update in a background job — the response is 202 Accepted and the database write happens asynchronously. Updates are keyed on (user_id, order_number); unknown order numbers are silently skipped.
The endpoint accepts both raw JSON and gzip-compressed JSON. The same gzip fallback rules as /api/v1/orders apply. Request body:
Response:

curl example

For a large batch, gzip the JSON first:

Error responses


Upload seller feedback

Upload seller feedback ratings scraped from TCGplayer. Matches each item to an existing order by order_number and stores the rating and comment. Items with no matching order or ratings outside 1–5 are silently skipped.
Request body:

Feedback object fields

Response:
The updated field is the number of orders that had feedback written to them.

curl example

Error responses