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

# Decisions

> How Specter evaluates decision requests.

A **decision** is the result of evaluating a transaction against an active ruleset. Request one with
`POST /api/decisions`: Specter returns an outcome and logs the decision for later retrieval and reporting.

## Outcomes

Every decision resolves to one of four outcomes.

| Outcome       | Meaning                                                                                          |
| ------------- | ------------------------------------------------------------------------------------------------ |
| `ALLOW`       | No blocking rule matched — the default when nothing fires.                                       |
| `REVIEW`      | A rule flagged the transaction for manual review. `REVIEW` outcomes **accumulate** across rules. |
| `BLOCK`       | A blocking rule matched. Evaluation **short-circuits** on the first `BLOCK`.                     |
| `PROVISIONAL` | An interim outcome while an asynchronous evaluation is still pending.                            |

Specter is designed to **fail open**: if a backend errors or times out and the rule's `on_error` is `allow`,
Specter skips that backend rather than blocking the customer. See the [rule engine](/products/specter/concepts/rule-engine).

## The decision request

Three attributes are always required; everything else is optional but enriches the evaluation.

<ParamField body="credential" type="object" required>
  Card credential — `type: "pan"`, `"masked_pan"`, or `"sepa"`. A `pan` credential is only accepted on an
  `SAQ_D` or `ROC` instance; on the default `SAQ_A` level it is rejected — see
  [Instance configuration](/products/specter/plans-and-access#pci-level).
</ParamField>

<ParamField body="customer" type="object" required>
  Must contain `id`.
</ParamField>

<ParamField body="transaction" type="object" required>
  Must contain `reference`, `amount` (minor units), and `currency` (ISO 4217).
</ParamField>

<ParamField body="device" type="object">
  IP address, fingerprint, user agent, session, and language.
</ParamField>

<ParamField body="billing" type="object">
  Addresses forwarded to applicable backends.
</ParamField>

<ParamField body="shipping" type="object">
  Addresses forwarded to applicable backends.
</ParamField>

<ParamField body="items" type="array">
  Cart line items; each needs at least `name` or `sku`.
</ParamField>

<ParamField body="airline" type="object">
  Travel data (passengers, legs) forwarded to backends that consume it.
</ParamField>

<ParamField body="metadata" type="object">
  Flat string key-value pairs, available to rules as `$.metadata.*`. Forwarded to
  backends and stored on the decision record, so treat it as data you share with
  your backend providers.
</ParamField>

<ParamField body="context" type="string" default="default">
  Selects which ruleset to evaluate.
</ParamField>

See [API integration](/products/specter/integration/via-api) for the full schema.

## The decision response

```json theme={null}
{
  "id": "dec_01J...",
  "decision": "REVIEW",
  "context": "checkout",
  "credential_fingerprint": "crd_4ba218...",
  "credential_type": "pan",
  "triggered_rules": [
    { "id": "ravelin-assessment", "type": "backend", "action": "REVIEW" }
  ],
  "backend_results": [
    {
      "backend": "link-prod/ravelin",
      "decision": "REVIEW",
      "raw_response": { "...": "..." }
    }
  ]
}
```

<ResponseField name="decision" type="string">
  The outcome.
</ResponseField>

<ResponseField name="triggered_rules" type="array">
  Rules that fired, in evaluation order.
</ResponseField>

<ResponseField name="backend_results" type="array">
  One entry per executed backend rule, including any error such as
  `insufficient_context`. Present when the ruleset includes backend rules.
</ResponseField>

<ResponseField name="credential_fingerprint" type="string">
  `HMAC-SHA256` identifier for the card instrument.
</ResponseField>

## The decision log

Every decision is written to the log. When a PAN is sent, only its fingerprint is returned. Retrieve a past decision with [`GET /api/decisions/{id}`](/products/specter/api-reference/decisions/get-decision-details).

## Resolving a REVIEW decision

A `REVIEW` decision is not final — it asks for a human judgement. Once your team has reviewed the transaction,
**resolve** it to record the accept/reject outcome and forward it to the backends that flagged it:

```
POST /api/decisions/{id}/resolve
```

Requires the `decisions:write` scope.

* Only decisions with `decision: "REVIEW"` can be resolved — others return `422`.
* Each decision can be resolved **once** — a second attempt returns `409`.

### Request

<ParamField body="action" type="string" required>
  `accept` or `reject`.
</ParamField>

<ParamField body="reason" type="string">
  Free-text note stored on the resolution.
</ParamField>

```json theme={null}
{
  "action": "accept",
  "reason": "manual review passed"
}
```

### Response

```json theme={null}
{
  "decision_id": "dec_01J...",
  "original_decision": "REVIEW",
  "resolution": "ACCEPTED",
  "resolved_at": "2026-03-17T12:00:00Z",
  "backend_notifications": [
    { "backend": "link-prod/vdm", "status": "ok" },
    { "backend": "link-prod/ravelin", "status": "skipped" }
  ]
}
```

The `resolution` is stored on the decision and returned by subsequent `GET /api/decisions/{id}` calls. Only
backends that produced a `REVIEW` result participate; Specter forwards the outcome to each through its
[Link integration](/products/specter/concepts/backends), and a backend that does not support resolution is
skipped.

| Status                  | Meaning                                                    |
| ----------------------- | ---------------------------------------------------------- |
| `ok`                    | The backend accepted the resolution.                       |
| `skipped`               | The backend does not support resolution.                   |
| `reference_unavailable` | The backend's stored response lacked a required reference. |

## Related

<CardGroup cols={2}>
  <Card title="Rule engine" icon="sliders" href="/products/specter/concepts/rule-engine">
    How rules combine to produce an outcome.
  </Card>

  <Card title="Lifecycle events" icon="arrows-spin" href="/products/specter/concepts/lifecycle-events">
    Feed transaction outcomes back to Specter and its backends.
  </Card>
</CardGroup>
