curl --request POST \
--url https://{companyName}.api.joinluminous.com/external/api/v1/cost-rules \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"vendor_id": 42,
"name": "Material cost — SKU-ABC",
"document_types": [
"PURCHASE_ORDER"
],
"status": "ACTIVE",
"tiers": [
{
"min_quantity": "0",
"effects": [
{
"effect_type": "FIXED_PER_UNIT",
"amount": "12.50",
"sequence": 1,
"description": "Material cost"
}
]
}
],
"scopes": [
{
"scope_type": "PRODUCT",
"scope_value": "12345",
"scope_operator": "EQUALS"
}
]
}
'import requests
url = "https://{companyName}.api.joinluminous.com/external/api/v1/cost-rules"
payload = {
"vendor_id": 42,
"name": "Material cost — SKU-ABC",
"document_types": ["PURCHASE_ORDER"],
"status": "ACTIVE",
"tiers": [
{
"min_quantity": "0",
"effects": [
{
"effect_type": "FIXED_PER_UNIT",
"amount": "12.50",
"sequence": 1,
"description": "Material cost"
}
]
}
],
"scopes": [
{
"scope_type": "PRODUCT",
"scope_value": "12345",
"scope_operator": "EQUALS"
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
vendor_id: 42,
name: 'Material cost — SKU-ABC',
document_types: ['PURCHASE_ORDER'],
status: 'ACTIVE',
tiers: [
{
min_quantity: '0',
effects: [
{
effect_type: 'FIXED_PER_UNIT',
amount: '12.50',
sequence: 1,
description: 'Material cost'
}
]
}
],
scopes: [{scope_type: 'PRODUCT', scope_value: '12345', scope_operator: 'EQUALS'}]
})
};
fetch('https://{companyName}.api.joinluminous.com/external/api/v1/cost-rules', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://{companyName}.api.joinluminous.com/external/api/v1/cost-rules",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'vendor_id' => 42,
'name' => 'Material cost — SKU-ABC',
'document_types' => [
'PURCHASE_ORDER'
],
'status' => 'ACTIVE',
'tiers' => [
[
'min_quantity' => '0',
'effects' => [
[
'effect_type' => 'FIXED_PER_UNIT',
'amount' => '12.50',
'sequence' => 1,
'description' => 'Material cost'
]
]
]
],
'scopes' => [
[
'scope_type' => 'PRODUCT',
'scope_value' => '12345',
'scope_operator' => 'EQUALS'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://{companyName}.api.joinluminous.com/external/api/v1/cost-rules"
payload := strings.NewReader("{\n \"vendor_id\": 42,\n \"name\": \"Material cost — SKU-ABC\",\n \"document_types\": [\n \"PURCHASE_ORDER\"\n ],\n \"status\": \"ACTIVE\",\n \"tiers\": [\n {\n \"min_quantity\": \"0\",\n \"effects\": [\n {\n \"effect_type\": \"FIXED_PER_UNIT\",\n \"amount\": \"12.50\",\n \"sequence\": 1,\n \"description\": \"Material cost\"\n }\n ]\n }\n ],\n \"scopes\": [\n {\n \"scope_type\": \"PRODUCT\",\n \"scope_value\": \"12345\",\n \"scope_operator\": \"EQUALS\"\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://{companyName}.api.joinluminous.com/external/api/v1/cost-rules")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"vendor_id\": 42,\n \"name\": \"Material cost — SKU-ABC\",\n \"document_types\": [\n \"PURCHASE_ORDER\"\n ],\n \"status\": \"ACTIVE\",\n \"tiers\": [\n {\n \"min_quantity\": \"0\",\n \"effects\": [\n {\n \"effect_type\": \"FIXED_PER_UNIT\",\n \"amount\": \"12.50\",\n \"sequence\": 1,\n \"description\": \"Material cost\"\n }\n ]\n }\n ],\n \"scopes\": [\n {\n \"scope_type\": \"PRODUCT\",\n \"scope_value\": \"12345\",\n \"scope_operator\": \"EQUALS\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://{companyName}.api.joinluminous.com/external/api/v1/cost-rules")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"vendor_id\": 42,\n \"name\": \"Material cost — SKU-ABC\",\n \"document_types\": [\n \"PURCHASE_ORDER\"\n ],\n \"status\": \"ACTIVE\",\n \"tiers\": [\n {\n \"min_quantity\": \"0\",\n \"effects\": [\n {\n \"effect_type\": \"FIXED_PER_UNIT\",\n \"amount\": \"12.50\",\n \"sequence\": 1,\n \"description\": \"Material cost\"\n }\n ]\n }\n ],\n \"scopes\": [\n {\n \"scope_type\": \"PRODUCT\",\n \"scope_value\": \"12345\",\n \"scope_operator\": \"EQUALS\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": 123,
"vendor_id": 123,
"vendor_name": "<string>",
"name": "<string>",
"description": "<string>",
"document_type": "PURCHASE_ORDER",
"document_types": [
"PURCHASE_ORDER"
],
"tier_mode": "NON_GRADUATED",
"tier_quantity_basis": "LINE",
"priority": 123,
"status": "ACTIVE",
"is_active": true,
"effective_from": "2023-12-25",
"effective_to": "2023-12-25",
"moq": 123,
"order_multiple": 123,
"output_kind": "UNIT_COST",
"extra_cost_item_name": "<string>",
"cost_allocation_type": "UNIT_BASED_ALLOCATION",
"cost_basis": "PERCENTAGE",
"cost_basis_amount": 123,
"shipment_type": "<string>",
"options": {
"auto_apply": true,
"add_as_additional_fee": true
},
"scopes": [
{
"id": 123,
"cost_rule_id": 123,
"scope_type": "PRODUCT",
"scope_value": "<string>",
"scope_operator": "EQUALS",
"scope_extra": {}
}
],
"conditions": [
{
"id": 123,
"cost_rule_id": 123,
"condition_type": "SUPPLIER",
"field_key": "<string>",
"operator": "IN",
"values": [
"<string>"
]
}
],
"tiers": [
{
"id": 123,
"cost_rule_id": 123,
"min_quantity": 123,
"max_quantity": 123,
"effects": [
{
"id": 123,
"cost_rule_id": 123,
"cost_rule_tier_id": 123,
"effect_type": "BASE_PRICE",
"amount": 123,
"order": 123,
"description": "<string>"
}
]
}
],
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}
}{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>",
"errors": {}
}Create a cost rule
Create a cost rule. Accepts the same snake_case body as the admin Cost Rules API. Requires the tenant Cost Rules feature flag.
On create, name and document_types (or singular document_type) are
required; vendor_id is required unless output_kind is EXTRA_COST or the
document type is PRODUCTION_RUN. For EXTRA_COST rules vendor_id must
not be set (a 422 is returned if one is supplied) — scope to specific
suppliers with a SUPPLIER condition instead. When output_kind is
EXTRA_COST, cost_basis and cost_basis_amount become required.
curl --request POST \
--url https://{companyName}.api.joinluminous.com/external/api/v1/cost-rules \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"vendor_id": 42,
"name": "Material cost — SKU-ABC",
"document_types": [
"PURCHASE_ORDER"
],
"status": "ACTIVE",
"tiers": [
{
"min_quantity": "0",
"effects": [
{
"effect_type": "FIXED_PER_UNIT",
"amount": "12.50",
"sequence": 1,
"description": "Material cost"
}
]
}
],
"scopes": [
{
"scope_type": "PRODUCT",
"scope_value": "12345",
"scope_operator": "EQUALS"
}
]
}
'import requests
url = "https://{companyName}.api.joinluminous.com/external/api/v1/cost-rules"
payload = {
"vendor_id": 42,
"name": "Material cost — SKU-ABC",
"document_types": ["PURCHASE_ORDER"],
"status": "ACTIVE",
"tiers": [
{
"min_quantity": "0",
"effects": [
{
"effect_type": "FIXED_PER_UNIT",
"amount": "12.50",
"sequence": 1,
"description": "Material cost"
}
]
}
],
"scopes": [
{
"scope_type": "PRODUCT",
"scope_value": "12345",
"scope_operator": "EQUALS"
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
vendor_id: 42,
name: 'Material cost — SKU-ABC',
document_types: ['PURCHASE_ORDER'],
status: 'ACTIVE',
tiers: [
{
min_quantity: '0',
effects: [
{
effect_type: 'FIXED_PER_UNIT',
amount: '12.50',
sequence: 1,
description: 'Material cost'
}
]
}
],
scopes: [{scope_type: 'PRODUCT', scope_value: '12345', scope_operator: 'EQUALS'}]
})
};
fetch('https://{companyName}.api.joinluminous.com/external/api/v1/cost-rules', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://{companyName}.api.joinluminous.com/external/api/v1/cost-rules",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'vendor_id' => 42,
'name' => 'Material cost — SKU-ABC',
'document_types' => [
'PURCHASE_ORDER'
],
'status' => 'ACTIVE',
'tiers' => [
[
'min_quantity' => '0',
'effects' => [
[
'effect_type' => 'FIXED_PER_UNIT',
'amount' => '12.50',
'sequence' => 1,
'description' => 'Material cost'
]
]
]
],
'scopes' => [
[
'scope_type' => 'PRODUCT',
'scope_value' => '12345',
'scope_operator' => 'EQUALS'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://{companyName}.api.joinluminous.com/external/api/v1/cost-rules"
payload := strings.NewReader("{\n \"vendor_id\": 42,\n \"name\": \"Material cost — SKU-ABC\",\n \"document_types\": [\n \"PURCHASE_ORDER\"\n ],\n \"status\": \"ACTIVE\",\n \"tiers\": [\n {\n \"min_quantity\": \"0\",\n \"effects\": [\n {\n \"effect_type\": \"FIXED_PER_UNIT\",\n \"amount\": \"12.50\",\n \"sequence\": 1,\n \"description\": \"Material cost\"\n }\n ]\n }\n ],\n \"scopes\": [\n {\n \"scope_type\": \"PRODUCT\",\n \"scope_value\": \"12345\",\n \"scope_operator\": \"EQUALS\"\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://{companyName}.api.joinluminous.com/external/api/v1/cost-rules")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"vendor_id\": 42,\n \"name\": \"Material cost — SKU-ABC\",\n \"document_types\": [\n \"PURCHASE_ORDER\"\n ],\n \"status\": \"ACTIVE\",\n \"tiers\": [\n {\n \"min_quantity\": \"0\",\n \"effects\": [\n {\n \"effect_type\": \"FIXED_PER_UNIT\",\n \"amount\": \"12.50\",\n \"sequence\": 1,\n \"description\": \"Material cost\"\n }\n ]\n }\n ],\n \"scopes\": [\n {\n \"scope_type\": \"PRODUCT\",\n \"scope_value\": \"12345\",\n \"scope_operator\": \"EQUALS\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://{companyName}.api.joinluminous.com/external/api/v1/cost-rules")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"vendor_id\": 42,\n \"name\": \"Material cost — SKU-ABC\",\n \"document_types\": [\n \"PURCHASE_ORDER\"\n ],\n \"status\": \"ACTIVE\",\n \"tiers\": [\n {\n \"min_quantity\": \"0\",\n \"effects\": [\n {\n \"effect_type\": \"FIXED_PER_UNIT\",\n \"amount\": \"12.50\",\n \"sequence\": 1,\n \"description\": \"Material cost\"\n }\n ]\n }\n ],\n \"scopes\": [\n {\n \"scope_type\": \"PRODUCT\",\n \"scope_value\": \"12345\",\n \"scope_operator\": \"EQUALS\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": 123,
"vendor_id": 123,
"vendor_name": "<string>",
"name": "<string>",
"description": "<string>",
"document_type": "PURCHASE_ORDER",
"document_types": [
"PURCHASE_ORDER"
],
"tier_mode": "NON_GRADUATED",
"tier_quantity_basis": "LINE",
"priority": 123,
"status": "ACTIVE",
"is_active": true,
"effective_from": "2023-12-25",
"effective_to": "2023-12-25",
"moq": 123,
"order_multiple": 123,
"output_kind": "UNIT_COST",
"extra_cost_item_name": "<string>",
"cost_allocation_type": "UNIT_BASED_ALLOCATION",
"cost_basis": "PERCENTAGE",
"cost_basis_amount": 123,
"shipment_type": "<string>",
"options": {
"auto_apply": true,
"add_as_additional_fee": true
},
"scopes": [
{
"id": 123,
"cost_rule_id": 123,
"scope_type": "PRODUCT",
"scope_value": "<string>",
"scope_operator": "EQUALS",
"scope_extra": {}
}
],
"conditions": [
{
"id": 123,
"cost_rule_id": 123,
"condition_type": "SUPPLIER",
"field_key": "<string>",
"operator": "IN",
"values": [
"<string>"
]
}
],
"tiers": [
{
"id": 123,
"cost_rule_id": 123,
"min_quantity": 123,
"max_quantity": 123,
"effects": [
{
"id": 123,
"cost_rule_id": 123,
"cost_rule_tier_id": 123,
"effect_type": "BASE_PRICE",
"amount": 123,
"order": 123,
"description": "<string>"
}
]
}
],
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}
}{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>",
"errors": {}
}Authorizations
Authenticate using a bearer token. To create a token, navigate to /settings/api-tokens and click Create API Token.
Body
Rule name. Required on create. Must be unique per vendor among non-deleted rules.
255Supplier / factory ID. Required on create except when output_kind is
EXTRA_COST or when the rule's document type is PRODUCTION_RUN (the
production run carries its own vendor). For EXTRA_COST rules a vendor_id
must not be set — the request is rejected with 422 if one is supplied
(on both create and update); scope the rule to specific suppliers with a
SUPPLIER condition instead. Optional on update for other rule kinds.
1000Document types the rule applies to. Required on create (or provide singular document_type).
1PURCHASE_ORDER, WORK_ORDER, SHIPMENT, PRODUCTION_RUN Singular alternative to document_types (back-compat).
PURCHASE_ORDER, WORK_ORDER, SHIPMENT, PRODUCTION_RUN Defaults to NON_GRADUATED.
NON_GRADUATED, GRADUATED Which quantity the tier thresholds are matched against. Defaults to LINE.
PRODUCTION_RUN_TOTAL sums the planned quantity across all work orders in the
production run (only meaningful for PRODUCTION_RUN document rules).
LINE, SCOPE_GROUP, PRODUCTION_RUN_TOTAL Defaults to 100.
1 <= x <= 1000Defaults to ACTIVE on create.
ACTIVE, INACTIVE, DRAFT Must be on or after effective_from.
x >= 0x >= 0Defaults to UNIT_COST.
UNIT_COST, EXTRA_COST 255UNIT_BASED_ALLOCATION, VOLUME_BASED_ALLOCATION, WEIGHT_BASED_ALLOCATION, VALUE_BASED_ALLOCATION Required when output_kind is EXTRA_COST.
PERCENTAGE, FIXED Required when output_kind is EXTRA_COST.
x >= 030Show child attributes
Show child attributes
Product / category / tag / supplier-SKU scopes. Replaces existing scopes when provided.
Show child attributes
Show child attributes
Document-level applicability gates. Replaces existing conditions when provided.
Show child attributes
Show child attributes
Quantity tiers with their effects. Replaces existing tiers when provided.
Show child attributes
Show child attributes
Response
Cost rule created.
A cost rule — vendor-scoped tiered pricing or extra-cost rule applied to
purchase orders, work orders, and shipments. Nested scopes, conditions,
and tiers (with effects) are only present when the relation is loaded
(always on GET /cost-rules/{id}).
Show child attributes
Show child attributes