{
  "openapi": "3.1.0",
  "info": {
    "title": "Ospree Compliance API",
    "description": "Rule-engine evaluation of transactions against the business's configured compliance rules.",
    "version": "2.0.0"
  },
  "paths": {
    "/api/v2/engine/evaluate": {
      "post": {
        "tags": [
          "Rule Evaluation"
        ],
        "summary": "Evaluate Transaction",
        "operationId": "evaluate_transaction_api_v2_engine_evaluate_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RuleEvalRequest"
              },
              "examples": {
                "all_active_rules": {
                  "summary": "Evaluate every active rule",
                  "description": "An empty `rule_codes` list evaluates all of the business's active rules.",
                  "value": {
                    "transaction": {
                      "transaction_id": "txn-2026-08-31-000417",
                      "originator_address": "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy",
                      "originator_name": "Ada Tester",
                      "originator_account_reference_id": "acct-orig-1042",
                      "beneficiary_address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
                      "beneficiary_name": "Grace Receiver",
                      "beneficiary_account_reference_id": "acct-benf-2087",
                      "amount": 18500.0,
                      "currency": "AED",
                      "country_code": "AE",
                      "metadata": {
                        "channel": "web",
                        "product": "spot"
                      }
                    },
                    "rule_codes": []
                  }
                },
                "selected_rules": {
                  "summary": "Evaluate named rules only",
                  "description": "Restricts the run to the listed rule codes.",
                  "value": {
                    "transaction": {
                      "transaction_id": "txn-2026-08-31-000418",
                      "originator_address": "0xBfEAf79E60C23883c92F06f642073f5aD85459F2",
                      "beneficiary_address": "0x59b87fa89986c81baBD1d91ebBF109F8855c7DeF",
                      "amount": 250.75,
                      "currency": "USD",
                      "country_code": "US"
                    },
                    "rule_codes": [
                      "TransferThresholdByCountry"
                    ]
                  }
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Evaluation completed. Per-rule verdicts are in `data.results`, which carries one entry for every rule evaluated and one for every requested `rule_codes` entry that has no active configuration.",
            "content": {
              "application/json": {
                "schema": {},
                "examples": {
                  "all_rules_passed": {
                    "summary": "All rules passed",
                    "description": "No rule was breached; nothing is written to the audit trail.",
                    "value": {
                      "status": "success",
                      "data": {
                        "transaction_id": "txn-2026-08-31-000417",
                        "evaluated_at": "2026-08-31T09:14:22.418293",
                        "results": [
                          {
                            "rule_code": "TransferThresholdByCountry",
                            "status": "pass"
                          }
                        ]
                      }
                    }
                  },
                  "rule_breached": {
                    "summary": "A rule was breached",
                    "description": "The breach is persisted to `rule_audit_log` before any configured action runs, and the transaction JSON is stored with it.",
                    "value": {
                      "status": "success",
                      "data": {
                        "transaction_id": "txn-2026-08-31-000417",
                        "evaluated_at": "2026-08-31T09:14:22.418293",
                        "results": [
                          {
                            "rule_code": "TransferThresholdByCountry",
                            "status": "breach",
                            "message": "Transfer exceeds the AE reporting threshold: 18500.0 > 15000.0"
                          }
                        ]
                      }
                    }
                  },
                  "breach_with_failed_action": {
                    "summary": "Breach whose action could not be delivered",
                    "description": "`status` stays `breach` -- the verdict is unchanged and still matches the audit row. Only delivery failed, reported on `action_status`.",
                    "value": {
                      "status": "success",
                      "data": {
                        "transaction_id": "txn-2026-08-31-000417",
                        "evaluated_at": "2026-08-31T09:14:22.418293",
                        "results": [
                          {
                            "rule_code": "TransferThresholdByCountry",
                            "status": "breach",
                            "message": "Transfer exceeds the AE reporting threshold: 18500.0 > 15000.0",
                            "action_status": "ERROR",
                            "action_message": "Webhook delivery failed: connection timed out"
                          }
                        ]
                      }
                    }
                  },
                  "rule_not_configured": {
                    "summary": "A requested rule code is not configured",
                    "description": "A code listed in `rule_codes` that the business has no active configuration for did not run, and says so on its own entry rather than being left out of `results`. Nothing is written to the audit trail for it.",
                    "value": {
                      "status": "success",
                      "data": {
                        "transaction_id": "txn-2026-08-31-000417",
                        "evaluated_at": "2026-08-31T09:14:22.418293",
                        "results": [
                          {
                            "rule_code": "TransferThresholdByCountry",
                            "status": "pass"
                          },
                          {
                            "rule_code": "SanctionScreening",
                            "status": "error",
                            "message": "Rule is not configured for this business"
                          }
                        ]
                      }
                    }
                  },
                  "rule_errored": {
                    "summary": "A rule failed to evaluate (still HTTP 200)",
                    "description": "One rule raising does not abort the evaluation or fail the request. A caller that checks only the HTTP status will miss this entirely.",
                    "value": {
                      "status": "success",
                      "data": {
                        "transaction_id": "txn-2026-08-31-000417",
                        "evaluated_at": "2026-08-31T09:14:22.418293",
                        "results": [
                          {
                            "rule_code": "TransferThresholdByCountry",
                            "status": "pass"
                          },
                          {
                            "rule_code": "SanctionScreening",
                            "status": "error",
                            "message": "Handler 'SanctionHandler' not found"
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found"
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiFailResponse"
                },
                "examples": {
                  "missing_or_invalid_credential": {
                    "summary": "Missing or invalid credential",
                    "description": "No API key was supplied, or it failed verification.",
                    "value": {
                      "status": "fail",
                      "message": "Unauthorized"
                    }
                  },
                  "payment_required": {
                    "summary": "Business is not a paying customer",
                    "description": "The credential verified, but the billing gate rejected it. Note the status is 401, not 402 -- the shared guards raise UnauthorizedError.",
                    "value": {
                      "status": "fail",
                      "message": "Payment required"
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity - Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiFailResponse"
                },
                "example": {
                  "status": "fail",
                  "message": "Validation error",
                  "data": [
                    {
                      "loc": [
                        "body",
                        "transaction",
                        "amount"
                      ],
                      "msg": "Field required",
                      "type": "missing"
                    }
                  ]
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "status": "error",
                  "code": 500,
                  "message": "An internal server error occurred."
                }
              }
            }
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "ApiErrorResponse": {
        "properties": {
          "status": {
            "type": "string",
            "title": "Status",
            "default": "error"
          },
          "code": {
            "type": "integer",
            "title": "Code"
          },
          "message": {
            "type": "string",
            "title": "Message"
          },
          "data": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "title": "Data"
          }
        },
        "type": "object",
        "required": [
          "code",
          "message"
        ],
        "title": "ApiErrorResponse",
        "description": "*summary*: Api error response model"
      },
      "ApiFailResponse": {
        "properties": {
          "status": {
            "type": "string",
            "title": "Status",
            "default": "fail"
          },
          "message": {
            "type": "string",
            "title": "Message"
          },
          "data": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "title": "Data"
          }
        },
        "type": "object",
        "required": [
          "message"
        ],
        "title": "ApiFailResponse",
        "description": "*summary*: Api fail response model"
      },
      "RuleEvalRequest": {
        "properties": {
          "transaction": {
            "$ref": "#/components/schemas/TransactionRequest",
            "description": "Transaction details to evaluate against the rules"
          },
          "rule_codes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Rule Codes",
            "description": "List of rule codes to evaluate. An empty list evaluates all of the business's active rules. A listed code with no active configuration is reported in `data.results` with `status: \"error\"` rather than omitted."
          }
        },
        "type": "object",
        "required": [
          "transaction",
          "rule_codes"
        ],
        "title": "RuleEvalRequest"
      },
      "TransactionRequest": {
        "properties": {
          "transaction_id": {
            "type": "string",
            "minLength": 3,
            "title": "Transaction Id",
            "description": "Unique transaction identifier"
          },
          "originator_address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Originator Address",
            "description": "Wallet involved in the transaction"
          },
          "originator_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Originator Name",
            "description": "Sender identifier"
          },
          "originator_account_reference_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Originator Account Reference Id",
            "description": "Sender account identifier"
          },
          "beneficiary_address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Beneficiary Address",
            "description": "Recepient wallet involved in the transaction"
          },
          "beneficiary_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Beneficiary Name",
            "description": "Recipient identifier"
          },
          "beneficiary_account_reference_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Beneficiary Account Reference Id",
            "description": "Recepient account identifier"
          },
          "amount": {
            "type": "number",
            "exclusiveMinimum": 0.0,
            "title": "Amount",
            "description": "Amount transferred"
          },
          "currency": {
            "type": "string",
            "maxLength": 5,
            "minLength": 2,
            "title": "Currency",
            "description": "Currency code (e.g., AED, USD)"
          },
          "country_code": {
            "type": "string",
            "minLength": 2,
            "title": "Country Code",
            "description": "Country to verify the threshold (use ISO 3166-1 alpha-2 country code, e.g. AE for United Arab Emirates)."
          },
          "metadata": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Metadata",
            "description": "Additional transaction metadata"
          }
        },
        "type": "object",
        "required": [
          "transaction_id",
          "amount",
          "currency",
          "country_code"
        ],
        "title": "TransactionRequest"
      }
    },
    "securitySchemes": {
      "HTTPBearer": {
        "type": "http",
        "scheme": "bearer"
      }
    }
  },
  "tags": [
    {
      "name": "Rule Evaluation",
      "description": "Evaluate a transaction against the business's compliance rules."
    }
  ]
}
