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

# Warnings

> Non-fatal diagnostics that never change an amount

Every calculation response carries a `warnings` array. It is the channel through which the
engine says *"what you sent me does not line up with what I can see"* — without deciding
on your behalf.

<Tip>
  **A warning never changes an amount.** Every figure in the response already reflects the
  request exactly as you sent it.
</Tip>

That is what separates this channel from validation. A warning reports that an input
contradicts something the engine can check for itself, and leaves the decision to you —
because you may hold information this API never receives.

## The field

`warnings` is **always present and never `null`**. It is an empty list when there is
nothing to flag, so you can iterate it without branching.

It appears on the `/calculate` response and inside every
`results[].calculation` of a `/batch` response.

```json theme={null}
{
  "warnings": [
    {
      "code": "FLAG_THRESHOLD_MISMATCH",
      "field": "overrides.aplica_auxilio_transporte",
      "message": "aplica_auxilio_transporte=true pero el salario basico (8,754,525) supera el umbral legal de 2 SMMLV (3,501,810). El auxilio se pago igual, por decision del integrador.",
      "severity": "warning"
    }
  ]
}
```

| Field      | Description                                                                 |
| ---------- | --------------------------------------------------------------------------- |
| `code`     | Stable code. Branch on this, not on the message text                        |
| `field`    | Dotted path of the request field the warning is about                       |
| `message`  | Human-readable explanation, quoting the values compared and the legal basis |
| `severity` | Always `warning` in v1                                                      |

`severity` exists from the start so that richer severities will not break the contract
later.

## Warning codes

| Code                      | What it means                                                                                                                                        |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `FLAG_THRESHOLD_MISMATCH` | A boolean flag contradicts the salary threshold of the benefit it enables. The calculation honoured the flag anyway                                  |
| `PERIOD_DAYS_IGNORED`     | `period.days` played no part in a `split_monthly` settlement — the factor came from `period.type`. The amounts are half a monthly salary             |
| `SALARY_FIELDS_DISAGREE`  | Both `daily_salary` and `monthly_salary` arrived and they contradict each other. The daily figure was used, being the legal base unit                |
| `EVENT_PAYMENT_SPLIT`     | The period split a concept whose payment the law fixes to a **date**, not to a stretch of the month — Brazil's 13th and ferias, Peru's gratificacion |

The last three came in with [fortnightly settlement](/guides/pay-periods).

## Threshold rules (CO ordinario)

Two Colombian flags are checked against the salary that gates them:

| Flag                        | Threshold                | Basis         |
| --------------------------- | ------------------------ | ------------- |
| `aplica_auxilio_transporte` | `<= 2 SMMLV` (inclusive) | Ley 15/1959   |
| `aplica_exoneracion_114_1`  | `< 10 SMMLV` (exclusive) | ET Art. 114-1 |

Both are measured on `salario_basico`, **not** on total earnings. That is a debatable
reading, so **every message states exactly what it compared**: a payroll officer who
disagrees can see the criterion instead of guessing it.

What the silence used to cost, measured in CO 2026:

* **Auxilio paid where it was not due**, at 5 SMMLV: `249,095` per month of overpayment per
  employee, plus an inflated cesantias base.
* **Exoneration claimed where it was not due**, at 15 SMMLV: `3,545,583` per month the
  employer believes it does not owe. Over twelve months, more than 42 million of exposure
  with the UGPP and the DIAN.

### Why one flag warns in both directions and the other does not

`aplica_exoneracion_114_1` **does not warn when it is off**, and that is deliberate.

The exoneration also requires the employer to be a corporate income tax filer — an
attribute of the company that never arrives in a request. Warning on the off case would
fire on almost every legitimate ordinary request, and **that is how you train an integrator
to ignore the entire channel**.

The auxilio warns in both directions, because there the engine has all the information it
needs.

The same reasoning applies in Peru: of the two concepts paid alongside the gratificacion,
only one is registered. Two warnings for one problem is the same mistake.

## Handling warnings in code

<CodeGroup>
  ```python Python theme={null}
  import httpx

  result = httpx.post(
      "https://api.clevis.dev/v1/payroll/calculate",
      headers={"Authorization": "Bearer YOUR_API_KEY"},
      json=payload,
  ).json()

  for warning in result["warnings"]:
      log.warning(
          "payroll warning %s on %s: %s",
          warning["code"], warning["field"], warning["message"],
      )
  ```

  ```javascript Node.js theme={null}
  const result = await fetch("https://api.clevis.dev/v1/payroll/calculate", {
    method: "POST",
    headers: {
      Authorization: "Bearer YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify(payload),
  }).then((r) => r.json());

  for (const warning of result.warnings) {
    console.warn(`${warning.code} on ${warning.field}: ${warning.message}`);
  }
  ```
</CodeGroup>

Surface warnings to whoever reviews the payroll before it is released. They are cheapest to
act on there.

## What warnings are not

<Warning>
  **Not a legal validation.** Clevis does not say whether the employer is entitled to a
  benefit. It says the flag and the salary do not agree.

  **Not a complete list of what could be wrong.** Registered rules exist only for CO
  `ordinario` and for the four codes above. There is no general coverage to promise.

  **Not a rejection.** Nothing is refused — not even the case that hurts most legally, an
  auxilio omitted for someone entitled to it.
</Warning>
