Skip to content

Get stock levels for products

Open .md

POST/v1/api/store/{team_slug}/product_stock

v1Operation ID v1_public_misc_product_stock

Read-only: returns the shop stock you hold for each product you list. Nothing is reserved or moved. Stock adjustments, stock takes and transfers are not part of the public API.

For each product the answer has id, type and total: stock_on_hand, stock_incoming (on purchase orders not yet received), stock_not_usable and qty_need_ordering, as decimal strings with eight decimal places, such as "24.00000000" ("0" when no stock row or aggregate matches; parse them as decimals), summed over your warehouses or, with warehouse_id, for that warehouse only. inventories lists the stock rows behind the totals, one per warehouse.

Customer-owned stock and hidden or deleted stock rows are left out. custom items are skipped, so the answer can be shorter than the list you sent.

Type names differ by operation. Here and on Load a product for a sales order line, your own simple product is db_simple; on sales order lines the same product is user_simple. A variant is db_variant and a catalog product db_catalog everywhere.

Permission

Any member of the team.

Business rules

  • Deleted simple products and variants are still answered; an id that does not exist fails the whole request with 404.

Path parameters

  • team_slugstringrequired

    Your team slug, shown as Team ID next to your API key in Profile.

    • Example your-team

Request body

application/json, required.

  • productarray of objectsrequired
    • At least 1 item
    Fields of each item (2)
    • typestringrequired

      A simple product, a variant, a catalog product, or a custom line (skipped).

      • One of: "db_simple", "db_variant", "db_catalog", "custom"
    • idstring

      Required unless type is custom. A product or variant hash id, or a catalog product id such as ssa-B00000001.

  • A company location that holds stock. Leave it out to sum all of them.

Response

200Successful response.

  • dataarray of objectsrequired
    Fields of each item (4)
    • idstringrequired
    • totalobjectrequired
      Child fields (4)
      • qty_need_orderingstringrequired

        How many sales orders need that stock does not cover. A decimal string, such as "24.00000000"; parse it as a decimal ("0" when there is no aggregate).

      • stock_incomingstringrequired

        A decimal string, such as "24.00000000"; parse it as a decimal.

      • stock_not_usablestringrequired

        A decimal string, such as "24.00000000"; parse it as a decimal.

      • stock_on_handstringrequired

        A decimal string, such as "24.00000000"; parse it as a decimal ("0" when there is no stock row).

    • typestringrequired

      The line type: db_simple, db_variant or db_catalog.

    • inventoriesarray of objects
      Fields of each item (5)
  • statusintegerrequired
  • successbooleanrequired

Errors

  • 401The API key is missing or wrong (unauthenticated).

  • 403You are not allowed to do this. api_access_not_in_plan: your team's plan doesn't include API access (Pro and above, with an active subscription or trial), so every request answers this until the team upgrades. When your role lacks the permission the operation needs, the body is only {"message": "Insufficient Permission"}. Other refusals use the error envelope, with unauthorized or user_is_not_authorized.

  • 404Not found. page_not_found: the team slug is unknown, you are not a member of the team, or an id in the path is not one of this team's. code: null, with a message that starts "No query results for": there is no record with that id.

    When
    An id does not exist for its type. Nothing is returned for the others. error.code is null and error.message names the record type.
    Fix
    Check each id and type.
  • 422The request was refused and changed nothing. validation_failed lists what to fix in error.fields; other codes name a business rule, explained in error.message. A few checks answer with only {"message": "..."}. An operation that calls another service (a payment provider, a carrier, an accounting app) can answer connect_timeout ("Please retry again") when that service does not answer in time: the change may or may not have happened there, so read the record back before you retry.

    When
    product is empty, a type is not allowed, or an id is missing. error.code is validation_failed.
    Fix
    Fix each field named in error.fields; its keys are field paths such as contact.0.phone.

Notes

  • This is your own stock. A supplier's stock comes from Get live supplier inventory.