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

# Custom formulas

> Create custom Locus scoring formulas with custom signal weights, compare formulas side-by-side, and apply them to portfolios for tailored territory analysis.

Custom formulas let you adjust the relative weight of each signal group in the Locus composite score. Instead of using a fixed [scoring profile](/locus/scoring-conventions#scoring-profiles), you define your own weighting — emphasizing the signals that matter most for your asset class and investment thesis.

Formulas are versioned and can be applied to [portfolios](/locus/api/portfolios). When a portfolio has an active formula, all location scores are computed with the formula weights instead of the default composite.

## How weights work

Each formula defines a weight for the eight Locus signal groups:

| Signal group         | Key                    | Default weight |
| -------------------- | ---------------------- | -------------- |
| Business vitality    | `business_vitality`    | 1.0            |
| Population momentum  | `population_momentum`  | 1.0            |
| Demographics         | `demographics`         | 1.0            |
| Economic strength    | `economic_strength`    | 1.0            |
| Development pipeline | `development_pipeline` | 1.0            |
| Accessibility        | `accessibility`        | 1.0            |
| Safety & environment | `safety_environment`   | 1.0            |
| Amenity demand       | `amenity_demand`       | 1.0            |

Weights are normalized so they sum to 1.0 before scoring. A weight of `2.0` on `business_vitality` with `1.0` on everything else means business vitality contributes roughly 22% of the final score instead of the default 12.5%.

## `GET` `/api/v1/locus/formulas`

<Note>Requires session authentication.</Note>

List all scoring formulas available to you. This includes system-provided formulas and your custom formulas.

**Parameters**

| Name          | Type   | Required | Description                                             |
| ------------- | ------ | -------- | ------------------------------------------------------- |
| `asset_class` | string |          | Filter by asset class (e.g. `qsr`, `retail`, `office`). |

**Response**

```json theme={null}
{
  "formulas": [
    {
      "id": "f_sys_qsr_v1",
      "name": "QSR Standard",
      "asset_class": "qsr",
      "version": 1,
      "is_system": true,
      "weights_json": {
        "business_vitality": 2.0,
        "population_momentum": 1.5,
        "demographics": 1.5,
        "economic_strength": 1.0,
        "development_pipeline": 0.5,
        "accessibility": 1.5,
        "safety_environment": 1.0,
        "amenity_demand": 1.0
      },
      "created_at": "2026-01-01T00:00:00Z",
      "updated_at": "2026-01-01T00:00:00Z"
    },
    {
      "id": "f_custom_abc",
      "name": "Drive-through optimized",
      "asset_class": "qsr",
      "version": 2,
      "is_system": false,
      "weights_json": {
        "business_vitality": 1.0,
        "population_momentum": 1.0,
        "demographics": 2.0,
        "economic_strength": 1.0,
        "development_pipeline": 0.5,
        "accessibility": 3.0,
        "safety_environment": 1.0,
        "amenity_demand": 0.5
      },
      "created_at": "2026-03-15T09:00:00Z",
      "updated_at": "2026-04-10T14:00:00Z"
    }
  ]
}
```

| Field          | Type    | Description                                                           |
| -------------- | ------- | --------------------------------------------------------------------- |
| `is_system`    | boolean | `true` for Locus-provided formulas, `false` for your custom formulas. |
| `weights_json` | object  | Signal group weights. Normalized to sum to 1.0 when applied.          |
| `version`      | int     | Formula version number.                                               |

**Example**

```bash theme={null}
curl https://axiomlocus.io/api/v1/locus/formulas?asset_class=qsr \
  -H "Authorization: Bearer YOUR_TOKEN"
```

## `POST` `/api/v1/locus/formulas`

<Note>Requires session authentication.</Note>

Create a custom scoring formula. If you omit `weights_json`, Locus uses the default weights for the specified asset class.

**Parameters**

| Name           | Type   | Required | Description                                                               |
| -------------- | ------ | -------- | ------------------------------------------------------------------------- |
| `name`         | string | ✓        | Formula name.                                                             |
| `asset_class`  | string | ✓        | Asset class this formula is designed for.                                 |
| `version`      | number |          | Version number (default 1).                                               |
| `weights_json` | object |          | Custom weights. Each key is a signal group, value is the relative weight. |

**Example**

```bash theme={null}
curl -X POST https://axiomlocus.io/api/v1/locus/formulas \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Drive-through optimized",
    "asset_class": "qsr",
    "weights_json": {
      "business_vitality": 1.0,
      "demographics": 2.0,
      "accessibility": 3.0,
      "amenity_demand": 0.5
    }
  }'
```

**Response** (HTTP 201)

```json theme={null}
{
  "formula": {
    "id": "f_custom_abc",
    "name": "Drive-through optimized",
    "asset_class": "qsr",
    "version": 1,
    "is_system": false,
    "weights_json": {
      "business_vitality": 1.0,
      "population_momentum": 1.0,
      "demographics": 2.0,
      "economic_strength": 1.0,
      "development_pipeline": 1.0,
      "accessibility": 3.0,
      "safety_environment": 1.0,
      "amenity_demand": 0.5
    },
    "created_at": "2026-04-20T12:00:00Z",
    "updated_at": "2026-04-20T12:00:00Z"
  }
}
```

<Note>
  Any signal group you omit from `weights_json` defaults to `1.0`. Weights are normalized before scoring so only the ratios between groups matter, not the absolute values.
</Note>

***

## Compare formulas

### `GET` `/api/v1/locus/formulas/compare`

<Note>Requires session authentication.</Note>

Score a single H3 cell with multiple formulas side-by-side. Use this to see how different weightings affect the composite score for a specific location before applying a formula to your portfolio.

**Parameters**

| Name          | Type   | Required | Description                             |
| ------------- | ------ | -------- | --------------------------------------- |
| `h3_index`    | string | ✓        | H3 cell id to score.                    |
| `profile`     | string |          | Scoring profile (default `general`).    |
| `formula_ids` | string | ✓        | Comma-separated formula ids to compare. |

**Response**

```json theme={null}
{
  "h3_index": "882a100d63fffff",
  "profile": "general",
  "base_composite": 72.0,
  "comparisons": [
    {
      "formula_id": "f_sys_qsr_v1",
      "name": "QSR Standard",
      "asset_class": "qsr",
      "version": 1,
      "is_system": true,
      "score": 76.3,
      "delta_from_base": 4.3
    },
    {
      "formula_id": "f_custom_abc",
      "name": "Drive-through optimized",
      "asset_class": "qsr",
      "version": 2,
      "is_system": false,
      "score": 79.1,
      "delta_from_base": 7.1
    }
  ]
}
```

| Field                           | Type  | Description                                                                                    |
| ------------------------------- | ----- | ---------------------------------------------------------------------------------------------- |
| `base_composite`                | float | Default composite score without any formula.                                                   |
| `comparisons[].score`           | float | Composite score using this formula's weights.                                                  |
| `comparisons[].delta_from_base` | float | Difference from the default composite. Positive means the formula scores this location higher. |

**Example**

```bash theme={null}
curl "https://axiomlocus.io/api/v1/locus/formulas/compare?h3_index=882a100d63fffff&formula_ids=f_sys_qsr_v1,f_custom_abc" \
  -H "Authorization: Bearer YOUR_TOKEN"
```
