> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gorules.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Create your first rule

> Build and test a discount pricing rule in 5 minutes using the GoRules visual editor.

export const SdkOverview = () => {
  const sdks = [{
    name: 'Node.js',
    href: '/developers/sdks/nodejs',
    icon: 'node-js',
    color: '#68a063'
  }, {
    name: 'Python',
    href: '/developers/sdks/python',
    icon: 'python',
    color: '#3776ab'
  }, {
    name: 'Go',
    href: '/developers/sdks/go',
    icon: 'golang',
    color: '#00add8'
  }, {
    name: 'Rust',
    href: '/developers/sdks/rust',
    icon: 'rust',
    color: '#ce422b'
  }, {
    name: 'Java',
    href: '/developers/sdks/java',
    icon: 'java',
    color: '#e76f00'
  }, {
    name: 'Kotlin',
    href: '/developers/sdks/kotlin',
    icon: '/images/kotlin.svg',
    color: '#7f52ff'
  }, {
    name: 'C#',
    href: '/developers/sdks/csharp',
    icon: '/images/dotnet.svg',
    color: '#512bd4'
  }, {
    name: 'Swift',
    href: '/developers/sdks/swift',
    icon: 'swift',
    color: '#f05138'
  }, {
    name: 'WASM',
    href: '/developers/sdks/wasm',
    icon: '/images/wasm.svg',
    color: '#654ff0'
  }];
  return <div style={{
    display: 'grid',
    gridTemplateColumns: 'repeat(4, 1fr)',
    gap: '12px',
    margin: '16px 0'
  }}>
      {sdks.map(sdk => <a key={sdk.name} href={sdk.href} style={{
    display: 'flex',
    alignItems: 'center',
    gap: '10px',
    padding: '14px 16px',
    borderRadius: '8px',
    backgroundColor: '#f8fafc',
    border: '1px solid #e2e8f0',
    textDecoration: 'none'
  }}>
          <Icon icon={sdk.icon} size={18} color={sdk.color} className="my-0" />
          <span style={{
    fontSize: '14px',
    fontWeight: 500,
    color: '#1e293b'
  }}>
            {sdk.name}
          </span>
        </a>)}
    </div>;
};

export const DecisionTableViz = ({inputs = [], outputs = [], rows = []}) => {
  const colCount = inputs.length + outputs.length;
  const getFieldDisplay = field => !field || field === '-' ? '-' : field;
  const allCells = rows.flatMap((row, ri) => [...inputs.map((input, i) => <div key={`c-${ri}-in-${i}`} style={{
    backgroundColor: '#ffffff',
    padding: '12px 16px',
    borderRadius: '8px',
    fontFamily: 'ui-monospace, monospace',
    fontSize: '14px',
    border: '1px solid #e2e8f0'
  }}>
        {row[input.field] ?? ''}
      </div>), ...outputs.map((output, i) => <div key={`c-${ri}-out-${i}`} style={{
    backgroundColor: '#ffffff',
    padding: '12px 16px',
    borderRadius: '8px',
    fontFamily: 'ui-monospace, monospace',
    fontSize: '14px',
    border: '1px solid #e2e8f0'
  }}>
        {row[output.field] ?? ''}
      </div>)]);
  return <div style={{
    backgroundColor: '#f1f5f9',
    borderRadius: '12px',
    padding: '20px',
    overflowX: 'auto',
    margin: '16px 0'
  }}>
      <div style={{
    display: 'grid',
    gridTemplateColumns: `repeat(${colCount}, 1fr)`,
    gap: '8px'
  }}>
        {}
        <div key="group-inputs" style={{
    gridColumn: `span ${inputs.length}`,
    padding: '8px 16px',
    fontWeight: '600',
    fontSize: '13px',
    color: '#374151',
    borderBottom: '2px solid #e2e8f0'
  }}>
          Inputs
        </div>
        <div key="group-outputs" style={{
    gridColumn: `span ${outputs.length}`,
    padding: '8px 16px',
    fontWeight: '600',
    fontSize: '13px',
    color: '#374151',
    borderBottom: '2px solid #e2e8f0'
  }}>
          Outputs
        </div>

        {}
        {inputs.map((input, i) => <div key={`h-in-${i}`} style={{
    backgroundColor: '#f0abfc',
    color: '#581c87',
    padding: '12px 16px',
    borderRadius: '8px',
    fontWeight: '500'
  }}>
            <div>{input.name}</div>
            <div style={{
    display: 'inline-block',
    marginTop: '6px',
    padding: '2px 8px',
    fontSize: '12px',
    fontWeight: '400',
    backgroundColor: 'rgba(88, 28, 135, 0.15)',
    borderRadius: '4px',
    fontFamily: 'ui-monospace, monospace'
  }}>
              {getFieldDisplay(input.field)}
            </div>
          </div>)}
        {outputs.map((output, i) => <div key={`h-out-${i}`} style={{
    backgroundColor: '#a5b4fc',
    color: '#312e81',
    padding: '12px 16px',
    borderRadius: '8px',
    fontWeight: '500'
  }}>
            <div>{output.name}</div>
            <div style={{
    display: 'inline-block',
    marginTop: '6px',
    padding: '2px 8px',
    fontSize: '12px',
    fontWeight: '400',
    backgroundColor: 'rgba(49, 46, 129, 0.15)',
    borderRadius: '4px',
    fontFamily: 'ui-monospace, monospace'
  }}>
              {getFieldDisplay(output.field)}
            </div>
          </div>)}

        {}
        {allCells}
      </div>
    </div>;
};

In this quickstart, you'll create a decision that calculates customer discounts based on order value and membership tier.

## What you'll build

A pricing rule that:

* Gives Gold members 15% off orders over \$100
* Gives Silver members 10% off orders over \$100
* Gives all customers 5% off orders over \$200
* Returns the best applicable discount

## Step 1: Create a new decision

<Tabs>
  <Tab title="BRMS (Web UI)">
    1. Open your GoRules BRMS instance
    2. Navigate to your project (or create one)
    3. Click on **Open Editor**
    4. Click **New** and select **File**
    5. Name it "Customer Discount" and press Enter

    The visual editor opens with an empty canvas.
  </Tab>

  <Tab title="Playground">
    1. Open the [GoRules Playground](https://editor.gorules.io)
    2. You'll see an empty canvas

    No account needed — the playground runs entirely in your browser.
  </Tab>
</Tabs>

## Step 2: Add an input node

1. From the node palette, drag an **Input** node onto the canvas
2. This is where your data enters the decision

## Step 3: Add a decision table

1. Drag a **Decision Table** onto the canvas
2. Position it to the right of the Input node
3. Connect the Input node to the Decision Table by dragging from the Input's output handle to the Decision Table's input handle

Your graph now looks like: `Input → Decision Table`

## Step 4: Define input columns

Click **Edit table** to open the editor. Add two input columns:

1. Click **Add input**.
2. Set the field to `customer.tier` and label it "Customer Tier"
3. Click **Add input** again
4. Set the field to `order.subtotal` and label it "Order Subtotal"

## Step 5: Define output columns

Add one output column:

1. Click **Add output**
2. Set the field to `discount` and label it "Discount"

## Step 6: Add your rules

Add rows to define the discount logic. For each row, enter the conditions and outcome:

<DecisionTableViz
  inputs={[
{ name: "Customer Tier", field: "customer.tier" },
{ name: "Order Subtotal", field: "order.subtotal" }
]}
  outputs={[
{ name: "Discount", field: "discount" }
]}
  rows={[
{ "customer.tier": '"gold"', "order.subtotal": ">= 100", discount: "0.15" },
{ "customer.tier": '"silver"', "order.subtotal": ">= 100", discount: "0.10" },
{ "customer.tier": "", "order.subtotal": ">= 200", discount: "0.05" },
{ "customer.tier": "", "order.subtotal": "", discount: "0" }
]}
/>

<Tip>
  Leave a cell empty to match any value. The last row acts as a default that catches all other cases.
</Tip>

## Step 7: Test your rule

Click **Open Simulator** in the toolbar. Create a test event and enter:

```json theme={null}
{
  "customer": {
    "tier": "gold"
  },
  "order": {
    "subtotal": 150
  }
}
```

Click **Run**. You should see:

```json theme={null}
{
  "discount": 0.15
}
```

Try different inputs to verify your logic:

| Test case                  | Expected discount |
| -------------------------- | ----------------- |
| Gold member, \$150 order   | 0.15              |
| Silver member, \$150 order | 0.10              |
| Bronze member, \$250 order | 0.05              |
| Bronze member, \$50 order  | 0                 |

## Step 8: Integrate with your application

Now that your rule works, integrate it into your application.

<Tabs>
  <Tab title="BRMS (REST API)">
    <Note>The local changes must be committed to `main` branch before evaluation is possible.</Note>

    Call your decision via HTTP from the BRMS:

    ```javascript Node.js theme={null}
    const response = await fetch(
      'https://[your-brms-url]/api/projects/{projectId}/evaluate/{documentPath}',
      {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'X-Access-Token': '[your-project-token]'
        },
        body: JSON.stringify({
          context: {
            customer: { tier: 'gold' },
            order: { subtotal: 150 }
          }
        })
      }
    );

    const data = await response.json();
    console.log(data.result);
    // => { discount: 0.15 }
    ```

    Replace `{projectId}` with your project ID and `{documentPath}` with the decision path (e.g., `customer-discount`).
  </Tab>

  <Tab title="SDK (Embedded)">
    Run rules locally by embedding the ZEN Engine. Export your decision from the BRMS or save it from the playground, then load it with any SDK:

    <SdkOverview />
  </Tab>
</Tabs>
