Skip to content
Bloomcount API
Esc
navigateopen⌘Jpreview

Create or update a price list with optional entries

ID-keyed upsert for the price list itself, plus a bulk upsert of price entries against existing variants.

Pricing method (flower / material): the storage convention is “priceExclTax is always the pack price; pricingMethod is a display flag.” This endpoint does the conversion for you — supply whichever method you have, and the right cost is recorded internally.

Hire price lists (productType: "hire"): each entry’s priceExclTax is the daily hire fee for one unit, stored as-is. Omit pricingMethod — it’s ignored for hire entries. Hire price lists list every hireable material variant on the tenant; setting an entry registers a daily fee for that variant on this list.

Tax group: pass taxGroupId: null to clear. Cross-tenant IDs return tax_group_not_found (422).

Clearing a price: an entry row with remove: true deletes that variant’s price on the list. A price is addressed by list and variant rather than by an id of its own, which is why this lives here rather than on a DELETE route. Cleared rows come back in removed, and a row for a variant that had no price is reported there too rather than as an error, since the end state is the same.

Errors (per entry row, in errors)

  • variant_not_found — the variantId is unknown or belongs to another tenant.
  • price_required — a row that neither sets priceExclTax nor asks to remove.

Whole-request failures: 422 price_list_name_required when creating without a name, 404 price_list_not_found for an unknown id, 422 tax_group_not_found for a tax group on another tenant, and 422 too_many_items above 500 entries.

POST/api/v1/price-lists
Authorization
AuthorizationBearer token (bloomcount_...) · headerrequired
Header parameters
Idempotency-Keystring
Replays return the cached response. 24h TTL, scoped per API key.
Request body
requiredapplication/json
priceListPriceListUpsertrequired
Show properties
idstring
Existing price-list ID. Present → update; absent → create.
namestring
descriptionstring
datestring
productTypestring
Restricts which variants this list can price. - `flower` — fresh-stem variants only. - `material` — sundry variants only. - `hire` — studio-owned hireable variants only. Entries are read as the daily hire fee.
Allowed:flowermaterialhire
defaultMarkupMultipliernumber<float>
2.5 = 150% markup on cost. Applied at quote-time.
taxGroupIdstring | null
Set to a valid tax group ID, or `null` to clear an existing assignment.
taxExemptboolean
entriesPriceEntry[]required
max items 500
Show properties
Array of PriceEntry
variantIdstringrequired
removeboolean
Clears this variant's price on the list instead of setting one. Omit priceExclTax when it is set. A row for a variant that has no price on the list is reported as removed rather than as an error, since the end state is the same.
priceExclTaxnumber<float>
Numeric price. The unit depends on the parent price list's `productType`: - Flower / material lists — combined with `pricingMethod` to mean either per-stem or per-pack; the endpoint converts to internal pack-price storage using the variant's `unitsPerPack`. - Hire lists — the daily hire fee for one unit. No conversion happens; the value is stored as-is and used directly when calculating `dailyFee × days × qty` on hire-mode event lines. `pricingMethod` is ignored for hire entries.
pricingMethodstring
Display flag and unit-of-measure for the price you supply on flower / material entries. Ignored on entries that belong to a `hire` price list. Internally the API always stores the per-pack cost — pass whichever method you have on hand and the conversion uses the variant's `unitsPerPack`. - `stem` — `priceExclTax` is the cost per single stem (e.g. `1.50` per rose). Multiplied by `unitsPerPack` for storage. - `pack` — `priceExclTax` is the cost for the whole pack (e.g. `15.00` for 10 stems). Stored as-is. For `material` variants without a meaningful pack size, use `pack`.
Allowed:stempack
Responses
200Update without create-flag set
priceListIdstringrequired
removedobject[]required
Rows that cleared a price. A variant that had none is listed here too.
Show properties
Array of object
indexintegerrequired
variantIdstringrequired
upsertedobject[]required
Show properties
Array of object
indexintegerrequired
variantIdstringrequired
entryIdstringrequired
errorsobject[]required
Show properties
Array of object
indexintegerrequired
variantIdstringrequired
errorstringrequired
201Upsert succeeded
priceListIdstringrequired
removedobject[]required
Rows that cleared a price. A variant that had none is listed here too.
Show properties
Array of object
indexintegerrequired
variantIdstringrequired
upsertedobject[]required
Show properties
Array of object
indexintegerrequired
variantIdstringrequired
entryIdstringrequired
errorsobject[]required
Show properties
Array of object
indexintegerrequired
variantIdstringrequired
errorstringrequired
401Missing or invalid API key, or revoked / expired.
errorstringrequired
403Authenticated, but the key lacks the required scope or the tenant has no API access.
errorstringrequired
422Request body or arguments failed validation.
errorstringrequired
429Per-minute rate limit (60/min) or per-month cap exceeded.
errorstringrequired
Try it
Server
Authorization
Parameters
Bodyapplication/json
Request
curl -X POST "https://app.bloomcount.com/api/v1/price-lists" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "priceList": {
    "id": "string",
    "name": "April supplier prices",
    "description": "string",
    "date": "2026-04-29",
    "productType": "flower",
    "defaultMarkupMultiplier": 2.5,
    "taxGroupId": "string",
    "taxExempt": true
  },
  "entries": [
    {
      "variantId": "string",
      "remove": true,
      "priceExclTax": 1.5,
      "pricingMethod": "stem"
    }
  ]
}'
Response
{
  "priceListId": "string",
  "removed": [
    {
      "index": 0,
      "variantId": "string"
    }
  ],
  "upserted": [
    {
      "index": 0,
      "variantId": "string",
      "entryId": "string"
    }
  ],
  "errors": [
    {
      "index": 0,
      "variantId": "string",
      "error": "string"
    }
  ]
}