> For the complete documentation index, see [llms.txt](https://midatechnologies.gitbook.io/mida-developer-portal/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://midatechnologies.gitbook.io/mida-developer-portal/midaforms/external-decisioning.md).

# External decisioning

External decisioning API reference

Base path: `/external-decisioning`

Tag: External Decisioning

Persists to `ExternalDecisioningResult`.

Runtime scoring uses the matrix’s `authoringMode` (`FREE_TEXT` vs `CATALOG`) automatically.

### 6.1 Evaluate

```
POST /external-decisioning/evaluate
```

**Behaviour**

1. If `referenceId` already exists for `orgKey` → return stored result (idempotent; no re-score).
2. Else create `PENDING` row → load active matrix for org → fetch bank statement from Midax via `accountId` → score → store `COMPLETED` (or `FAILED` + rethrow).

**Request body** (`EvaluateExternalDecisioningDto`)

| Field              | Type                        | Required | Notes                                      |
| ------------------ | --------------------------- | -------- | ------------------------------------------ |
| `orgKey`           | string (2–120)              | Yes      | Organisation id / key                      |
| `decisionMatrixId` | UUID                        | Yes      | Must belong to org and be `isActive: true` |
| `applicationType`  | `INDIVIDUAL` \| `CORPORATE` | Yes      |                                            |
| `applicationData`  | object                      | Yes      | Must include `loan.amount > 0`             |
| `creditBureauData` | object                      | No       | Bureau reports / profile used by scorers   |
| `bankStatement`    | object                      | Yes      | `{ "accountId": "…" }`                     |
| `referenceId`      | string (max 120)            | No       | Unique per organisation when set           |

```json
{
  "orgKey": "acme",
  "decisionMatrixId": "ea040abd-8084-4bab-8bbb-c9d091710149",
  "applicationType": "INDIVIDUAL",
  "referenceId": "ACME-LOAN-998877",
  "applicationData": {
    "loan": {
      "amount": 500000,
      "tenure": 12
    },
    "dob": "1992-04-12",
    "gender": "female",
    "phone": "08012345678",
    "email": "jane@example.com",
    "homeAddress": {
      "street": "12 Admiralty Way",
      "lga": "Eti-Osa",
      "state": "Lagos"
    },
    "monthlyIncome": 350000,
    "employmentStatus": "Salaried",
    "creditBureau": {
      "gender": "female",
      "maritalStatus": "single",
      "bvn": "22222222222",
      "dob": "1992-04-12"
    }
  },
  "creditBureauData": {
    "summary": {
      "successful": 2,
      "totalBureaus": 3
    },
    "reports": []
  },
  "bankStatement": {
    "accountId": "mono-account-id-123"
  }
}
```

**applicationData notes**

* Required: `loan.amount` (number > 0).
* You may send either:
  * Flat / nested fields (auto-normalized into internal responses), or
  * Internal-shaped `{ "responses": [ { "fields": [ { "name", "value", "type" } ] } ] }`.
* Optional nested `creditBureau` on application data is merged with top-level `creditBureauData`.

**Response data**

```json
{
  "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "organisationId": "acme",
  "decisionMatrixId": "ea040abd-8084-4bab-8bbb-c9d091710149",
  "referenceId": "ACME-LOAN-998877",
  "applicationType": "INDIVIDUAL",
  "status": "COMPLETED",
  "score": 78,
  "decision": "APPROVE",
  "label": "PRIME",
  "amountApproved": "100",
  "tenureApproved": 12,
  "action": "AUTO_DISBURSE",
  "breakdown": [
    {
      "parentVariable": "Income",
      "weight": 25,
      "score": 8,
      "maxScore": 10,
      "weightedContribution": 20,
      "performance": "Strong",
      "details": {},
      "subVariables": []
    }
  ],
  "decisionRule": {
    "label": "PRIME",
    "minScore": 70,
    "maxScore": 100,
    "decision": "APPROVE",
    "amountApproved": 100,
    "tenureApproved": 12,
    "action": "AUTO_DISBURSE"
  },
  "bankStatementRef": {
    "accountId": "mono-account-id-123"
  },
  "errorMessage": null,
  "createdAt": "2026-09-03T13:00:00.000Z",
  "updatedAt": "2026-09-03T13:00:02.000Z"
}
```

`amountApproved` is the percentage of requested loan amount from the matched decision band (stored as string).

### 6.2 List results

```
GET /external-decisioning
```

**Query** (`ListExternalDecisioningQueryDto`)

| Param              | Type       | Required | Notes                                |
| ------------------ | ---------- | -------- | ------------------------------------ |
| `orgKey`           | string     | Yes      |                                      |
| `decisionMatrixId` | UUID       | No       |                                      |
| `status`           | enum       | No       | `PENDING` \| `COMPLETED` \| `FAILED` |
| `referenceId`      | string     | No       |                                      |
| `minScore`         | number ≥ 0 | No       | Inclusive                            |
| `maxScore`         | number ≥ 0 | No       | Inclusive                            |
| `page`             | number ≥ 1 | No       | Default 1                            |
| `limit`            | number ≥ 1 | No       | Default 20                           |

```
GET /external-decisioning?orgKey=acme&decisionMatrixId=ea040abd-8084-4bab-8bbb-c9d091710149&status=COMPLETED&minScore=50&maxScore=100&page=1&limit=20
```

**Response data**

```json
{
  "data": [
    {
      "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
      "organisationId": "acme",
      "decisionMatrixId": "ea040abd-8084-4bab-8bbb-c9d091710149",
      "referenceId": "ACME-LOAN-998877",
      "applicationType": "INDIVIDUAL",
      "status": "COMPLETED",
      "score": 78,
      "decision": "APPROVE",
      "label": "PRIME",
      "amountApproved": "100",
      "tenureApproved": 12,
      "action": "AUTO_DISBURSE",
      "breakdown": [],
      "decisionRule": {},
      "bankStatementRef": { "accountId": "mono-account-id-123" },
      "errorMessage": null,
      "createdAt": "2026-09-03T13:00:00.000Z",
      "updatedAt": "2026-09-03T13:00:02.000Z"
    }
  ],
  "pagination": {
    "total": 1,
    "page": 1,
    "limit": 20,
    "totalPages": 1
  }
}
```

### 6.3 Get by id

```
GET /external-decisioning/:id
```

`:id` = `ExternalDecisioningResult` UUID.

Response data is the same object as a single evaluate result (§6.1).

### 6.4 Rerun

```
POST /external-decisioning/:id/rerun
```

Reuses stored `applicationData`, `creditBureauData`, and `bankStatementRef.accountId`. Re-scores against the current active matrix definition (useful after matrix updates).

No request body.

Response data is the same shape as evaluate.
