Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Reframe - A Universal Transformation Engine

Reframe is a high-performance, open-source rules engine for transforming any message format. Convert between SWIFT MT, ISO 20022, or custom formats using auditable JSONLogic rules.

Try the Interactive Playground →


Universal Transformation Engine

Reframe transforms any message format using auditable rules:

  • SWIFT MT ↔ ISO 20022: Free CBPR+ package included
  • Custom formats: Any format with JSONLogic transformation rules
# Quick start with Docker
docker pull plasmatic/reframe:latest
docker run -p 3000:3000 plasmatic/reframe:latest

Architecture

Reframe separates the transformation engine from business rules via packages. The engine handles parsing, rule evaluation, and validation - while packages contain the actual transformation logic.

Learn About the Architecture →


Why Choose Reframe?

Open Source Rules Engine

All transformation rules are externalized in auditable JSONLogic files. Inspect, modify, and extend any mapping logic. Apache 2.0 licensed.

High Performance

Built in Rust with sub-millisecond transformation latency. Process thousands of messages per second.

Standards Agnostic

Load the SWIFT CBPR+ package or create your own for proprietary formats.

Enterprise Ready

Hot-reload, GraphQL API, custom fields, and full audit trails. Deploy as a single Docker container.


Free, SR2025-compliant transformation package with 41+ scenarios:

CategoryTransformations
Customer PaymentsMT103 ↔ pacs.008
FI TransfersMT202 ↔ pacs.009
StatementsMT940 ↔ camt.053

View Complete Message Catalog →


Powered By Open Source

Reframe is built on a foundation of specialized open-source libraries:

LibraryPurposeLinks
DatalogicJSONLogic rule evaluationDocs · GitHub
DataflowWorkflow orchestrationDocs · GitHub
DatafakeTest data generationDocs · GitHub

Each library has its own interactive playground for testing and learning.


Quick Comparison

FeatureReframe (Open Source)Proprietary Solutions
LicenseApache 2.0 (Free)Expensive licensing
RulesAuditable JSONLogicBlack-box logic
StandardsUniversal (packages)Limited scope
PerformanceSub-millisecond (Rust)Slower (JVM)
UpdatesHot-reload rulesVendor intervention

Get Started

Try the Playground - Test transformations instantly

Quick Start Guide - Run Reframe in 5 minutes

CBPR+ Package Guide - Explore ISO 20022 transformations


Resources


Built by Plasmatic - Making message transformation transparent, fast, and reliable.

Interactive Playground

Test Reframe transformations, validation, and sample generation directly in your browser.

Full Playground

The complete playground with all features:

Features

Generate Tab

Create sample SWIFT MT or ISO 20022 messages for testing.

Validate Tab

Validate any message and see detailed error reports.

Transform Tab

Convert messages between MT and ISO 20022 formats.

Configuration

API URL

By default, the playground connects to https://reframeapi.goplasmatic.io. To use a local instance:

  1. Click the Settings icon in the playground
  2. Enter your local API URL (e.g., http://localhost:3000)
  3. Click Save

Your preference is stored in browser local storage.

Running Locally

Start Reframe locally:

docker run -p 3000:3000 plasmatic/reframe:latest

Then configure the playground to use http://localhost:3000.

Individual Widgets

For focused testing, use the individual playground pages:

Keyboard Shortcuts

ShortcutAction
Ctrl/Cmd + EnterExecute current operation
Ctrl/Cmd + LClear output
Ctrl/Cmd + KCopy output to clipboard

Tips

Testing Transformations

  1. Generate a sample message
  2. Copy the output
  3. Switch to Transform tab
  4. Paste and transform
  5. Validate the result

Debugging Issues

Enable Debug Mode in the transformer to see:

  • Each workflow that executed
  • Intermediate values
  • Field mapping results

API Integration

Each operation shows the API Request & Response panel. Use this to:

  • Copy curl commands for your scripts
  • See exact request format
  • Debug API integration issues

Generator Playground →

Validator Playground →

Transformer Playground →

The Open Source Advantage

Why financial institutions are choosing open source for ISO 20022 transformation.

The Challenge with Proprietary Solutions

Traditional SWIFT MT to ISO 20022 transformation solutions share common limitations:

  • Black-box logic: Transformation rules hidden in compiled code
  • Vendor lock-in: Difficult to switch providers or customize behavior
  • Expensive licensing: Per-message fees or costly annual licenses
  • Slow updates: Waiting for vendors to support new standards
  • Limited auditability: Cannot verify transformation correctness

How Reframe is Different

100% Transparent Rules

Every transformation rule in Reframe is defined in human-readable JSON:

{
  "path": "data.output.CdtTrfTxInf.PmtId.InstrId",
  "logic": {"var": "data.SwiftMT.fields.20.transaction_reference"}
}

You can inspect, audit, and modify any rule. No hidden logic, no surprises.

Full Auditability

For regulated financial institutions, auditability is essential:

  • Complete rule visibility: Review every field mapping and business rule
  • Version control: Track changes to transformation rules in Git
  • Compliance documentation: Generate rule documentation for auditors
  • Testing transparency: Understand exactly why a transformation produces its output

Cost Efficiency

Cost FactorProprietaryReframe
License fees$50K-500K/yearFree (Apache 2.0)
Per-message fees$0.01-0.10/messageNone
CustomizationVendor rates ($200-400/hr)In-house or community
SupportMandatory contractsOptional, community available

Control Over Your Infrastructure

With Reframe, you own your transformation infrastructure:

  • Self-hosted: Run on your infrastructure, your cloud, your rules
  • No external dependencies: No calls to vendor APIs during transformation
  • Data sovereignty: Messages never leave your environment
  • Customization: Modify rules to match your specific business requirements

Community and Ecosystem

Reframe is part of a growing ecosystem:

  • Active development: Regular updates and improvements
  • Community support: GitHub issues, discussions, and contributions
  • Ecosystem libraries: Datalogic, Dataflow, Datafake all open source
  • Enterprise support: Available for organizations that need it

Migration Path

Moving from proprietary solutions to Reframe:

  1. Evaluate: Run Reframe alongside your current solution
  2. Compare: Verify transformation outputs match expectations
  3. Customize: Adjust rules for your specific requirements
  4. Migrate: Gradually shift traffic to Reframe
  5. Optimize: Fine-tune performance and add custom features

Real-World Benefits

For Development Teams

  • Debug transformation issues by reading the rules
  • Extend functionality without vendor involvement
  • Test edge cases with full visibility into logic

For Compliance Teams

  • Document transformation logic for regulators
  • Verify SR2025 compliance in detail
  • Audit trail of all rule changes

For Operations Teams

  • Hot-reload configuration without downtime
  • Monitor transformation performance
  • Scale horizontally as needed

Learn About the Architecture →

See Real Use Cases →

Architecture Overview

How Reframe achieves high-performance, transparent message transformation.

Universal, Package-Based Design

Reframe is a universal message transformation engine - not tied to any specific standard. The engine loads transformation packages that define the rules for converting between formats.

Key insight: Reframe is completely format-agnostic - all SWIFT, ISO 20022, and CBPR+ knowledge lives in loadable packages.

Design Principles

Reframe is built on four core principles:

  1. Separation of concerns: Engine logic completely separate from transformation rules
  2. Transparency: All business rules in external, auditable JSON files
  3. Performance: Rust implementation with zero-copy processing
  4. Universality: Package-based architecture supports any message standard

System Architecture

                    ┌──────────────────────────────────────────────┐
                    │              Reframe Engine                  │
                    │                                              │
   Input Message    │  ┌─────────┐  ┌─────────┐  ┌─────────┐       │   Output Message
   (MT or MX)  ────▶│  │ Parser  │─▶│Workflow │─▶│Publisher│─────▶ │   (MX or MT)
                    │  └─────────┘  │ Engine  │  └─────────┘       │
                    │               └────┬────┘                    │
                    │                    │                         │
                    └────────────────────┼─────────────────────────┘
                                         │ loads
                    ┌────────────────────▼─────────────────────────┐
                    │           Transformation Package             │
                    │                                              │
                    │   ┌─────────────┐  ┌─────────────────────┐   │
                    │   │  Workflows  │  │   Field Mappings    │   │
                    │   │  (JSON)     │  │   (JSONLogic)       │   │
                    │   └─────────────┘  └─────────────────────┘   │
                    │                                              │
                    │   ┌─────────────┐  ┌─────────────────────┐   │
                    │   │ Conditions  │  │   Validation Rules  │   │
                    │   │ (JSONLogic) │  │   (JSONLogic)       │   │
                    │   └─────────────┘  └─────────────────────┘   │
                    └──────────────────────────────────────────────┘

Core Components

1. Reframe Engine

The engine handles all runtime processing:

ComponentResponsibility
ParserDetects message format (MT/MX), parses into internal representation
Workflow EngineOrchestrates transformation pipeline using Dataflow
Rule EvaluatorExecutes JSONLogic expressions using Datalogic
PublisherGenerates output in target format (MT or MX XML)
ValidatorValidates messages against schemas and business rules

2. Transformation Package

Packages contain all transformation logic in JSON. Reframe can load any package - it’s not limited to a specific format.

Available Packages:

PackageDescriptionLink
SWIFT CBPR+ MT ↔ ISO 20022SR2025 compliant bidirectional transformations (free)GitHub
Custom packagesCreate your own for FIX, proprietary formats, etc.Package Guide

Example Package Structure (SWIFT CBPR+):

reframe-package-swift-cbpr/
├── reframe-package.json      # Package metadata
├── transform/
│   ├── index.json           # Workflow registry
│   ├── outgoing/            # MT → MX rules
│   │   ├── MT103/
│   │   │   ├── document-mapping.json
│   │   │   ├── bah-mapping.json
│   │   │   └── precondition.json
│   │   └── MT202/
│   └── incoming/            # MX → MT rules
│       ├── pacs008/
│       └── pacs009/
├── validate/                # Validation rules
└── generate/                # Sample generation

3. Technology Stack

LayerTechnologyPurpose
RuntimeRust + TokioAsync, high-performance execution
WorkflowDataflowPipeline orchestration
RulesDatalogicJSONLogic evaluation
MT Parserswift-mt-messageSWIFT MT parsing
MX Parsermx-messageISO 20022 XML parsing
APIAxumHTTP/REST server

Transformation Pipeline

MT to ISO 20022 (Outgoing)

MT103 Input
    │
    ▼
┌─────────────────┐
│ 1. Parse MT     │  Extract blocks and fields
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ 2. Detect Type  │  Identify MT variant (standard/STP/reject/return)
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ 3. Map BAH      │  Create Business Application Header
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ 4. Pre-validate │  Check business rule preconditions
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ 5. Map Document │  Transform fields to ISO 20022 paths
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ 6. Post-validate│  Verify output compliance
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ 7. Publish XML  │  Generate ISO 20022 XML envelope
└────────┬────────┘
         │
         ▼
    pacs.008 Output

ISO 20022 to MT (Incoming)

The reverse flow follows a similar pattern, extracting data from XML and constructing MT blocks.

Performance Characteristics

Zero-Copy Processing

  • Pre-compiled JSONLogic rules at startup
  • No runtime parsing of rule definitions
  • Direct memory access for string operations

Async Architecture

  • Tokio runtime with configurable worker threads
  • Non-blocking I/O for all operations
  • Handles thousands of concurrent requests

Benchmarks

OperationLatencyThroughput
MT103 → pacs.008<1ms5,000+ msg/sec
pacs.008 → MT103<1ms5,000+ msg/sec
Validation<0.5ms10,000+ msg/sec

Benchmarks on standard cloud VM (4 vCPU, 8GB RAM)

Scalability

Horizontal Scaling

  • Stateless design enables simple replication
  • No shared state between instances
  • Load balance across multiple containers

Deployment Options

                    ┌─────────────┐
                    │   Load      │
                    │   Balancer  │
                    └──────┬──────┘
                           │
        ┌──────────────────┼──────────────────┐
        │                  │                  │
        ▼                  ▼                  ▼
   ┌─────────┐       ┌─────────┐       ┌─────────┐
   │ Reframe │       │ Reframe │       │ Reframe │
   │   #1    │       │   #2    │       │   #3    │
   └─────────┘       └─────────┘       └─────────┘

Hot Reload

Update transformation rules without restarting the engine. See Hot Reload Guide →


See Real Use Cases →

Get Started with Quick Start →

Use Cases

Real-world applications of Reframe for message transformation.

Reframe’s package-based architecture supports any message format. Below are common use cases, including the free SWIFT CBPR+ package for ISO 20022 transformations.

Bank Modernization

MT to ISO 20022 Migration

Financial institutions worldwide are migrating from SWIFT MT to ISO 20022. Reframe enables:

Challenge: Banks need to convert existing MT-based systems to support ISO 20022 while maintaining backward compatibility.

Solution with Reframe:

  • Run Reframe alongside existing systems during transition
  • Convert outgoing MT messages to ISO 20022 for SWIFT
  • Convert incoming ISO 20022 to MT for legacy systems
  • Gradually migrate internal systems while maintaining interoperability
Legacy Core Banking          Reframe              SWIFT Network
      (MT)                                         (ISO 20022)
        │                                               │
        │    MT103                                      │
        ├─────────────────▶ Transform ─────────────────▶│
        │                    to MX                pacs.008
        │                                               │
        │    MT103                                      │
        ◀─────────────────◀ Transform ◀─────────────────┤
        │                    to MT                pacs.008

Phased Migration Benefits

  • No big bang: Migrate message types incrementally
  • Fallback ready: Keep MT capability while building MX
  • Testing: Compare outputs side-by-side
  • Timeline control: Move at your own pace

Payment Hub Integration

Central Transformation Service

Large organizations with multiple payment channels benefit from centralized transformation:

┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│  Channel 1  │    │  Channel 2  │    │  Channel 3  │
│  (Legacy)   │    │  (Modern)   │    │  (Partner)  │
└──────┬──────┘    └──────┬──────┘    └──────┬──────┘
       │                  │                  │
       │     MT103        │    pacs.008      │    Mixed
       │                  │                  │
       └──────────────────┼──────────────────┘
                          │
                    ┌─────▼─────┐
                    │  Reframe  │
                    │  Hub      │
                    └─────┬─────┘
                          │
              ┌───────────┼───────────┐
              │           │           │
              ▼           ▼           ▼
         To SWIFT    To Partner   To Archive
         (pacs.008)  (MT103)      (Both)

Benefits:

  • Single transformation engine for all channels
  • Consistent mapping across the organization
  • Centralized rule management and updates
  • Unified logging and monitoring

Testing and Certification

Test Message Generation

Reframe generates valid test messages for any supported type:

curl -X POST http://localhost:3000/api/generate \
  -H "Content-Type: application/json" \
  -d '{"message_type": "MT103", "scenario": "standard"}'

Use cases:

  • Integration testing: Generate realistic messages for system testing
  • Certification: Create messages for SWIFT certification programs
  • Development: Provide developers with valid sample messages
  • Training: Generate examples for training materials

Transformation Testing

Verify transformations before production:

# Transform and validate
curl -X POST http://localhost:3000/api/transform \
  -H "Content-Type: application/json" \
  -d '{
    "message": "<MT103 content>",
    "validation": true,
    "debug": true
  }'

The debug mode shows:

  • Each rule that was applied
  • Intermediate values during transformation
  • Validation results at each step

Regulatory Compliance

SR2025 Compliance

SWIFT’s Standards Release 2025 mandates ISO 20022 for cross-border payments. Reframe provides:

  • Full SR2025 support: All required message types and fields
  • CBPR+ compliance: Cross-Border Payments and Reporting guidelines
  • Audit trail: Complete logging of all transformations
  • Rule documentation: Export rules for compliance review

Compliance Documentation

Generate compliance documentation from rules:

// Example rule with documentation
{
  "path": "data.output.CdtTrfTxInf.ChrgBr",
  "logic": {
    "if": [
      {"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "SHA"]},
      "SHAR",
      {"if": [
        {"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "OUR"]},
        "DEBT",
        "CRED"
      ]}
    ]
  },
  "documentation": {
    "source": "MT Tag 71A Details of Charges",
    "target": "ChargeBearerType1Code",
    "rule": "SHA→SHAR, OUR→DEBT, BEN→CRED",
    "reference": "CBPR+ Usage Guidelines 4.2.1"
  }
}

Message Validation

Pre-transformation Validation

Validate messages before processing:

curl -X POST http://localhost:3000/api/validate \
  -H "Content-Type: application/json" \
  -d '{
    "message": "<message content>",
    "business_validation": true
  }'

Validation checks:

  • Format compliance (MT structure, XML schema)
  • Field content rules (BIC format, amount precision)
  • Business rules (valid currency pairs, date ranges)
  • Network validation rules (SWIFT-specific)

Validation Use Cases

  • Gateway validation: Reject invalid messages before processing
  • Quality assurance: Ensure message quality across channels
  • Debugging: Identify specific validation failures
  • Monitoring: Track validation failure patterns

Multi-Market Support

Regional Customization

Different markets may require rule variations:

┌─────────────────────────────────────────────────┐
│                 Reframe Engine                  │
└─────────────────────────────────────────────────┘
                        │
        ┌───────────────┼───────────────┐
        │               │               │
        ▼               ▼               ▼
   ┌─────────┐    ┌─────────┐    ┌─────────┐
   │  CBPR+  │    │  SEPA   │    │ Target2 │
   │ Package │    │ Package │    │ Package │
   └─────────┘    └─────────┘    └─────────┘

Benefits:

  • Share common rules across markets
  • Customize specific mappings per region
  • Hot-swap packages for different contexts
  • Maintain market-specific compliance

Development and DevOps

Integrate Reframe into your development pipeline with Docker and standard CI/CD tools. Use the GitHub Container Registry image in your workflows:

# GitHub Actions example
services:
  reframe:
    image: plasmatic/reframe:latest
    ports:
      - 3000:3000

For full deployment configurations, see Kubernetes Deployment →


Beyond SWIFT: Custom Packages

Reframe is not limited to SWIFT messaging. Create packages for any transformation need:

FIX Protocol Transformation

Convert between FIX and other formats:

FIX 4.4 Message          Reframe              Internal Format
      │                                               │
      │    NewOrderSingle                             │
      ├─────────────────▶ Transform ─────────────────▶│
      │                                         JSON/XML

Proprietary Format Migration

Organizations with legacy proprietary formats can:

  • Create packages to transform to industry standards
  • Maintain both old and new formats during migration
  • Validate against custom business rules

Multi-Format Hub

A single Reframe instance can load multiple packages:

┌─────────────────────────────────────────────────────┐
│                   Reframe Engine                    │
├─────────────────────────────────────────────────────┤
│                   Loaded Packages                   │
│  ┌──────────┐  ┌──────────┐  ┌──────────────────┐   │
│  │  CBPR+   │  │   FIX    │  │ Custom Format A  │   │
│  │  MT↔MX   │  │  4.4↔5.0 │  │   Legacy→XML     │   │
│  └──────────┘  └──────────┘  └──────────────────┘   │
└─────────────────────────────────────────────────────┘

Building Custom Packages

See the Packages and Rules guide for creating your own transformation packages.


Get Started →

Explore the API →

Transformation Engine

Reframe’s open source rules engine transforms messages between any formats using auditable JSONLogic rules. Load transformation packages for SWIFT MT↔ISO 20022 or custom formats.

How It Works

The transformation engine follows a simple pipeline:

Input Message → Parse → Detect Format → Transform → Validate → Output
  1. Parse: Extract structured data from input format
  2. Detect: Identify message type and target transformation
  3. Transform: Apply JSONLogic mapping rules
  4. Validate: Check output against format rules
  5. Output: Generate target format message

Format Detection

The engine automatically detects input formats based on package rules:

PackageDetectionExample
CBPR+{1: prefix = MT, XML namespace = ISO 20022SWIFT messages
CustomPackage-defined patternsAny format

Transformation Pipeline

Every transformation follows this generic pipeline:

┌────────────────────────────────────────────────────────────┐
│               Generic Transformation Pipeline              │
├────────────────────────────────────────────────────────────┤
│  1. Parse Input      → Extract structured data             │
│  2. Detect Target    → Identify output format              │
│  3. Pre-conditions   → Validate business rules             │
│  4. Map Fields       → Apply JSONLogic transformations     │
│  5. Post-conditions  → Validate output                     │
│  6. Publish          → Generate target format              │
└────────────────────────────────────────────────────────────┘

Packages customize each stage with format-specific rules.

CBPR+ Package Example

For SWIFT CBPR+ transformations:

  • MT → ISO 20022: Parse MT blocks → Map to pacs/camt XML → Validate CBPR+ rules
  • ISO 20022 → MT: Parse XML → Map to MT fields → Validate MT structure

Field Mapping

The core of transformation is field mapping using JSONLogic rules.

Simple Mapping

Direct field copy:

{
  "path": "data.output.field_name",
  "logic": {"var": "data.input.source_field"}
}

Conditional Mapping

Logic-based transformation:

{
  "path": "data.output.status",
  "logic": {
    "if": [
      {"==": [{"var": "data.input.code"}, "A"]}, "ACCEPTED",
      {"==": [{"var": "data.input.code"}, "R"]}, "REJECTED",
      "UNKNOWN"
    ]
  }
}

Composite Mapping

Combining multiple fields:

{
  "path": "data.output.amount",
  "logic": {
    "object": {
      "currency": {"var": "data.input.ccy"},
      "value": {"var": "data.input.amt"}
    }
  }
}

See JSONLogic Rules for complete syntax reference.

Validation Integration

Transformation can include validation:

curl -X POST http://localhost:3000/api/transform \
  -d '{"message": "...", "validation": true}'

When enabled:

  1. Input message validated before transformation
  2. Output message validated after transformation
  3. Validation errors included in response

Error Handling

Transformation errors are categorized:

Error TypeDescription
Parse ErrorCannot parse input message format
Mapping ErrorField transformation failed
Validation ErrorOutput fails format rules
Rule ErrorBusiness rule violation

Error responses include error code, pipeline location, and source field.


Learn About Packages → · JSONLogic Rules →

Packages and Rules

How Reframe organizes transformation logic into modular, reusable packages.

Key Concept: Engine vs Package

Reframe is a universal transformation engine. It doesn’t know anything about SWIFT, ISO 20022, or any specific message format. All transformation knowledge lives in packages.

ComponentContainsExamples
Reframe EngineWorkflow execution, rule evaluation, message parsing frameworkCore engine code
PackagesMessage-specific transformation rules, schemas, validationSWIFT CBPR+, FIX, custom formats

This means you can use Reframe for any message transformation - not just SWIFT/ISO 20022.

Benefits

This separation of engine and packages enables:

  • Customization: Modify rules without changing engine code
  • Multiple packages: Load different rule sets for different contexts
  • Version control: Track rule changes independently
  • Hot reload: Update rules without restarting

For architecture diagrams, see Architecture Overview →

Package Structure

A Reframe package follows this structure:

reframe-package-swift-cbpr/
├── reframe-package.json          # Package metadata
│
├── transform/                    # Transformation workflows
│   ├── index.json               # Workflow registry
│   ├── 00-detect-format.json    # Format detection
│   │
│   ├── outgoing/                # MT → MX rules
│   │   ├── parse-mt.json        # Common MT parser
│   │   ├── combine-xml.json     # XML assembly
│   │   ├── MT103/               # MT103-specific rules
│   │   │   ├── bah-mapping.json
│   │   │   ├── document-mapping.json
│   │   │   ├── precondition.json
│   │   │   └── postcondition.json
│   │   └── MT202/
│   │       └── ...
│   │
│   └── incoming/                # MX → MT rules
│       ├── parse-mx.json        # Common MX parser
│       ├── pacs008/             # pacs.008-specific rules
│       │   ├── 01-variant-detection.json
│       │   ├── 02-preconditions.json
│       │   ├── 03-headers-mapping.json
│       │   └── ...
│       └── pacs009/
│           └── ...
│
├── validate/                    # Validation workflows
│   ├── index.json
│   ├── validate-mt.json
│   └── validate-mx.json
│
├── generate/                    # Sample generation
│   ├── index.json
│   ├── generate-mt.json
│   └── generate-mx.json
│
└── scenarios/                   # Test scenarios
    ├── index.json
    ├── outgoing/
    │   └── mt103_to_pacs008_standard.json
    └── incoming/
        └── pacs008_to_mt103.json

Package Metadata

The reframe-package.json file defines package identity:

{
  "id": "swift-cbpr-mt-mx",
  "name": "SWIFT CBPR+ MT <-> MX Transformations",
  "version": "2.1.2",
  "description": "SR2025 compliant CBPR+ transformations",
  "engine_version": "3.1.4",
  "author": "Plasmatic",
  "license": "Apache-2.0",

  "workflows": {
    "transform": {
      "path": "transform",
      "entry_point": "index.json"
    },
    "generate": {
      "path": "generate",
      "entry_point": "index.json"
    },
    "validate": {
      "path": "validate",
      "entry_point": "index.json"
    }
  },

  "scenarios": {
    "path": "scenarios",
    "entry_point": "index.json"
  }
}

Workflow Definition

Workflows are defined in JSON with this structure:

{
  "id": "mt103-document-mapping",
  "name": "MT103 Document Mapping",
  "description": "Maps MT103 fields to pacs.008 document",
  "priority": 5,

  "condition": {
    "and": [
      {"==": [{"var": "metadata.direction"}, "outgoing"]},
      {"==": [{"var": "metadata.message_type"}, "MT103"]}
    ]
  },

  "tasks": [
    {
      "id": "map-payment-id",
      "name": "Map Payment Identification",
      "function": {
        "name": "map",
        "input": {
          "mappings": [
            {
              "path": "data.output.PmtId.InstrId",
              "logic": {"var": "data.SwiftMT.fields.20.transaction_reference"}
            },
            {
              "path": "data.output.PmtId.EndToEndId",
              "logic": {"var": "data.SwiftMT.fields.21.related_reference"}
            }
          ]
        }
      }
    }
  ]
}

Workflow Properties

PropertyDescription
idUnique identifier
priorityExecution order (lower = earlier)
conditionJSONLogic expression determining when workflow runs
tasksArray of tasks to execute

Task Properties

PropertyDescription
idTask identifier
function.nameFunction to execute (map, validation, custom)
function.inputFunction-specific configuration
conditionOptional condition for task execution

Rule Organization

Rules are organized by message type and transformation stage:

Outgoing (MT → MX)

transform/outgoing/MT103/
├── bah-mapping.json       # Priority 3: Business Application Header
├── precondition.json      # Priority 4: Pre-transformation validation
├── document-mapping.json  # Priority 5: Field transformation
└── postcondition.json     # Priority 6: Post-transformation validation

Incoming (MX → MT)

transform/incoming/pacs008/
├── 01-variant-detection.json    # Detect target MT type
├── 02-preconditions.json        # Validate transformation
├── 03-headers-mapping.json      # Map MT headers
├── 04-mandatory-fields.json     # Required fields
├── 05-amount-fields.json        # Amount handling
├── 06-party-fields.json         # Party information
├── 07-agent-fields.json         # Agent (bank) information
├── 08-remittance-fields.json    # Remittance details
└── 09-postconditions.json       # Final validation

Priority-Based Execution

Workflows execute in priority order:

Priority 1: parse-mt.json          ─── Parse input
Priority 2: method-detection.json  ─── Detect variant
Priority 3: bah-mapping.json       ─── Map header
Priority 4: precondition.json      ─── Validate
Priority 5: document-mapping.json  ─── Transform
Priority 6: postcondition.json     ─── Validate output
Priority 10: combine-xml.json      ─── Generate XML

This ensures:

  • Parsing happens before mapping
  • Validation occurs at appropriate stages
  • Output generation happens last

Loading Packages

Default Package Path

# Environment variable
export REFRAME_PACKAGE_PATH=/path/to/packages

# Or in reframe.config.json
{
  "packages": [
    {
      "path": "/packages/swift-cbpr",
      "enabled": true
    }
  ]
}

Docker Volume Mount

services:
  reframe:
    image: plasmatic/reframe:latest
    volumes:
      - ./my-package:/packages/my-package
    environment:
      - REFRAME_PACKAGE_PATH=/packages

Packages can be hot-reloaded. See Hot Reload →

Creating Custom Packages

1. Create Package Structure

mkdir -p my-package/{transform,validate,generate,scenarios}

2. Define Package Metadata

// my-package/reframe-package.json
{
  "id": "my-custom-package",
  "name": "My Custom Transformations",
  "version": "1.0.0",
  "engine_version": "3.1.0",
  "workflows": {
    "transform": {"path": "transform", "entry_point": "index.json"}
  }
}

3. Create Workflow Index

// my-package/transform/index.json
{
  "workflows": [
    {"path": "my-transformation.json"}
  ]
}

4. Define Transformation Rules

// my-package/transform/my-transformation.json
{
  "id": "my-transform",
  "name": "My Custom Transformation",
  "priority": 5,
  "condition": {"==": [{"var": "metadata.type"}, "custom"]},
  "tasks": [
    // ... your mapping tasks
  ]
}

JSONLogic Rules

How Reframe uses JSONLogic for business rules and field transformations.

What is JSONLogic?

JSONLogic is a standard for expressing business logic as JSON. It provides:

  • Portable rules: Same rules work across languages and platforms
  • Human-readable: Logic expressed in familiar JSON structure
  • Safe evaluation: No arbitrary code execution
  • Testable: Rules can be validated independently

Reframe uses Datalogic, a high-performance Rust implementation of JSONLogic with 59 built-in operators.

Basic Syntax

JSONLogic expressions follow this pattern:

{ "operator": [arguments] }

Variable Access

Read data from the message context:

{"var": "data.SwiftMT.fields.20.transaction_reference"}

This accesses:

data
└── SwiftMT
    └── fields
        └── 20
            └── transaction_reference → "REF123456"

Comparison

{"==": [{"var": "data.field"}, "expected_value"]}
{"!=": [{"var": "data.field"}, "unexpected_value"]}
{">": [{"var": "data.amount"}, 10000]}
{">=": [{"var": "data.amount"}, 0]}

Boolean Logic

{"and": [condition1, condition2]}
{"or": [condition1, condition2]}
{"!": [condition]}
{"!!": [value]}  // Convert to boolean

Common Transformation Patterns

Direct Mapping

Copy a value from source to target:

{
  "path": "data.output.InstrId",
  "logic": {"var": "data.SwiftMT.fields.20.transaction_reference"}
}

Conditional Mapping

Map different values based on conditions:

{
  "path": "data.output.ChrgBr",
  "logic": {
    "if": [
      {"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "SHA"]},
      "SHAR",
      {"if": [
        {"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "OUR"]},
        "DEBT",
        "CRED"
      ]}
    ]
  }
}

Default Values

Provide fallback when source is missing:

{
  "path": "data.output.PmtTpInf.SvcLvl.Cd",
  "logic": {
    "or": [
      {"var": "data.SwiftMT.fields.23B.bank_operation_code"},
      "G001"
    ]
  }
}

String Concatenation

Combine multiple fields:

{
  "path": "data.output.FullName",
  "logic": {
    "cat": [
      {"var": "data.first_name"},
      " ",
      {"var": "data.last_name"}
    ]
  }
}

String Extraction

Extract portions of a string:

{
  "path": "data.output.CountryCode",
  "logic": {
    "substr": [
      {"var": "data.SwiftMT.fields.50K.account"},
      0,
      2
    ]
  }
}

Array Operations

Map (Transform Each Element)

{
  "map": [
    {"var": "data.items"},
    {"cat": ["Item: ", {"var": ""}]}
  ]
}

Filter

{
  "filter": [
    {"var": "data.transactions"},
    {">": [{"var": "amount"}, 1000]}
  ]
}

Reduce (Aggregate)

{
  "reduce": [
    {"var": "data.amounts"},
    {"+": [{"var": "accumulator"}, {"var": "current"}]},
    0
  ]
}

Check All/Some/None

{"all": [{"var": "data.items"}, {"!!": {"var": "valid"}}]}
{"some": [{"var": "data.items"}, {"==": [{"var": "status"}, "active"]}]}
{"none": [{"var": "data.items"}, {"<": [{"var": "amount"}, 0]}]}

Object Construction

Create Objects

Build complex structures:

{
  "path": "data.output.Amt",
  "logic": {
    "object": {
      "Ccy": {"var": "data.SwiftMT.fields.32A.currency"},
      "value": {"var": "data.SwiftMT.fields.32A.amount"}
    }
  }
}

Nested Objects

{
  "path": "data.output.Dbtr",
  "logic": {
    "object": {
      "Nm": {"var": "data.SwiftMT.fields.50K.name"},
      "PstlAdr": {
        "object": {
          "Ctry": {"var": "data.country"},
          "AdrLine": {"var": "data.address_lines"}
        }
      }
    }
  }
}

Date and Time Operations

Current Timestamp

{"now": []}

Format Date

{
  "format_date": [
    {"var": "data.date"},
    "%Y-%m-%d"
  ]
}

Parse Date

{
  "parse_date": [
    {"var": "data.date_string"},
    "%y%m%d"
  ]
}

Validation Rules

Use JSONLogic for validation:

{
  "id": "validate-amount",
  "function": {
    "name": "validation",
    "input": {
      "rules": [
        {
          "logic": {">": [{"var": "data.amount"}, 0]},
          "message": "Amount must be positive"
        },
        {
          "logic": {"!!": {"var": "data.currency"}},
          "message": "Currency is required"
        },
        {
          "logic": {
            "in": [
              {"var": "data.currency"},
              ["USD", "EUR", "GBP", "JPY"]
            ]
          },
          "message": "Invalid currency code"
        }
      ]
    }
  }
}

CBPR+ Rule Examples

Charge Bearer Mapping

// MT Tag 71A to ISO 20022 ChargeBearerType1Code
{
  "if": [
    {"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "SHA"]},
    "SHAR",
    {"if": [
      {"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "OUR"]},
      "DEBT",
      {"if": [
        {"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "BEN"]},
        "CRED",
        "SHAR"
      ]}
    ]}
  ]
}

Service Level Determination

// Determine CBPR+ service level from MT fields
{
  "if": [
    {"==": [{"var": "data.SwiftMT.fields.23E.instruction_code"}, "URGP"]},
    "G001",
    {"if": [
      {"==": [{"var": "data.SwiftMT.fields.23B.bank_operation_code"}, "SPAY"]},
      "G003",
      "G002"
    ]}
  ]
}

Party Identification

// Build creditor identification from MT fields
{
  "object": {
    "Nm": {"var": "data.SwiftMT.fields.59.beneficiary_name"},
    "PstlAdr": {
      "object": {
        "AdrLine": {
          "filter": [
            {"var": "data.SwiftMT.fields.59.address_lines"},
            {"!!": {"var": ""}}
          ]
        }
      }
    },
    "Id": {
      "if": [
        {"!!": {"var": "data.SwiftMT.fields.59.account"}},
        {
          "object": {
            "OrgId": {
              "object": {
                "Othr": {
                  "object": {
                    "Id": {"var": "data.SwiftMT.fields.59.account"}
                  }
                }
              }
            }
          }
        },
        null
      ]
    }
  }
}

Testing Rules

Test rules in the Datalogic playground:

Datalogic Playground →

Example test:

// Rule
{
  "if": [
    {">": [{"var": "amount"}, 10000]},
    "HIGH",
    "NORMAL"
  ]
}

// Data
{"amount": 50000}

// Result
"HIGH"

Operator Reference

Comparison Operators

==, ===, !=, !==, >, >=, <, <=

Boolean Operators

and, or, !, !!

Numeric Operators

+, -, *, /, %, min, max, abs

String Operators

cat, substr, in, starts_with, ends_with, upper, lower, trim

Array Operators

map, filter, reduce, all, some, none, merge, sort

Control Flow

if, ?:, ??

Date/Time

now, datetime, format_date, parse_date, date_diff

Complete Operator Reference →


Workflow Orchestration

How Reframe orchestrates transformation pipelines using Dataflow.

Dataflow Engine

Reframe uses Dataflow for workflow orchestration. Dataflow provides:

  • Pre-compiled workflows: All rules compiled at startup, zero runtime parsing
  • Priority-based execution: Workflows execute in defined order
  • Conditional routing: Rules determine which workflows apply
  • Audit trail: Complete record of all transformations

Workflow Execution Model

                    Input Message
                          │
                          ▼
              ┌───────────────────────┐
              │   Message Context     │
              │   • data              │
              │   • metadata          │
              │   • temp_data         │
              └───────────┬───────────┘
                          │
         ┌────────────────┼────────────────┐
         │                │                │
         ▼                ▼                ▼
    ┌─────────┐     ┌─────────┐     ┌─────────┐
    │Workflow │     │Workflow │     │Workflow │
    │   P:1   │────▶│   P:5   │────▶│  P:10   │
    └─────────┘     └─────────┘     └─────────┘
         │                │                │
         ▼                ▼                ▼
    ┌─────────────────────────────────────────┐
    │           Updated Context               │
    └─────────────────────────────────────────┘
                          │
                          ▼
                   Output Message

Message Context

Every message flows through with a context object:

{
  "context": {
    "data": {
      "SwiftMT": { /* parsed MT message */ },
      "output": { /* transformation output */ }
    },
    "metadata": {
      "direction": "outgoing",
      "message_type": "MT103",
      "variant": "standard"
    },
    "temp_data": {
      /* intermediate calculations */
    }
  },
  "audit_trail": [
    /* record of all changes */
  ],
  "errors": [
    /* any errors encountered */
  ]
}

Context Sections

SectionPurpose
dataPrimary business data (input and output)
metadataRouting and tracking information
temp_dataIntermediate processing results
audit_trailRecord of all modifications
errorsCollected errors and warnings

Workflow Structure

A workflow definition:

{
  "id": "mt103-transform",
  "name": "MT103 Transformation",
  "description": "Transform MT103 to pacs.008",
  "priority": 5,

  "condition": {
    "and": [
      {"==": [{"var": "metadata.direction"}, "outgoing"]},
      {"==": [{"var": "metadata.message_type"}, "MT103"]}
    ]
  },

  "error_handling": "continue",

  "tasks": [
    {
      "id": "map-payment-info",
      "name": "Map Payment Information",
      "function": {
        "name": "map",
        "input": {
          "mappings": [/* field mappings */]
        }
      }
    }
  ]
}

Workflow Properties

PropertyTypeDescription
idstringUnique workflow identifier
namestringHuman-readable name
prioritynumberExecution order (lower = earlier)
conditionJSONLogicWhen this workflow should run
error_handlingstring"continue" or "stop" on error
tasksarrayTasks to execute

Priority-Based Execution

Workflows execute in priority order:

Priority 1: parse-mt.json
    │
    ▼ (condition check)
Priority 2: detect-variant.json
    │
    ▼ (condition check)
Priority 3: bah-mapping.json
    │
    ▼ (condition check)
Priority 4: precondition.json
    │
    ▼ (condition check)
Priority 5: document-mapping.json
    │
    ▼ (condition check)
Priority 6: postcondition.json
    │
    ▼ (condition check)
Priority 10: publish-xml.json

Each workflow’s condition is evaluated:

  • Condition true: Workflow executes
  • Condition false: Workflow skipped

Task Types

Map Task

Transform data using JSONLogic:

{
  "id": "map-fields",
  "function": {
    "name": "map",
    "input": {
      "mappings": [
        {
          "path": "data.output.field1",
          "logic": {"var": "data.input.source_field"}
        },
        {
          "path": "data.output.field2",
          "logic": {"cat": [{"var": "data.a"}, {"var": "data.b"}]}
        }
      ]
    }
  }
}

Validation Task

Validate data against rules:

{
  "id": "validate-input",
  "function": {
    "name": "validation",
    "input": {
      "rules": [
        {
          "logic": {"!!": {"var": "data.required_field"}},
          "message": "Required field is missing"
        },
        {
          "logic": {">": [{"var": "data.amount"}, 0]},
          "message": "Amount must be positive"
        }
      ]
    }
  }
}

Custom Function Task

Call custom functions registered with the engine:

{
  "id": "parse-message",
  "function": {
    "name": "parse_mt",
    "input": {
      "source": "data.raw_message",
      "target": "data.SwiftMT"
    }
  }
}

Conditional Tasks

Tasks can have their own conditions:

{
  "id": "map-optional-field",
  "condition": {
    "!!": {"var": "data.SwiftMT.fields.70.remittance_information"}
  },
  "function": {
    "name": "map",
    "input": {
      "mappings": [
        {
          "path": "data.output.RmtInf.Ustrd",
          "logic": {"var": "data.SwiftMT.fields.70.remittance_information"}
        }
      ]
    }
  }
}

The task only executes if the condition evaluates to true.

Audit Trail

Every modification is recorded:

{
  "audit_trail": [
    {
      "timestamp": "2025-01-15T10:30:00.123Z",
      "workflow_id": "mt103-transform",
      "task_id": "map-payment-info",
      "path": "data.output.PmtId.InstrId",
      "old_value": null,
      "new_value": "REF123456"
    },
    {
      "timestamp": "2025-01-15T10:30:00.125Z",
      "workflow_id": "mt103-transform",
      "task_id": "map-amount",
      "path": "data.output.IntrBkSttlmAmt",
      "old_value": null,
      "new_value": {"Ccy": "USD", "value": "50000.00"}
    }
  ]
}

Audit Trail Benefits

  • Debugging: See exactly what changed and when
  • Compliance: Complete transformation history
  • Testing: Verify expected transformations occurred
  • Monitoring: Track transformation patterns

Error Handling

Workflow-Level Handling

{
  "id": "critical-workflow",
  "error_handling": "stop",
  "tasks": [/* ... */]
}
SettingBehavior
"continue"Log error, continue to next workflow
"stop"Halt processing, return error

Task-Level Handling

{
  "id": "optional-task",
  "error_handling": "continue",
  "function": {/* ... */}
}

Error Collection

Errors are collected in the context:

{
  "errors": [
    {
      "workflow_id": "validation",
      "task_id": "check-amount",
      "code": "VALIDATION_FAILED",
      "message": "Amount must be positive"
    }
  ]
}

Performance Optimization

Pre-Compilation

All JSONLogic rules are compiled at startup:

Startup
   │
   ▼
┌──────────────────┐
│ Load Workflows   │
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│ Compile All      │  ← One-time cost
│ JSONLogic Rules  │
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│ Cache Compiled   │
│ Rules in Memory  │
└────────┬─────────┘
         │
         ▼
    Ready to Process

Runtime Efficiency

During message processing:

  • No parsing of rule definitions
  • Direct execution of compiled logic
  • O(1) access to cached rules

Workflow Index

The workflow index registers all workflows:

// transform/index.json
{
  "workflows": [
    {"path": "00-detect-format.json"},
    {"path": "outgoing/parse-mt.json"},
    {"path": "outgoing/MT103/bah-mapping.json"},
    {"path": "outgoing/MT103/document-mapping.json"},
    {"path": "outgoing/combine-xml.json"},
    {"path": "incoming/parse-mx.json"},
    {"path": "incoming/pacs008/variant-detection.json"},
    {"path": "incoming/pacs008/field-mapping.json"}
  ]
}

Try the Dataflow Playground →

See CBPR+ Workflows →

Quick Start: Run Reframe in 5 Minutes

Get the open source SWIFT MT to ISO 20022 transformation engine running locally.

Note: This guide uses the CBPR+ package (SWIFT MT ↔ ISO 20022). Reframe supports custom transformation packages for other formats.

Prerequisites

  • Docker installed (Get Docker)
  • curl or similar HTTP client

Step 1: Start Reframe

# Pull and run Reframe
docker run -d -p 3000:3000 --name reframe plasmatic/reframe:latest

# Verify it's running
curl http://localhost:3000/health

Expected response:

{
  "status": "healthy",
  "engines": {
    "transform": "ready",
    "generation": "ready",
    "validation": "ready"
  }
}

Step 2: Transform a Message (CBPR+ Example)

Transform an MT103 to ISO 20022 pacs.008 using the included CBPR+ package:

curl -X POST http://localhost:3000/api/transform \
  -H "Content-Type: application/json" \
  -d '{
    "message": "{1:F01BNPAFRPPXXX0000000000}{2:I103DEUTDEFFXXXXN}{4:\n:20:REF123456\n:23B:CRED\n:32A:250115USD50000,00\n:50K:/12345678\nACME CORPORATION\n123 MAIN STREET\nNEW YORK NY 10001\n:59:/98765432\nGLOBAL TRADING LTD\n456 HIGH STREET\nLONDON EC1A 1BB\n:71A:SHA\n-}"
  }'

The response contains the transformed pacs.008 XML message.

Step 3: Generate a Sample Message

Generate a test MT103 message:

curl -X POST http://localhost:3000/api/generate \
  -H "Content-Type: application/json" \
  -d '{"message_type": "MT103", "scenario": "standard"}'

Step 4: Validate a Message

Validate any MT or ISO 20022 message:

curl -X POST http://localhost:3000/api/validate \
  -H "Content-Type: application/json" \
  -d '{
    "message": "<your message here>",
    "business_validation": true
  }'

Try the Playground

For a visual interface, use the interactive playground:

Open Playground →

The playground lets you:

  • Generate sample messages
  • Transform between formats
  • Validate messages
  • See API requests and responses

What’s Next?

First Transformation Tutorial → Step-by-step guide to understanding MT103 → pacs.008 transformation

CBPR+ Guide → Explore all supported message types

API Reference → Complete API documentation

Common Issues

Port Already in Use

# Check what's using port 3000
lsof -i :3000

# Use a different port
docker run -p 8080:3000 plasmatic/reframe:latest

Container Not Starting

# Check container logs
docker logs reframe

# Run in foreground for debugging
docker run -p 3000:3000 plasmatic/reframe:latest

Connection Refused

Ensure Docker is running and the container is healthy:

docker ps
docker inspect reframe | grep Health

Your First Transformation

A step-by-step guide to understanding how Reframe transforms MT103 to ISO 20022 pacs.008.

What We’ll Cover

  1. Understanding the MT103 message structure
  2. Transforming MT103 to pacs.008
  3. Examining the transformation result
  4. Understanding field mappings

The MT103 Message

MT103 is SWIFT’s standard message for single customer credit transfers. Here’s a sample:

{1:F01BNPAFRPPXXX0000000000}
{2:I103DEUTDEFFXXXXN}
{3:{121:174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a}}
{4:
:20:REF123456
:23B:CRED
:32A:250115USD50000,00
:50K:/12345678
ACME CORPORATION
123 MAIN STREET
NEW YORK NY 10001
:59:/98765432
GLOBAL TRADING LTD
456 HIGH STREET
LONDON EC1A 1BB
:71A:SHA
-}

MT103 Structure

Block/TagContentPurpose
Block 1F01BNPAFRPPXXX...Basic header - sender BIC
Block 2I103DEUTDEFFXXXXApplication header - receiver BIC
Block 3{121:...}User header - UETR
Tag 20REF123456Transaction reference
Tag 23BCREDBank operation code
Tag 32A250115USD50000,00Value date, currency, amount
Tag 50KAccount + Name + AddressOrdering customer (debtor)
Tag 59Account + Name + AddressBeneficiary (creditor)
Tag 71ASHACharges (shared)

Step 1: Send the Transformation Request

curl -X POST http://localhost:3000/api/transform \
  -H "Content-Type: application/json" \
  -d '{
    "message": "{1:F01BNPAFRPPXXX0000000000}{2:I103DEUTDEFFXXXXN}{3:{121:174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a}}{4:\n:20:REF123456\n:23B:CRED\n:32A:250115USD50000,00\n:50K:/12345678\nACME CORPORATION\n123 MAIN STREET\nNEW YORK NY 10001\n:59:/98765432\nGLOBAL TRADING LTD\n456 HIGH STREET\nLONDON EC1A 1BB\n:71A:SHA\n-}",
    "validation": true
  }'

Step 2: Examine the Response

The response contains the transformed pacs.008 message:

{
  "status": "success",
  "direction": "outgoing",
  "source_type": "MT103",
  "target_type": "pacs.008.001.12",
  "message": "<?xml version=\"1.0\"?>...",
  "timing_ms": 0.8
}

Step 3: Understanding the pacs.008 Output

The transformed ISO 20022 message has two parts:

Business Application Header (BAH)

<AppHdr xmlns="urn:iso:std:iso:20022:tech:xsd:head.001.001.03">
  <Fr>
    <FIId>
      <FinInstnId>
        <BICFI>BNPAFRPPXXX</BICFI>
      </FinInstnId>
    </FIId>
  </Fr>
  <To>
    <FIId>
      <FinInstnId>
        <BICFI>DEUTDEFFXXX</BICFI>
      </FinInstnId>
    </FIId>
  </To>
  <BizMsgIdr>REF123456</BizMsgIdr>
  <MsgDefIdr>pacs.008.001.12</MsgDefIdr>
  <CreDt>2025-01-15T10:30:00Z</CreDt>
</AppHdr>

Document (pacs.008)

<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.12">
  <FIToFICstmrCdtTrf>
    <GrpHdr>
      <MsgId>REF123456</MsgId>
      <CreDtTm>2025-01-15T10:30:00Z</CreDtTm>
      <NbOfTxs>1</NbOfTxs>
      <SttlmInf>
        <SttlmMtd>INDA</SttlmMtd>
      </SttlmInf>
    </GrpHdr>
    <CdtTrfTxInf>
      <PmtId>
        <InstrId>REF123456</InstrId>
        <EndToEndId>REF123456</EndToEndId>
        <UETR>174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a</UETR>
      </PmtId>
      <IntrBkSttlmAmt Ccy="USD">50000.00</IntrBkSttlmAmt>
      <IntrBkSttlmDt>2025-01-15</IntrBkSttlmDt>
      <ChrgBr>SHAR</ChrgBr>
      <Dbtr>
        <Nm>ACME CORPORATION</Nm>
        <PstlAdr>
          <AdrLine>123 MAIN STREET</AdrLine>
          <AdrLine>NEW YORK NY 10001</AdrLine>
        </PstlAdr>
      </Dbtr>
      <DbtrAcct>
        <Id>
          <Othr>
            <Id>12345678</Id>
          </Othr>
        </Id>
      </DbtrAcct>
      <DbtrAgt>
        <FinInstnId>
          <BICFI>BNPAFRPPXXX</BICFI>
        </FinInstnId>
      </DbtrAgt>
      <CdtrAgt>
        <FinInstnId>
          <BICFI>DEUTDEFFXXX</BICFI>
        </FinInstnId>
      </CdtrAgt>
      <Cdtr>
        <Nm>GLOBAL TRADING LTD</Nm>
        <PstlAdr>
          <AdrLine>456 HIGH STREET</AdrLine>
          <AdrLine>LONDON EC1A 1BB</AdrLine>
        </PstlAdr>
      </Cdtr>
      <CdtrAcct>
        <Id>
          <Othr>
            <Id>98765432</Id>
          </Othr>
        </Id>
      </CdtrAcct>
    </CdtTrfTxInf>
  </FIToFICstmrCdtTrf>
</Document>

Field Mapping Summary

Here’s how key MT103 fields map to pacs.008:

MT103 Fieldpacs.008 PathExample
Block 1 BICFr/FIId/FinInstnId/BICFIBNPAFRPPXXX
Block 2 BICTo/FIId/FinInstnId/BICFIDEUTDEFFXXX
Tag 20PmtId/InstrIdREF123456
Tag 121 (UETR)PmtId/UETR174d2c70-…
Tag 32A dateIntrBkSttlmDt2025-01-15
Tag 32A amountIntrBkSttlmAmt50000.00
Tag 32A currencyIntrBkSttlmAmt/@CcyUSD
Tag 50K nameDbtr/NmACME CORPORATION
Tag 50K accountDbtrAcct/Id/Othr/Id12345678
Tag 59 nameCdtr/NmGLOBAL TRADING LTD
Tag 59 accountCdtrAcct/Id/Othr/Id98765432
Tag 71AChrgBrSHA → SHAR

Charge Bearer Mapping

The 71A tag maps to ISO 20022 charge bearer codes:

MT (71A)ISO 20022Meaning
SHASHARShared between parties
OURDEBTAll charges to debtor
BENCREDAll charges to creditor

Try It Yourself

Use the interactive playground to experiment:

Debug Mode

To see the transformation steps, add debug: true:

curl -X POST http://localhost:3000/api/transform \
  -H "Content-Type: application/json" \
  -d '{
    "message": "...",
    "debug": true
  }'

The debug response shows:

  • Parsed input structure
  • Each workflow that executed
  • Intermediate transformation values
  • Final output assembly

Reverse Transformation

Transform pacs.008 back to MT103:

curl -X POST http://localhost:3000/api/transform \
  -H "Content-Type: application/json" \
  -d '{
    "message": "<?xml version=\"1.0\"?>..."
  }'

Reframe auto-detects the input format and applies the appropriate transformation direction.


Explore CBPR+ Message Types →

See MT103 → pacs.008 Details →

API Reference →

CBPR+ Package: SWIFT MT to ISO 20022 Migration Guide

The free, open source CBPR+ transformation package for SWIFT MT to ISO 20022 migration with SR2025 compliance.

About This Package

The SWIFT CBPR+ Package is a free, open-source transformation package for Reframe. It provides:

  • 41+ transformation scenarios for SWIFT MT ↔ ISO 20022
  • SR2025 compliance for the November 2025 migration deadline
  • Bidirectional support - convert in both directions
  • 594 JSON rule files - fully auditable transformation logic
GitHubgithub.com/GoPlasmatic/reframe-package-swift-cbpr
LicenseApache 2.0 (Free)
Version2.1.2

What is CBPR+?

CBPR+ (Cross-Border Payments and Reporting Plus) is SWIFT’s framework for the migration from MT messages to ISO 20022. It defines:

  • Which ISO 20022 messages replace which MT messages
  • Field mapping guidelines between formats
  • Business rules and validation requirements
  • Coexistence rules during the migration period

SR2025 Compliance

This CBPR+ package is fully compliant with SWIFT Standards Release 2025 (SR2025), which becomes mandatory in November 2025. Key SR2025 features:

  • Business Application Header v3
  • UETR (Unique End-to-End Transaction Reference) support
  • Enhanced party identification with LEI
  • Structured remittance information
  • Updated message versions (pacs.008.001.12, pacs.009.001.11, etc.)

Supported Transformations

The CBPR+ package supports 41+ transformation scenarios across payment, status, and administrative messages.

Message Categories

CategoryDescriptionExamples
Customer PaymentsIndividual customer transfersMT103 ↔ pacs.008
FI TransfersBank-to-bank transfersMT202 ↔ pacs.009
ReturnsPayment returnsMT103 RETN ↔ pacs.004
RejectionsPayment rejectionsMT103 REJT ↔ pacs.002
CancellationsCancellation requestsMT192 ↔ camt.056
StatusPayment status reportsMT199 ↔ camt.029
Cash ManagementAccount statementsMT940 ↔ camt.053

Direction Terminology

TermDirectionDescription
OutgoingMT → MXSWIFT MT converted to ISO 20022
IncomingMX → MTISO 20022 converted to SWIFT MT

Package Structure

The CBPR+ package contains 594 JSON rule files organized by transformation type:

reframe-package-swift-cbpr/
├── reframe-package.json          # Package metadata
│
├── transform/                    # Transformation workflows
│   ├── outgoing/                # MT → ISO 20022
│   │   ├── MT103/               # Customer transfers
│   │   ├── MT202/               # FI transfers
│   │   ├── MT192/               # Cancellations
│   │   └── ...
│   │
│   └── incoming/                # ISO 20022 → MT
│       ├── pacs008/             # FIToFICustomerCreditTransfer
│       ├── pacs009/             # FIToFIFinancialInstitutionCreditTransfer
│       ├── camt056/             # FIToFIPaymentCancellationRequest
│       └── ...
│
├── validate/                    # Validation rules
└── generate/                    # Sample generation

Message Flow

Outgoing Flow (MT → ISO 20022)

MT103 Message
      │
      ▼
┌─────────────────┐
│ 1. Parse MT     │  Extract SWIFT blocks and fields
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ 2. Detect Type  │  Identify variant (standard/STP/REJT/RETN)
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ 3. Apply Rules  │  Execute CBPR+ mapping rules
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ 4. Generate XML │  Create ISO 20022 envelope
└────────┬────────┘
         │
         ▼
   pacs.008 XML

Incoming Flow (ISO 20022 → MT)

pacs.008 XML
      │
      ▼
┌─────────────────┐
│ 1. Parse XML    │  Extract ISO 20022 structure
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ 2. Detect MT    │  Determine target MT type
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ 3. Apply Rules  │  Execute reverse mapping rules
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ 4. Generate MT  │  Create SWIFT message blocks
└────────┬────────┘
         │
         ▼
   MT103 Message

Key Concepts

Business Application Header (BAH)

ISO 20022 messages include a BAH with routing information:

<AppHdr xmlns="urn:iso:std:iso:20022:tech:xsd:head.001.001.03">
  <Fr><FIId><FinInstnId><BICFI>SENDERXX</BICFI></FinInstnId></FIId></Fr>
  <To><FIId><FinInstnId><BICFI>RECEIVERXX</BICFI></FinInstnId></FIId></To>
  <BizMsgIdr>MSG123</BizMsgIdr>
  <MsgDefIdr>pacs.008.001.12</MsgDefIdr>
  <CreDt>2025-01-15T10:30:00Z</CreDt>
</AppHdr>

The BAH is generated from MT Block 1 and Block 2 information.

UETR (Unique End-to-End Transaction Reference)

UETR provides end-to-end tracking for payments:

  • Format: UUID v4 (e.g., 174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a)
  • In MT: Tag 121 in Block 3
  • In ISO 20022: PmtId/UETR

Service Level Codes

CBPR+ defines service levels for payment processing:

CodeNameDescription
G001URGPUrgent payment (high priority)
G002NURGNormal urgent (standard)
G003SDVASame-day value
G004NORMNormal (next-day)

Try the Transformations

Interactive Playground

API Examples

# MT103 → pacs.008
curl -X POST http://localhost:3000/api/transform \
  -H "Content-Type: application/json" \
  -d '{"message": "{1:F01...}{2:I103...}{4:...}"}'

# pacs.008 → MT103
curl -X POST http://localhost:3000/api/transform \
  -H "Content-Type: application/json" \
  -d '{"message": "<?xml version=\"1.0\"?>..."}'

View Message Catalog →

MT to ISO 20022 Transformations →

ISO 20022 to MT Transformations →

Message Catalog

Complete list of message types supported by the Reframe CBPR+ package.

Outgoing Transformations (MT → ISO 20022)

Customer Payments

MT TypeISO 20022Description
MT101pain.001Request for Transfer
MT103pacs.008Single Customer Credit Transfer
MT103 STPpacs.008Straight-Through Processing variant
MT103 REJTpacs.002Payment Rejection
MT103 RETNpacs.004Payment Return

Financial Institution Transfers

MT TypeISO 20022Description
MT200pacs.009Financial Institution Transfer (Own Account)
MT202pacs.009Financial Institution Transfer
MT202 COVpacs.009Cover Payment
MT202 REJTpacs.002FI Transfer Rejection
MT202 RETNpacs.004FI Transfer Return
MT205pacs.009Financial Institution Transfer (Third Party)
MT205 COVpacs.009Cover Payment (Third Party)
MT205 REJTpacs.002FI Transfer Rejection
MT205 RETNpacs.004FI Transfer Return

Cancellation & Investigation

MT TypeISO 20022Description
MT192camt.056Request for Cancellation (Customer)
MT196camt.029Answer to Cancellation Request
MT292camt.056Request for Cancellation (FI)
MT296camt.029Answer to Cancellation Request (FI)

Cash Management

MT TypeISO 20022Description
MT900camt.054Confirmation of Debit
MT910camt.054Confirmation of Credit
MT940camt.053Customer Statement
MT941camt.052Balance Report
MT942camt.052Interim Transaction Report

Incoming Transformations (ISO 20022 → MT)

Payment Messages

ISO 20022MT TypeDescription
pain.001MT101CustomerCreditTransferInitiation
pacs.002MT103 REJT / MT202 REJTFIToFIPaymentStatusReport
pacs.003MT104FIToFICustomerDirectDebit
pacs.004MT103 RETN / MT202 RETNPaymentReturn
pacs.008MT103FIToFICustomerCreditTransfer
pacs.009MT202 / MT202 COV / MT205FIToFIFinancialInstitutionCreditTransfer
pacs.010MT204FIToFIDirectDebit

Cash Management Messages

ISO 20022MT TypeDescription
camt.029MT196 / MT296ResolutionOfInvestigation
camt.052MT942 / MT941BankToCustomerAccountReport
camt.053MT940BankToCustomerStatement
camt.054MT900 / MT910 / MT103 / MT202BankToCustomerDebitCreditNotification
camt.056MT192 / MT292FIToFIPaymentCancellationRequest
camt.057MT210NotificationToReceive
camt.058NotificationNotificationToReceiveCancellationAdvice

SR2025 New Messages

ISO 20022MT TypeDescription
camt.105MTn90ChargesPaymentNotification
camt.106MTn91ChargesPaymentRequest
camt.107MT110ChequePresentation
camt.108MT111ChequeCancellationOrStopRequest
camt.109MT112ChequeCancellationOrStopReport
admi.024MT199SystemEventNotification

Message Type Details

pacs.008 - FIToFICustomerCreditTransfer

The core message for customer credit transfers.

Used for:

  • Single customer payments
  • Cross-border transfers
  • Domestic high-value payments

Key elements:

  • Group Header (GrpHdr)
  • Credit Transfer Transaction Information (CdtTrfTxInf)
  • Payment Identification
  • Interbank Settlement Amount
  • Debtor/Creditor Information
  • Agent Chain

pacs.009 - FIToFIFinancialInstitutionCreditTransfer

Bank-to-bank transfers for treasury operations.

Used for:

  • Bank treasury movements
  • Cover payments
  • Nostro/Vostro movements

Key elements:

  • Group Header
  • Credit Transfer Transaction Information
  • Underlying Customer Credit Transfer (for covers)

camt.056 - FIToFIPaymentCancellationRequest

Request to cancel a previously sent payment.

Used for:

  • Duplicate payment recall
  • Fraudulent payment recall
  • Technical error correction

Key elements:

  • Assignment information
  • Original message details
  • Cancellation reason

Version Support

The CBPR+ package supports the latest ISO 20022 message versions:

MessageVersion
head.001001.03
pacs.002001.14
pacs.004001.13
pacs.008001.12
pacs.009001.11
camt.029001.13
camt.052001.12
camt.053001.12
camt.054001.12
camt.056001.12

MT → ISO 20022 Details →

ISO 20022 → MT Details →

MT to ISO 20022 Transformations

Converting SWIFT MT messages to ISO 20022 format.

Overview

Outgoing transformations convert legacy SWIFT MT messages to ISO 20022 XML format. This is the primary direction for institutions migrating to ISO 20022 for cross-border payments.

Transformation Pipeline

Every MT → ISO 20022 transformation follows this pipeline:

┌─────────────────────────────────────────────────────────────┐
│                    MT → ISO 20022 Pipeline                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. Parse MT              Priority 1                        │
│     Extract blocks, tags, and field values                  │
│                                                             │
│  2. Detect Message Type   Priority 2                        │
│     Identify MT variant (standard, STP, REJT, RETN)         │
│                                                             │
│  3. Map BAH               Priority 3                        │
│     Create Business Application Header from MT headers      │
│                                                             │
│  4. Pre-conditions        Priority 4                        │
│     Validate business rules before transformation           │
│                                                             │
│  5. Map Document          Priority 5                        │
│     Transform MT fields to ISO 20022 document structure     │
│                                                             │
│  6. Post-conditions       Priority 6                        │
│     Validate output compliance                              │
│                                                             │
│  7. Combine XML           Priority 10                       │
│     Generate final ISO 20022 XML envelope                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Supported Transformations

Customer Payments

SourceTargetDescriptionDetails
MT103pacs.008Customer Credit TransferView →
MT103 STPpacs.008Straight-Through Processing
MT103 REJTpacs.002Payment Rejection
MT103 RETNpacs.004Payment Return

Financial Institution Transfers

SourceTargetDescription
MT200pacs.009Own Account Transfer
MT202pacs.009General FI Transfer
MT202 COVpacs.009Cover Payment
MT202 REJTpacs.002FI Transfer Rejection
MT202 RETNpacs.004FI Transfer Return
MT205pacs.009Third Party FI Transfer
MT205 COVpacs.009Cover Payment (Third Party)

Cancellation & Investigation

SourceTargetDescription
MT192camt.056Customer Payment Cancellation
MT196camt.029Cancellation Response
MT292camt.056FI Payment Cancellation
MT296camt.029FI Cancellation Response

Cash Management

SourceTargetDescription
MT900camt.054Debit Confirmation
MT910camt.054Credit Confirmation

Common Field Mappings

These mappings apply across multiple MT → ISO 20022 transformations:

Header Mappings

MT SourceISO 20022 TargetDescription
Block 1 BICAppHdr/Fr/FIId/FinInstnId/BICFISender identification
Block 2 BICAppHdr/To/FIId/FinInstnId/BICFIReceiver identification
Tag 20AppHdr/BizMsgIdrMessage identifier
Tag 121 (Block 3)PmtId/UETREnd-to-end tracking

Amount Mappings

MT SourceISO 20022 TargetNotes
Tag 32A DateIntrBkSttlmDtYYMMDD → YYYY-MM-DD
Tag 32A CurrencyIntrBkSttlmAmt/@Ccy3-letter code
Tag 32A AmountIntrBkSttlmAmtRemove comma separator

Party Mappings

MT SourceISO 20022 TargetNotes
Tag 50K/50FDbtrOrdering customer
Tag 50K AccountDbtrAcct/Id/Othr/IdAccount number
Tag 59/59ACdtrBeneficiary
Tag 59 AccountCdtrAcct/Id/Othr/IdAccount number

Agent Mappings

MT SourceISO 20022 TargetNotes
Tag 52ADbtrAgtDebtor’s bank
Tag 53A/53BInstgAgt or IntrmyAgt1Intermediary
Tag 54AIntrmyAgt1Intermediary
Tag 57ACdtrAgtCreditor’s bank

Charge Bearer Mapping

MT (Tag 71A)ISO 20022Code
SHASHARShared
OURDEBTAll charges to debtor
BENCREDAll charges to creditor

Business Rules

Service Level Determination

The CBPR+ service level is determined from MT fields:

{
  "if": [
    {"==": [{"var": "fields.23E.instruction_code"}, "URGP"]},
    "G001",
    {"if": [
      {"==": [{"var": "fields.23B.bank_operation_code"}, "SPAY"]},
      "G003",
      "G002"
    ]}
  ]
}
MT IndicatorService LevelPriority
23E: URGPG001Urgent
23B: SPAYG003Same-day
DefaultG002Normal

UETR Handling

If Tag 121 exists in Block 3, it’s used as the UETR. Otherwise, a new UUID is generated.

Date Conversion

MT dates (YYMMDD) are converted to ISO format (YYYY-MM-DD):

MTISO 20022
2501152025-01-15
9912312099-12-31

Example Transformation

Input: MT103

{1:F01BNPAFRPPXXX0000000000}
{2:I103DEUTDEFFXXXXN}
{3:{121:174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a}}
{4:
:20:REF123456
:23B:CRED
:32A:250115USD50000,00
:50K:/12345678
ACME CORPORATION
:59:/98765432
GLOBAL TRADING LTD
:71A:SHA
-}

Output: pacs.008

<?xml version="1.0"?>
<BizMsg xmlns="urn:iso:std:iso:20022:tech:xsd:head.001.001.03">
  <AppHdr>
    <Fr><FIId><FinInstnId><BICFI>BNPAFRPPXXX</BICFI></FinInstnId></FIId></Fr>
    <To><FIId><FinInstnId><BICFI>DEUTDEFFXXX</BICFI></FinInstnId></FIId></To>
    <BizMsgIdr>REF123456</BizMsgIdr>
    <MsgDefIdr>pacs.008.001.12</MsgDefIdr>
  </AppHdr>
  <Document xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.12">
    <FIToFICstmrCdtTrf>
      <CdtTrfTxInf>
        <PmtId>
          <InstrId>REF123456</InstrId>
          <UETR>174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a</UETR>
        </PmtId>
        <IntrBkSttlmAmt Ccy="USD">50000.00</IntrBkSttlmAmt>
        <IntrBkSttlmDt>2025-01-15</IntrBkSttlmDt>
        <ChrgBr>SHAR</ChrgBr>
        <Dbtr><Nm>ACME CORPORATION</Nm></Dbtr>
        <DbtrAcct><Id><Othr><Id>12345678</Id></Othr></Id></DbtrAcct>
        <Cdtr><Nm>GLOBAL TRADING LTD</Nm></Cdtr>
        <CdtrAcct><Id><Othr><Id>98765432</Id></Othr></Id></CdtrAcct>
      </CdtTrfTxInf>
    </FIToFICstmrCdtTrf>
  </Document>
</BizMsg>

Try It


MT103 → pacs.008 Details →

Back to CBPR+ Overview →

MT103 → pacs.008 Transformation

Complete guide to transforming SWIFT MT103 to ISO 20022 pacs.008.

Overview

MT103 (Single Customer Credit Transfer) is the most common SWIFT message type. It transforms to pacs.008 (FIToFICustomerCreditTransfer) in ISO 20022.

AttributeValue
Source MessageMT103
Target Messagepacs.008.001.12
DirectionOutgoing (MT → MX)
CategoryCustomer Payments
SR2025Fully compliant

Message Structure Comparison

MT103 Structure

{1:F01...}           Basic Header
{2:I103...}          Application Header
{3:{121:...}}        User Header (UETR)
{4:                  Text Block
:20:                 Transaction Reference
:23B:                Bank Operation Code
:32A:                Value Date/Currency/Amount
:50K:                Ordering Customer
:52A:                Ordering Institution
:53A:                Sender's Correspondent
:54A:                Receiver's Correspondent
:56A:                Intermediary
:57A:                Account With Institution
:59:                 Beneficiary
:70:                 Remittance Information
:71A:                Details of Charges
:71F:                Sender's Charges
:71G:                Receiver's Charges
:72:                 Sender to Receiver Info
:77B:                Regulatory Reporting
-}

pacs.008 Structure

<Document>
  <FIToFICstmrCdtTrf>
    <GrpHdr>                    Group Header
      <MsgId>                   Message Identification
      <CreDtTm>                 Creation Date Time
      <NbOfTxs>                 Number of Transactions
      <SttlmInf>                Settlement Information
    </GrpHdr>
    <CdtTrfTxInf>               Credit Transfer Transaction
      <PmtId>                   Payment Identification
      <PmtTpInf>                Payment Type Information
      <IntrBkSttlmAmt>          Interbank Settlement Amount
      <IntrBkSttlmDt>           Interbank Settlement Date
      <ChrgBr>                  Charge Bearer
      <Dbtr>                    Debtor
      <DbtrAcct>                Debtor Account
      <DbtrAgt>                 Debtor Agent
      <CdtrAgt>                 Creditor Agent
      <Cdtr>                    Creditor
      <CdtrAcct>                Creditor Account
      <RmtInf>                  Remittance Information
    </CdtTrfTxInf>
  </FIToFICstmrCdtTrf>
</Document>

Complete Field Mapping Table

Header Mappings

MT FieldISO 20022 PathRuleExample
Block 1 BICAppHdr/Fr/FIId/FinInstnId/BICFIDirectBNPAFRPPXXX
Block 2 BICAppHdr/To/FIId/FinInstnId/BICFIDirectDEUTDEFFXXX
Tag 20AppHdr/BizMsgIdrDirectREF123456
Tag 20GrpHdr/MsgIdDirectREF123456
Tag 20PmtId/InstrIdDirectREF123456
Tag 121PmtId/UETRDirectUUID

Amount & Date Mappings

MT FieldISO 20022 PathRuleExample
Tag 32A (date)IntrBkSttlmDtYYMMDD → YYYY-MM-DD250115 → 2025-01-15
Tag 32A (currency)IntrBkSttlmAmt/@CcyDirectUSD
Tag 32A (amount)IntrBkSttlmAmtRemove comma50000,00 → 50000.00
Tag 33B (currency)InstdAmt/@CcyDirectEUR
Tag 33B (amount)InstdAmtRemove comma45000,00 → 45000.00
Tag 36XchgRateDirect1.1234

Ordering Customer (Debtor) Mappings

MT FieldISO 20022 PathNotes
Tag 50K Line 1 (with /)DbtrAcct/Id/Othr/IdAccount number
Tag 50K NameDbtr/NmCustomer name
Tag 50K AddressDbtr/PstlAdr/AdrLineAddress lines
Tag 50F /1Dbtr/NmStructured name
Tag 50F /2Dbtr/PstlAdr/StrtNmStreet
Tag 50F /3Dbtr/PstlAdr/TwnNmTown
Tag 50F /4Dbtr/PstlAdr/CtryCountry

Beneficiary (Creditor) Mappings

MT FieldISO 20022 PathNotes
Tag 59 Line 1 (with /)CdtrAcct/Id/Othr/IdAccount number
Tag 59 NameCdtr/NmBeneficiary name
Tag 59 AddressCdtr/PstlAdr/AdrLineAddress lines
Tag 59ACdtr/Id/OrgId/AnyBICBIC identification
Tag 59F /1Cdtr/NmStructured name

Agent (Bank) Mappings

MT FieldISO 20022 PathNotes
Tag 52ADbtrAgt/FinInstnId/BICFIOrdering institution
Tag 52DDbtrAgt/FinInstnId/Nm + PstlAdrName and address
Tag 53AInstgAgt/FinInstnId/BICFISender’s correspondent
Tag 53BInstgAgt/FinInstnId/ClrSysMmbIdClearing system
Tag 54AIntrmyAgt1/FinInstnId/BICFIReceiver’s correspondent
Tag 56AIntrmyAgt2/FinInstnId/BICFIIntermediary
Tag 57ACdtrAgt/FinInstnId/BICFIAccount with institution
Tag 57DCdtrAgt/FinInstnId/Nm + PstlAdrName and address

Charges Mappings

MT FieldISO 20022 PathMapping
Tag 71A: SHAChrgBrSHAR
Tag 71A: OURChrgBrDEBT
Tag 71A: BENChrgBrCRED
Tag 71FChrgsInf/Amt + AgtSender’s charges
Tag 71GChrgsInf/Amt + AgtReceiver’s charges

Remittance & Regulatory

MT FieldISO 20022 PathNotes
Tag 70RmtInf/UstrdUnstructured remittance
Tag 72InstrForCdtrAgtSender to receiver info
Tag 77BRgltryRptgRegulatory reporting

Business Rules Applied

Service Level Determination

{
  "path": "data.output.PmtTpInf.SvcLvl.Cd",
  "logic": {
    "if": [
      {"==": [{"var": "data.SwiftMT.fields.23E.instruction_code"}, "URGP"]},
      "G001",
      {"if": [
        {"==": [{"var": "data.SwiftMT.fields.23B.bank_operation_code"}, "SPAY"]},
        "G003",
        "G002"
      ]}
    ]
  }
}

Settlement Method

{
  "path": "data.output.GrpHdr.SttlmInf.SttlmMtd",
  "logic": {
    "if": [
      {"!!": {"var": "data.SwiftMT.fields.53A"}},
      "COVE",
      "INDA"
    ]
  }
}

Charge Bearer Conversion

{
  "path": "data.output.ChrgBr",
  "logic": {
    "if": [
      {"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "SHA"]},
      "SHAR",
      {"if": [
        {"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "OUR"]},
        "DEBT",
        "CRED"
      ]}
    ]
  }
}

Complete Example

Input: MT103

{1:F01BNPAFRPPXXX0000000000}
{2:I103DEUTDEFFXXXXN}
{3:{121:174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a}}
{4:
:20:REF123456789
:23B:CRED
:32A:250115USD50000,00
:50K:/12345678901234
ACME INTERNATIONAL CORP
123 BUSINESS AVENUE
NEW YORK NY 10001
:52A:CITIUS33XXX
:57A:COBADEFFXXX
:59:/DE89370400440532013000
GLOBAL TRADING GMBH
MUSTERSTRASSE 123
60329 FRANKFURT
:70:/INV/2025-001
PAYMENT FOR INVOICE
:71A:SHA
:72:/REC/PAYMENT
-}

Output: pacs.008

<?xml version="1.0" encoding="UTF-8"?>
<BizMsg xmlns="urn:iso:std:iso:20022:tech:xsd:head.001.001.03">
  <AppHdr>
    <Fr>
      <FIId>
        <FinInstnId>
          <BICFI>BNPAFRPPXXX</BICFI>
        </FinInstnId>
      </FIId>
    </Fr>
    <To>
      <FIId>
        <FinInstnId>
          <BICFI>DEUTDEFFXXX</BICFI>
        </FinInstnId>
      </FIId>
    </To>
    <BizMsgIdr>REF123456789</BizMsgIdr>
    <MsgDefIdr>pacs.008.001.12</MsgDefIdr>
    <CreDt>2025-01-15T10:30:00Z</CreDt>
  </AppHdr>
  <Document xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.12">
    <FIToFICstmrCdtTrf>
      <GrpHdr>
        <MsgId>REF123456789</MsgId>
        <CreDtTm>2025-01-15T10:30:00Z</CreDtTm>
        <NbOfTxs>1</NbOfTxs>
        <SttlmInf>
          <SttlmMtd>INDA</SttlmMtd>
        </SttlmInf>
      </GrpHdr>
      <CdtTrfTxInf>
        <PmtId>
          <InstrId>REF123456789</InstrId>
          <EndToEndId>REF123456789</EndToEndId>
          <UETR>174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a</UETR>
        </PmtId>
        <PmtTpInf>
          <SvcLvl>
            <Cd>G002</Cd>
          </SvcLvl>
        </PmtTpInf>
        <IntrBkSttlmAmt Ccy="USD">50000.00</IntrBkSttlmAmt>
        <IntrBkSttlmDt>2025-01-15</IntrBkSttlmDt>
        <ChrgBr>SHAR</ChrgBr>
        <Dbtr>
          <Nm>ACME INTERNATIONAL CORP</Nm>
          <PstlAdr>
            <AdrLine>123 BUSINESS AVENUE</AdrLine>
            <AdrLine>NEW YORK NY 10001</AdrLine>
          </PstlAdr>
        </Dbtr>
        <DbtrAcct>
          <Id>
            <Othr>
              <Id>12345678901234</Id>
            </Othr>
          </Id>
        </DbtrAcct>
        <DbtrAgt>
          <FinInstnId>
            <BICFI>CITIUS33XXX</BICFI>
          </FinInstnId>
        </DbtrAgt>
        <CdtrAgt>
          <FinInstnId>
            <BICFI>COBADEFFXXX</BICFI>
          </FinInstnId>
        </CdtrAgt>
        <Cdtr>
          <Nm>GLOBAL TRADING GMBH</Nm>
          <PstlAdr>
            <AdrLine>MUSTERSTRASSE 123</AdrLine>
            <AdrLine>60329 FRANKFURT</AdrLine>
          </PstlAdr>
        </Cdtr>
        <CdtrAcct>
          <Id>
            <IBAN>DE89370400440532013000</IBAN>
          </Id>
        </CdtrAcct>
        <InstrForCdtrAgt>
          <InstrInf>PAYMENT</InstrInf>
        </InstrForCdtrAgt>
        <RmtInf>
          <Ustrd>/INV/2025-001 PAYMENT FOR INVOICE</Ustrd>
        </RmtInf>
      </CdtTrfTxInf>
    </FIToFICstmrCdtTrf>
  </Document>
</BizMsg>

Variants

MT103 STP

Straight-Through Processing variant with BIC-only agent identification:

  • Same mapping as standard MT103
  • Tag 119: STP in Block 3
  • All agents identified by BIC (no name/address)

MT103 REJT

Payment rejection (transformed to pacs.002):

  • Block 2 contains 103 with REJT indicator
  • Includes original message reference
  • Rejection reason code

MT103 RETN

Payment return (transformed to pacs.004):

  • Indicates returned payment
  • Contains reason for return
  • May include charges information

Try It

API Example

curl -X POST http://localhost:3000/api/transform \
  -H "Content-Type: application/json" \
  -d '{
    "message": "{1:F01BNPAFRPPXXX0000000000}{2:I103DEUTDEFFXXXXN}{3:{121:174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a}}{4:\n:20:REF123456789\n:23B:CRED\n:32A:250115USD50000,00\n:50K:/12345678901234\nACME INTERNATIONAL CORP\n:59:/DE89370400440532013000\nGLOBAL TRADING GMBH\n:71A:SHA\n-}",
    "validation": true
  }'

Back to MT → ISO 20022 Overview →

View Message Catalog →

ISO 20022 to MT Transformations

Converting ISO 20022 messages to SWIFT MT format.

Overview

Incoming transformations convert ISO 20022 XML messages to legacy SWIFT MT format. This direction supports:

  • Systems that haven’t migrated to ISO 20022
  • Legacy downstream applications
  • Parallel running during migration
  • Fallback scenarios

Transformation Pipeline

Every ISO 20022 → MT transformation follows this pipeline:

┌─────────────────────────────────────────────────────────────┐
│                  ISO 20022 → MT Pipeline                    │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. Parse XML             Priority 1                        │
│     Extract ISO 20022 structure to JSON                     │
│                                                             │
│  2. Detect Target MT      Priority 2                        │
│     Determine appropriate MT message type                   │
│                                                             │
│  3. Pre-conditions        Priority 3                        │
│     Validate transformation feasibility                     │
│                                                             │
│  4. Map Headers           Priority 4                        │
│     Construct MT Block 1, 2, 3                              │
│                                                             │
│  5. Map Fields            Priority 5-9                      │
│     Transform ISO 20022 elements to MT tags                 │
│                                                             │
│  6. Post-conditions       Priority 10                       │
│     Validate MT structure and assemble                      │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Supported Transformations

Payment Messages

SourceTargetDescription
pain.001MT101Customer Credit Transfer Initiation
pacs.002MT103 REJT / MT202 REJTPayment Status Report
pacs.003MT104Direct Debit
pacs.004MT103 RETN / MT202 RETNPayment Return
pacs.008MT103Customer Credit Transfer
pacs.009MT202 / MT202 COV / MT205FI Credit Transfer
pacs.010MT204Financial Institution Direct Debit

Cash Management Messages

SourceTargetDescription
camt.029MT196 / MT296Resolution of Investigation
camt.052MT942 / MT941Account Report
camt.053MT940Bank Statement
camt.054MT900 / MT910Debit/Credit Notification
camt.056MT192 / MT292Cancellation Request
camt.057MT210Notification to Receive

SR2025 Messages

SourceTargetDescription
camt.105MTn90Charges Payment Notification
camt.106MTn91Charges Payment Request
camt.107MT110Cheque Presentation
camt.108MT111Cheque Cancellation Request
camt.109MT112Cheque Cancellation Report
admi.024MT199System Event Notification

Target MT Detection

The target MT type is determined by analyzing the ISO 20022 message:

pacs.008 → MT Detection

{
  "if": [
    {"!!": {"var": "data.MX.UndrlygCstmrCdtTrf"}},
    "MT103",
    {"if": [
      {"==": [{"var": "data.MX.PmtTpInf.LclInstrm.Prtry"}, "COVER"]},
      "MT202COV",
      "MT103"
    ]}
  ]
}

pacs.009 → MT Detection

ConditionTarget MT
Has UnderlyingCustomerCreditTransferMT202 COV
InterbankSettlement onlyMT202
Third party indicatorMT205

camt.054 → MT Detection

ConditionTarget MT
Debit entryMT900
Credit entryMT910
Multiple entriesMultiple MTs

Common Field Mappings

Header Generation

ISO 20022 SourceMT TargetNotes
AppHdr/Fr/FIId/FinInstnId/BICFIBlock 1 BICSender
AppHdr/To/FIId/FinInstnId/BICFIBlock 2 BICReceiver
PmtId/UETRBlock 3 Tag 121End-to-end tracking
AppHdr/BizMsgIdrTag 20Reference

Amount Mapping

ISO 20022 SourceMT TargetNotes
IntrBkSttlmDtTag 32A (date)YYYY-MM-DD → YYMMDD
IntrBkSttlmAmt/@CcyTag 32A (currency)3-letter code
IntrBkSttlmAmtTag 32A (amount)Add comma separator

Party Mapping

ISO 20022 SourceMT TargetNotes
Dbtr/NmTag 50K Line 1Debtor name
Dbtr/PstlAdr/AdrLineTag 50K Lines 2-4Address
DbtrAcct/Id/IBANTag 50K AccountWith / prefix
DbtrAcct/Id/Othr/IdTag 50K AccountWith / prefix
Cdtr/NmTag 59 Line 1Creditor name
CdtrAcct/Id/IBANTag 59 AccountWith / prefix

Agent Mapping

ISO 20022 SourceMT TargetNotes
DbtrAgt/FinInstnId/BICFITag 52ADebtor’s bank
CdtrAgt/FinInstnId/BICFITag 57ACreditor’s bank
IntrmyAgt1/FinInstnId/BICFITag 56AIntermediary

Charge Bearer Mapping

ISO 20022MT (Tag 71A)
SHARSHA
DEBTOUR
CREDBEN

Data Truncation Rules

MT messages have field length limits. ISO 20022 data is truncated when necessary:

MT FieldMax LengthTruncation Rule
Tag 2016 charsTruncate right
Tag 50K/59 name35 charsTruncate right
Tag 50K/59 address35 chars/lineTruncate per line
Tag 704 x 35 charsTruncate total
Tag 726 x 35 charsTruncate total

Example Transformation

Input: pacs.008

<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.12">
  <FIToFICstmrCdtTrf>
    <GrpHdr>
      <MsgId>MSG123456789</MsgId>
      <CreDtTm>2025-01-15T10:30:00Z</CreDtTm>
      <NbOfTxs>1</NbOfTxs>
      <SttlmInf><SttlmMtd>INDA</SttlmMtd></SttlmInf>
    </GrpHdr>
    <CdtTrfTxInf>
      <PmtId>
        <InstrId>INSTR123</InstrId>
        <EndToEndId>E2E123</EndToEndId>
        <UETR>174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a</UETR>
      </PmtId>
      <IntrBkSttlmAmt Ccy="EUR">25000.00</IntrBkSttlmAmt>
      <IntrBkSttlmDt>2025-01-15</IntrBkSttlmDt>
      <ChrgBr>SHAR</ChrgBr>
      <Dbtr><Nm>SENDER COMPANY</Nm></Dbtr>
      <DbtrAcct><Id><IBAN>FR7630006000011234567890189</IBAN></Id></DbtrAcct>
      <DbtrAgt><FinInstnId><BICFI>BNPAFRPPXXX</BICFI></FinInstnId></DbtrAgt>
      <CdtrAgt><FinInstnId><BICFI>DEUTDEFFXXX</BICFI></FinInstnId></CdtrAgt>
      <Cdtr><Nm>RECEIVER GMBH</Nm></Cdtr>
      <CdtrAcct><Id><IBAN>DE89370400440532013000</IBAN></Id></CdtrAcct>
    </CdtTrfTxInf>
  </FIToFICstmrCdtTrf>
</Document>

Output: MT103

{1:F01BNPAFRPPXXX0000000000}
{2:I103DEUTDEFFXXXXN}
{3:{121:174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a}}
{4:
:20:INSTR123
:23B:CRED
:32A:250115EUR25000,00
:50K:/FR7630006000011234567890189
SENDER COMPANY
:57A:DEUTDEFFXXX
:59:/DE89370400440532013000
RECEIVER GMBH
:71A:SHA
-}

Try It

API Example

curl -X POST http://localhost:3000/api/transform \
  -H "Content-Type: application/json" \
  -d '{
    "message": "<?xml version=\"1.0\"?><Document xmlns=\"urn:iso:std:iso:20022:tech:xsd:pacs.008.001.12\">...</Document>"
  }'

The API automatically detects ISO 20022 input and applies the appropriate reverse transformation.


Back to CBPR+ Overview →

View Message Catalog →

SR2025 Compliance

SWIFT Standards Release 2025 compliance in Reframe.

Overview

SR2025 (Standards Release 2025) is SWIFT’s mandatory update that becomes effective in November 2025. It introduces:

  • Updated ISO 20022 message versions
  • Business Application Header v3
  • Enhanced data requirements
  • New message types for cash management

Reframe’s CBPR+ package is fully SR2025 compliant.

Message Version Support

Payment Messages

MessageSR2025 VersionPrevious Version
pacs.002001.14001.12
pacs.004001.13001.11
pacs.008001.12001.10
pacs.009001.11001.09
pacs.010001.06001.04

Cash Management Messages

MessageSR2025 VersionPrevious Version
camt.029001.13001.11
camt.052001.12001.10
camt.053001.12001.10
camt.054001.12001.10
camt.056001.12001.10
camt.057001.08001.06

New SR2025 Messages

MessageVersionDescription
camt.105001.02Charges Payment Notification
camt.106001.02Charges Payment Request
camt.107001.02Cheque Presentation Notification
camt.108001.02Cheque Cancellation or Stop Request
camt.109001.02Cheque Cancellation or Stop Report
admi.024001.01System Event Notification

Business Application Header v3

SR2025 uses BAH version 3 (head.001.001.03) with enhanced features:

<AppHdr xmlns="urn:iso:std:iso:20022:tech:xsd:head.001.001.03">
  <Fr>
    <FIId>
      <FinInstnId>
        <BICFI>BNPAFRPPXXX</BICFI>
        <LEI>9695005MSX1OYEMGDF46</LEI>
      </FinInstnId>
    </FIId>
  </Fr>
  <To>
    <FIId>
      <FinInstnId>
        <BICFI>DEUTDEFFXXX</BICFI>
        <LEI>7LTWFZYICNSX8D621K86</LEI>
      </FinInstnId>
    </FIId>
  </To>
  <BizMsgIdr>MSG123456789</BizMsgIdr>
  <MsgDefIdr>pacs.008.001.12</MsgDefIdr>
  <BizSvc>swift.cbprplus.02</BizSvc>
  <CreDt>2025-01-15T10:30:00Z</CreDt>
  <Prty>NORM</Prty>
</AppHdr>

BAH v3 Enhancements

FieldDescriptionNotes
LEILegal Entity Identifier20-character code
BizSvcBusiness ServiceCBPR+ service identifier
PrtyPriorityHIGH, NORM, or empty
PssblDplctPossible DuplicateBoolean flag

UETR Requirements

The UETR (Unique End-to-End Transaction Reference) is mandatory for all CBPR+ payments:

Format

  • UUID version 4
  • 36 characters including hyphens
  • Example: 174d2c70-7a8c-4c0d-8b2e-5c2a9f8e6d3a

In Messages

  • ISO 20022: PmtId/UETR
  • SWIFT MT: Block 3, Tag 121

Reframe Handling

{
  "path": "data.output.PmtId.UETR",
  "logic": {
    "or": [
      {"var": "data.SwiftMT.block3.121"},
      {"uuid": []}
    ]
  }
}

If the source MT message contains Tag 121, it’s preserved. Otherwise, a new UUID is generated.

Enhanced Party Identification

SR2025 requires richer party identification:

<Dbtr>
  <Nm>ACME CORPORATION</Nm>
  <Id>
    <OrgId>
      <LEI>5493001KJTIIGC8Y1R12</LEI>
    </OrgId>
  </Id>
</Dbtr>

BIC + BEI Identification

<DbtrAgt>
  <FinInstnId>
    <BICFI>BNPAFRPPXXX</BICFI>
  </FinInstnId>
</DbtrAgt>

Structured Address

SR2025 encourages structured addresses over free-form:

<PstlAdr>
  <StrtNm>123 MAIN STREET</StrtNm>
  <BldgNb>SUITE 500</BldgNb>
  <PstCd>10001</PstCd>
  <TwnNm>NEW YORK</TwnNm>
  <CtrySubDvsn>NY</CtrySubDvsn>
  <Ctry>US</Ctry>
</PstlAdr>

Service Level Codes

CBPR+ service levels for SR2025:

CodeNameDescriptionSLA
G001URGPUrgent PaymentImmediate
G002NURGNormal UrgentSame day
G003SDVASame Day ValueEnd of day
G004NORMNormalNext day

Mapping from MT

{
  "if": [
    {"==": [{"var": "fields.23E"}, "URGP"]},
    "G001",
    {"if": [
      {"==": [{"var": "fields.23B"}, "SPAY"]},
      "G003",
      "G002"
    ]}
  ]
}

Structured Remittance

SR2025 supports structured remittance information:

Structured Format

<RmtInf>
  <Strd>
    <RfrdDocInf>
      <Tp>
        <CdOrPrtry>
          <Cd>CINV</Cd>
        </CdOrPrtry>
      </Tp>
      <Nb>INV-2025-001234</Nb>
      <RltdDt>2025-01-10</RltdDt>
    </RfrdDocInf>
    <RfrdDocAmt>
      <DuePyblAmt Ccy="USD">50000.00</DuePyblAmt>
    </RfrdDocAmt>
  </Strd>
</RmtInf>

Document Types

CodeDescription
CINVCommercial Invoice
CRENCredit Note
DEBNDebit Note
SOACStatement of Account
DISPDispatch Advice

Regulatory Reporting

Enhanced regulatory reporting for SR2025:

<RgltryRptg>
  <DbtCdtRptgInd>DEBT</DbtCdtRptgInd>
  <Authrty>
    <Nm>CENTRAL BANK</Nm>
    <Ctry>US</Ctry>
  </Authrty>
  <Dtls>
    <Tp>CRED</Tp>
    <Cd>GOODS</Cd>
    <Amt Ccy="USD">50000.00</Amt>
    <Inf>PAYMENT FOR GOODS</Inf>
  </Dtls>
</RgltryRptg>

Validation Rules

Reframe enforces SR2025 validation rules:

Mandatory Fields

MessageRequired Fields
pacs.008UETR, IntrBkSttlmAmt, IntrBkSttlmDt, ChrgBr
pacs.009UETR, IntrBkSttlmAmt, IntrBkSttlmDt
camt.056OrgnlMsgId, OrgnlMsgNmId, CxlRsnInf

Format Validations

FieldRule
BIC8 or 11 characters
LEI20 characters
UETRUUID v4 format
IBANCountry-specific length
AmountMax 18 digits, 5 decimals

Coexistence Period

During the SR2025 migration, Reframe supports:

Bidirectional Translation

  • Convert MT messages to SR2025-compliant ISO 20022
  • Convert ISO 20022 back to MT for legacy systems

Version Handling

  • Accept older ISO 20022 versions
  • Output latest SR2025 versions
  • Preserve data through translation

Feature Degradation

  • LEI stripped when converting to MT
  • Structured addresses converted to free-form
  • Structured remittance converted to unstructured

Testing SR2025 Compliance

Generate SR2025 Messages

curl -X POST http://localhost:3000/api/generate \
  -H "Content-Type: application/json" \
  -d '{"message_type": "pacs.008", "scenario": "sr2025_standard"}'

Validate SR2025 Compliance

curl -X POST http://localhost:3000/api/validate \
  -H "Content-Type: application/json" \
  -d '{
    "message": "<ISO 20022 message>",
    "business_validation": true
  }'

Back to CBPR+ Overview →

View Message Catalog →

Sample Generation

Generate valid test messages for development, testing, and certification.

Overview

Reframe can generate sample SWIFT MT and ISO 20022 messages for any supported message type. Generated messages are:

  • Valid: Pass schema and business validation
  • Realistic: Use plausible data values
  • Configurable: Multiple scenarios per message type
  • Reproducible: Same scenario produces consistent structure

API Usage

Generate a Sample Message

curl -X POST http://localhost:3000/api/generate \
  -H "Content-Type: application/json" \
  -d '{
    "message_type": "MT103",
    "scenario": "standard"
  }'

Response

{
  "status": "success",
  "message_type": "MT103",
  "scenario": "standard",
  "message": "{1:F01BNPAFRPPXXX0000000000}{2:I103DEUTDEFFXXXXN}...",
  "metadata": {
    "generated_at": "2025-01-15T10:30:00Z",
    "package": "swift-cbpr-mt-mx",
    "version": "2.1.2"
  }
}

Supported Types

For the complete list of supported message types and scenarios, see Generate API Reference →

Scenarios

Scenarios define different variations of a message type:

MT103 Scenarios

standard: Basic customer credit transfer

{"message_type": "MT103", "scenario": "standard"}

high_value: Large amount transfer with additional details

{"message_type": "MT103", "scenario": "high_value"}

remittance: Includes detailed remittance information

{"message_type": "MT103", "scenario": "remittance"}

pacs.008 Scenarios

standard: Basic ISO 20022 credit transfer

{"message_type": "pacs.008", "scenario": "standard"}

high_value: Large amount with full party details

{"message_type": "pacs.008", "scenario": "high_value"}

Data Generation

Sample messages use realistic generated data:

Financial Data

  • BICs: Valid SWIFT BIC codes
  • IBANs: Country-appropriate format
  • Amounts: Realistic ranges by scenario
  • Currencies: Major currencies (USD, EUR, GBP, etc.)

Party Information

  • Names: Company names for corporate payments
  • Addresses: Valid postal addresses
  • References: Realistic transaction references

Dates

  • Value Date: Near future dates
  • Creation Time: Current timestamp
  • Statement Dates: Recent date ranges

Use Cases

Development Testing

Generate messages for unit and integration tests:

# Generate test data for your test suite
curl -X POST http://localhost:3000/api/generate \
  -d '{"message_type": "MT103", "scenario": "standard"}' \
  > test_fixtures/mt103_sample.txt

SWIFT Certification

Generate valid messages for certification testing:

# Generate SR2025 compliant messages
curl -X POST http://localhost:3000/api/generate \
  -d '{"message_type": "pacs.008", "scenario": "sr2025_standard"}'

Demo and Training

Create realistic examples for demonstrations:

# Generate various message types
for type in MT103 MT202 MT940; do
  curl -X POST http://localhost:3000/api/generate \
    -d "{\"message_type\": \"$type\", \"scenario\": \"standard\"}" \
    > "samples/${type}.txt"
done

Transformation Testing

Generate source messages and verify transformation:

# Generate MT103
MT103=$(curl -s -X POST http://localhost:3000/api/generate \
  -d '{"message_type": "MT103", "scenario": "standard"}' | jq -r .message)

# Transform to pacs.008
curl -X POST http://localhost:3000/api/transform \
  -d "{\"message\": \"$MT103\"}"

Interactive Playground

Generate messages using the interactive playground:

Powered by Datafake

Sample generation uses Datafake, an open-source test data generation library. Datafake provides:

  • Faker.js compatible API
  • Deterministic output with seeds
  • Financial domain generators (BIC, IBAN, amounts)
  • Locale-aware data generation

API Reference →

Message Validation: SWIFT MT and ISO 20022

Validate SWIFT MT and ISO 20022 messages against schemas and business rules with the open source Reframe validation engine.

Overview

Reframe’s open source rules engine validates messages at multiple levels:

  1. Format Validation: Message structure and syntax
  2. Schema Validation: Field formats and required elements
  3. Business Validation: Package-specific business rules
  4. Custom Rules: User-defined validation rules via JSONLogic

API Usage

Basic Validation

curl -X POST http://localhost:3000/api/validate \
  -H "Content-Type: application/json" \
  -d '{
    "message": "{1:F01BNPAFRPPXXX...}",
    "business_validation": true
  }'

Response (Valid Message)

{
  "status": "valid",
  "message_type": "MT103",
  "format": "swift_mt",
  "validation": {
    "format": "passed",
    "schema": "passed",
    "business": "passed"
  },
  "timing_ms": 0.5
}

Response (Invalid Message)

{
  "status": "invalid",
  "message_type": "MT103",
  "format": "swift_mt",
  "validation": {
    "format": "passed",
    "schema": "failed",
    "business": "skipped"
  },
  "errors": [
    {
      "code": "FIELD_REQUIRED",
      "field": "32A",
      "message": "Tag 32A (Value Date/Currency/Amount) is required"
    },
    {
      "code": "INVALID_FORMAT",
      "field": "50K",
      "message": "Account number must start with /"
    }
  ]
}

Validation Options

OptionDefaultDescription
business_validationfalseEnable CBPR+ business rules
canonical_jsonfalseReturn parsed message as JSON
fail_fastfalseStop on first error

Full Options Example

curl -X POST http://localhost:3000/api/validate \
  -H "Content-Type: application/json" \
  -d '{
    "message": "...",
    "business_validation": true,
    "canonical_json": true,
    "fail_fast": false
  }'

Format Detection

Reframe automatically detects the message format:

PatternDetected Format
Starts with {1:SWIFT MT
Contains xmlns="urn:iso:std:iso:20022ISO 20022 XML
XML with BAHISO 20022 with header

SWIFT MT Validation

Block Structure

  • Block 1: Basic header format
  • Block 2: Application header format
  • Block 3: User header (optional)
  • Block 4: Text block with tags
  • Block 5: Trailer (optional)

Tag Validation

CheckDescription
Tag presenceRequired tags present
Tag formatCorrect format per tag
Tag sequenceTags in valid order
Tag lengthWithin max length

Example Errors

{
  "errors": [
    {
      "code": "BLOCK_STRUCTURE",
      "message": "Block 1 is malformed"
    },
    {
      "code": "MISSING_TAG",
      "field": "32A",
      "message": "Required tag 32A is missing"
    },
    {
      "code": "INVALID_BIC",
      "field": "52A",
      "message": "Invalid BIC format in tag 52A"
    }
  ]
}

ISO 20022 Validation

XML Schema Validation

  • Well-formed XML
  • Valid against XSD schema
  • Correct namespace declarations
  • Required elements present

Business Application Header

  • Valid sender/receiver BIC
  • Message definition identifier matches document
  • Creation date/time format

Document Validation

CheckDescription
Required elementsAll mandatory fields present
Data typesCorrect format (dates, amounts, codes)
EnumerationsValid code values
ConstraintsCross-field validations

Example Errors

{
  "errors": [
    {
      "code": "SCHEMA_VIOLATION",
      "path": "/Document/FIToFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmAmt",
      "message": "Currency attribute is required"
    },
    {
      "code": "INVALID_DATE",
      "path": "/Document/FIToFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmDt",
      "message": "Date must be in YYYY-MM-DD format"
    }
  ]
}

Business Validation

When business_validation: true, package-specific rules are applied.

CBPR+ Package Rules

Party Identification

  • Debtor/Creditor name required
  • Valid account formats
  • BIC format validation

Amount Rules

  • Positive amounts only
  • Currency code validation
  • Settlement date validation

Agent Chain

  • Valid BIC codes
  • Required agent information
  • Consistent agent chain

UETR Validation

  • UUID format check
  • Uniqueness (optional with persistence)

Canonical JSON Output

With canonical_json: true, the parsed message structure is returned:

SWIFT MT Canonical

{
  "canonical": {
    "basic_header": {
      "app_id": "F",
      "service_id": "01",
      "lt_address": "BNPAFRPPXXX"
    },
    "application_header": {
      "message_type": "103",
      "receiver_address": "DEUTDEFFXXX"
    },
    "fields": {
      "20": {"transaction_reference": "REF123456"},
      "32A": {
        "date": "250115",
        "currency": "USD",
        "amount": "50000,00"
      }
    }
  }
}

ISO 20022 Canonical

{
  "canonical": {
    "app_header": {
      "from": "BNPAFRPPXXX",
      "to": "DEUTDEFFXXX",
      "msg_def_id": "pacs.008.001.12"
    },
    "document": {
      "grp_hdr": {
        "msg_id": "MSG123",
        "cre_dt_tm": "2025-01-15T10:30:00Z"
      },
      "cdt_trf_tx_inf": {
        "pmt_id": {
          "instr_id": "INSTR123",
          "uetr": "174d2c70-..."
        }
      }
    }
  }
}

Error Codes

CodeDescription
PARSE_ERRORCannot parse message
BLOCK_STRUCTUREInvalid MT block structure
MISSING_TAGRequired tag missing
INVALID_FORMATField format error
INVALID_BICInvalid BIC code
INVALID_IBANInvalid IBAN
INVALID_AMOUNTAmount format error
INVALID_DATEDate format error
SCHEMA_VIOLATIONXML schema error
BUSINESS_RULEBusiness rule violation

Interactive Playground

Validate messages using the interactive playground:


Hot Reload: Update Rules Without Restart

Update SWIFT MT and ISO 20022 transformation rules in production without downtime or service interruption.

Overview

Hot reloading allows you to:

  • Update rules in production without downtime
  • Test new mappings without restart
  • Roll back changes quickly

Triggering a Reload

curl -X POST http://localhost:3000/admin/reload-workflows

Success Response:

{
  "status": "success",
  "message": "Workflows reloaded successfully",
  "package": {
    "id": "swift-cbpr-mt-mx",
    "version": "2.1.2",
    "workflows_loaded": 594
  },
  "timing_ms": 125
}

Error Response:

{
  "status": "error",
  "error": {
    "code": "COMPILATION_ERROR",
    "details": "Invalid JSONLogic in MT103/document-mapping.json"
  }
}

Behavior

PhaseBehavior
During reloadExisting requests continue; new requests may briefly queue
After reloadAll new requests use updated rules
On errorCurrent rules remain active; error returned

Development Workflow

Mount your package directory and iterate without restarts:

# docker-compose.yml
services:
  reframe:
    image: plasmatic/reframe:latest
    volumes:
      - ./my-package:/packages/custom
# Edit → Reload → Test cycle
vim my-package/transform/outgoing/MT103/document-mapping.json
curl -X POST http://localhost:3000/admin/reload-workflows
curl -X POST http://localhost:3000/api/transform -d '...'

CI/CD Integration

# GitHub Actions example
deploy-rules:
  steps:
    - run: scp -r rules/* server:/packages/swift-cbpr/
    - run: curl -X POST https://api.example.com/admin/reload-workflows
    - run: curl https://api.example.com/health

Best Practices

  1. Pre-validate: Test on staging before production reload
  2. Keep backups: cp -r /packages/swift-cbpr /packages/swift-cbpr.backup
  3. Version packages: Increment version in reframe-package.json on changes
  4. Monitor health: Check /health endpoint after reload

Monitoring

The health endpoint shows package info:

{
  "status": "healthy",
  "package": {
    "id": "swift-cbpr-mt-mx",
    "version": "2.1.2",
    "loaded_at": "2025-01-15T10:30:00Z"
  }
}

Custom Fields

Define package-specific computed fields for analytics and monitoring.

Overview

Custom fields allow you to extract and compute values from transformed messages for:

  • Analytics: Track transformation patterns
  • Filtering: Query messages by business attributes
  • Monitoring: Build dashboards and alerts
  • Compliance: Extract regulatory reporting data

How It Works

Custom fields are defined in api_config.json within your transformation package:

{
  "custom_fields": [
    {
      "name": "sender_country",
      "type": "string",
      "storage": "precompute",
      "logic": {
        "substr": [
          {"var": "context.data.sender_bic"},
          4,
          2
        ]
      }
    }
  ]
}

The Reframe engine evaluates these JSONLogic expressions after each transformation and stores the results.

Field Definition

Structure

{
  "name": "field_name",
  "type": "string | number | boolean",
  "storage": "precompute | runtime | hybrid",
  "logic": { /* JSONLogic expression */ },
  "description": "Optional field description"
}

Properties

PropertyRequiredDescription
nameYesUnique field identifier
typeYesData type: string, number, boolean
storageYesWhen to compute the field
logicYesJSONLogic expression
descriptionNoHuman-readable description

Storage Strategies

StrategyComputedStoredBest For
precomputeAt transformation timeYesFiltering, frequent queries
runtimeAt query timeNoTime-dependent values
hybridBothYesUpdateable computations

Example Custom Fields

Basic Extraction

Extract sender country from BIC:

{
  "name": "sender_country",
  "type": "string",
  "storage": "precompute",
  "logic": {
    "substr": [{"var": "context.data.sender_bic"}, 4, 2]
  }
}

Amount Banding

Categorize transactions by value:

{
  "name": "amount_band",
  "type": "string",
  "storage": "precompute",
  "logic": {
    "if": [
      {">": [{"var": "context.data.amount"}, 1000000]},
      "HIGH",
      {"if": [
        {">": [{"var": "context.data.amount"}, 100000]},
        "MEDIUM",
        "LOW"
      ]}
    ]
  }
}

Risk Scoring

Compute a risk score based on multiple factors:

{
  "name": "risk_score",
  "type": "number",
  "storage": "precompute",
  "logic": {
    "+": [
      {"if": [{">": [{"var": "context.data.amount"}, 500000]}, 30, 0]},
      {"if": [{"in": [{"var": "context.data.receiver_country"}, ["HR", "RS", "BY"]]}, 40, 0]},
      {"if": [{"!": {"var": "context.data.remittance_info"}}, 20, 0]},
      10
    ]
  }
}

Cross-Border Detection

Determine if payment is cross-border:

{
  "name": "is_cross_border",
  "type": "boolean",
  "storage": "precompute",
  "logic": {
    "!=": [
      {"substr": [{"var": "context.data.sender_bic"}, 4, 2]},
      {"substr": [{"var": "context.data.receiver_bic"}, 4, 2]}
    ]
  }
}

Processing Priority

Assign priority based on business rules:

{
  "name": "processing_priority",
  "type": "string",
  "storage": "precompute",
  "logic": {
    "if": [
      {"==": [{"var": "context.data.service_level"}, "G001"]},
      "CRITICAL",
      {"if": [
        {"or": [
          {">": [{"var": "context.data.amount"}, 1000000]},
          {"==": [{"var": "context.data.service_level"}, "G002"]}
        ]},
        "HIGH",
        "NORMAL"
      ]}
    ]
  }
}

Complete Configuration Example

// api_config.json
{
  "custom_fields": [
    {
      "name": "sender_name",
      "type": "string",
      "storage": "precompute",
      "logic": {"var": "context.data.debtor_name"}
    },
    {
      "name": "receiver_name",
      "type": "string",
      "storage": "precompute",
      "logic": {"var": "context.data.creditor_name"}
    },
    {
      "name": "amount",
      "type": "number",
      "storage": "precompute",
      "logic": {"var": "context.data.settlement_amount"}
    },
    {
      "name": "currency",
      "type": "string",
      "storage": "precompute",
      "logic": {"var": "context.data.settlement_currency"}
    },
    {
      "name": "sender_country",
      "type": "string",
      "storage": "precompute",
      "logic": {"substr": [{"var": "context.data.sender_bic"}, 4, 2]}
    },
    {
      "name": "receiver_country",
      "type": "string",
      "storage": "precompute",
      "logic": {"substr": [{"var": "context.data.receiver_bic"}, 4, 2]}
    },
    {
      "name": "is_cross_border",
      "type": "boolean",
      "storage": "precompute",
      "logic": {
        "!=": [
          {"substr": [{"var": "context.data.sender_bic"}, 4, 2]},
          {"substr": [{"var": "context.data.receiver_bic"}, 4, 2]}
        ]
      }
    },
    {
      "name": "amount_band",
      "type": "string",
      "storage": "precompute",
      "logic": {
        "if": [
          {">": [{"var": "context.data.settlement_amount"}, 1000000]},
          "HIGH",
          {"if": [
            {">": [{"var": "context.data.settlement_amount"}, 100000]},
            "MEDIUM",
            "LOW"
          ]}
        ]
      }
    }
  ]
}

Querying Custom Fields

GraphQL API

Query messages using custom fields:

query {
  messages(
    filter: {
      package_id: "swift-cbpr-mt-mx",
      custom_field_filters: {
        is_cross_border: true,
        amount_band: "HIGH",
        sender_country: "US"
      }
    },
    limit: 100
  ) {
    messages {
      id
      message_type
      direction
      custom_fields {
        sender_name
        receiver_name
        amount
        currency
        is_cross_border
        amount_band
      }
      created_at
    }
    total_count
  }
}

Aggregations

query {
  message_aggregations(
    package_id: "swift-cbpr-mt-mx",
    group_by: ["sender_country", "amount_band"],
    date_range: {
      start: "2025-01-01",
      end: "2025-01-31"
    }
  ) {
    groups {
      sender_country
      amount_band
      count
      total_amount
    }
  }
}

Context Variables

Custom fields have access to transformation context:

VariableDescription
context.data.*Parsed message data
context.metadata.*Message metadata
context.temp_data.*Intermediate values

Available Data Fields

The available context.data fields depend on the message type. Common fields include:

  • sender_bic, receiver_bic
  • debtor_name, creditor_name
  • settlement_amount, settlement_currency
  • value_date, settlement_date
  • message_type, direction
  • transaction_reference, uetr
  • service_level, charge_bearer

Best Practices

Naming Conventions

Use clear, consistent names:

  • sender_*, receiver_* for party data
  • is_* for boolean flags
  • *_date for dates
  • *_count for counts

Performance

  • Prefer precompute for frequently queried fields
  • Use runtime for time-dependent calculations
  • Keep expressions simple for better performance

Maintenance

  • Document each field’s purpose
  • Version your api_config.json
  • Test field logic with sample data

GraphQL API Reference →

JSONLogic Reference →

API Reference

Complete reference for the Reframe open source rules engine REST API.

Base URL

Sandbox: https://reframeapi.goplasmatic.io

Local: http://localhost:3000

Authentication

The sandbox API requires no authentication (rate limited). For production deployments, configure authentication as needed.

Endpoints

MethodEndpointDescription
POST/api/transformTransform messages between formats
POST/api/validateValidate MT or ISO 20022 messages
POST/api/generateGenerate sample messages
POST/admin/reload-workflowsHot reload transformation rules
GET/healthHealth check
GET/packagesList loaded packages
GET/swagger-uiInteractive API documentation
POST/graphqlGraphQL endpoint

Common Response Format

Success Response

{
  "status": "success",
  "message": "...",
  "timing_ms": 1.2,
  "metadata": {
    "package": "swift-cbpr-mt-mx",
    "version": "2.1.2"
  }
}

Error Response

{
  "status": "error",
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error message",
    "details": {}
  }
}

Error Codes

CodeHTTP StatusDescription
PARSE_ERROR400Cannot parse input message
VALIDATION_ERROR400Message validation failed
TRANSFORMATION_ERROR400Transformation failed
UNSUPPORTED_TYPE400Message type not supported
INTERNAL_ERROR500Internal server error

Request Headers

HeaderRequiredDescription
Content-TypeYesapplication/json
AcceptNoapplication/json (default)

Rate Limiting

Sandbox API:

  • 100 requests per minute per IP
  • 1000 requests per hour per IP

Rate limit headers in response:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1705312800

Quick Examples

Transform a Message

curl -X POST https://reframeapi.goplasmatic.io/api/transform \
  -H "Content-Type: application/json" \
  -d '{"message": "{1:F01BNPAFRPPXXX...}"}'

Validate a Message

curl -X POST https://reframeapi.goplasmatic.io/api/validate \
  -H "Content-Type: application/json" \
  -d '{"message": "...", "business_validation": true}'

Generate a Sample

curl -X POST https://reframeapi.goplasmatic.io/api/generate \
  -H "Content-Type: application/json" \
  -d '{"message_type": "MT103", "scenario": "standard"}'

Check Health

curl https://reframeapi.goplasmatic.io/health

OpenAPI / Swagger

Interactive API documentation is available at:

  • Sandbox: https://reframeapi.goplasmatic.io/swagger-ui
  • Local: http://localhost:3000/swagger-ui

Transform API →

Validate API →

Generate API →

Transform API

Transform messages between SWIFT MT and ISO 20022 formats.

Endpoint

POST /api/transform

Request

Headers

HeaderValue
Content-Typeapplication/json

Body

{
  "message": "string (required)",
  "validation": "boolean (optional, default: false)",
  "debug": "boolean (optional, default: false)",
  "metadata": "object (optional)"
}

Parameters

ParameterTypeRequiredDescription
messagestringYesThe message to transform (MT or ISO 20022)
validationbooleanNoValidate before and after transformation
debugbooleanNoInclude debug information in response
metadataobjectNoUser-provided metadata to include in response

Response

Success (200 OK)

{
  "status": "success",
  "direction": "outgoing",
  "source_type": "MT103",
  "target_type": "pacs.008.001.12",
  "message": "<transformed message>",
  "timing_ms": 1.2,
  "metadata": {
    "package": "swift-cbpr-mt-mx",
    "version": "2.1.2"
  }
}

With Debug (200 OK)

{
  "status": "success",
  "direction": "outgoing",
  "source_type": "MT103",
  "target_type": "pacs.008.001.12",
  "message": "<transformed message>",
  "timing_ms": 1.2,
  "debug": {
    "workflows_executed": [
      {"id": "parse-mt", "priority": 1, "timing_ms": 0.2},
      {"id": "mt103-bah-mapping", "priority": 3, "timing_ms": 0.3},
      {"id": "mt103-document-mapping", "priority": 5, "timing_ms": 0.5},
      {"id": "combine-xml", "priority": 10, "timing_ms": 0.2}
    ],
    "parsed_input": {...},
    "intermediate_values": {...}
  }
}

Validation Error (400 Bad Request)

{
  "status": "error",
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Input validation failed",
    "errors": [
      {
        "code": "MISSING_TAG",
        "field": "32A",
        "message": "Tag 32A is required"
      }
    ]
  }
}

Transformation Error (400 Bad Request)

{
  "status": "error",
  "error": {
    "code": "TRANSFORMATION_ERROR",
    "message": "Failed to transform message",
    "details": {
      "workflow": "mt103-document-mapping",
      "task": "map-amount",
      "reason": "Missing source field"
    }
  }
}

Auto-Detection

The API automatically detects:

Input PatternDetection
Starts with {1:SWIFT MT format
XML with ISO 20022 namespaceISO 20022 format
Block 2 message typeSpecific MT type (103, 202, etc.)
MsgDefIdr elementSpecific ISO 20022 type

Examples

MT103 to pacs.008

curl -X POST http://localhost:3000/api/transform \
  -H "Content-Type: application/json" \
  -d '{
    "message": "{1:F01BNPAFRPPXXX0000000000}{2:I103DEUTDEFFXXXXN}{3:{121:f47ac10b-58cc-4372-a567-0e02b2c3d479}}{4:\n:20:REF123456\n:23B:CRED\n:32A:250115USD50000,00\n:50K:/12345678\nACME CORP\n:59:/98765432\nGLOBAL LTD\n:71A:SHA\n-}"
  }'

pacs.008 to MT103

curl -X POST http://localhost:3000/api/transform \
  -H "Content-Type: application/json" \
  -d '{
    "message": "<?xml version=\"1.0\"?><Document xmlns=\"urn:iso:std:iso:20022:tech:xsd:pacs.008.001.12\">...</Document>"
  }'

With Validation

curl -X POST http://localhost:3000/api/transform \
  -H "Content-Type: application/json" \
  -d '{
    "message": "{1:F01BNPAFRPPXXX...}",
    "validation": true
  }'

With Debug

curl -X POST http://localhost:3000/api/transform \
  -H "Content-Type: application/json" \
  -d '{
    "message": "{1:F01BNPAFRPPXXX...}",
    "debug": true
  }'

With Metadata

curl -X POST http://localhost:3000/api/transform \
  -H "Content-Type: application/json" \
  -d '{
    "message": "{1:F01BNPAFRPPXXX...}",
    "metadata": {
      "request_id": "req-12345",
      "source_system": "payment-gateway"
    }
  }'

Supported Transformations

For the complete list of supported message transformations, see Message Catalog →


API Overview →

Try in Playground →

Validate API

Validate SWIFT MT and ISO 20022 messages.

Endpoint

POST /api/validate

Request

Headers

HeaderValue
Content-Typeapplication/json

Body

{
  "message": "string (required)",
  "business_validation": "boolean (optional, default: false)",
  "canonical_json": "boolean (optional, default: false)",
  "fail_fast": "boolean (optional, default: false)"
}

Parameters

ParameterTypeRequiredDescription
messagestringYesThe message to validate
business_validationbooleanNoApply CBPR+ business rules
canonical_jsonbooleanNoReturn parsed message structure
fail_fastbooleanNoStop on first validation error

Response

Valid Message (200 OK)

{
  "status": "valid",
  "message_type": "MT103",
  "format": "swift_mt",
  "validation": {
    "format": "passed",
    "schema": "passed",
    "business": "passed"
  },
  "timing_ms": 0.5
}

With Canonical JSON (200 OK)

{
  "status": "valid",
  "message_type": "MT103",
  "format": "swift_mt",
  "validation": {
    "format": "passed",
    "schema": "passed"
  },
  "canonical": {
    "basic_header": {
      "app_id": "F",
      "service_id": "01",
      "lt_address": "BNPAFRPPXXX"
    },
    "application_header": {
      "io_identifier": "I",
      "message_type": "103",
      "receiver_address": "DEUTDEFFXXX"
    },
    "user_header": {
      "121": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
    },
    "fields": {
      "20": {"transaction_reference": "REF123456"},
      "23B": {"bank_operation_code": "CRED"},
      "32A": {
        "date": "250115",
        "currency": "USD",
        "amount": "50000,00"
      },
      "50K": {
        "account": "12345678",
        "name": "ACME CORP"
      },
      "59": {
        "account": "98765432",
        "name": "GLOBAL LTD"
      },
      "71A": {"details_of_charges": "SHA"}
    }
  }
}

Invalid Message (200 OK with errors)

{
  "status": "invalid",
  "message_type": "MT103",
  "format": "swift_mt",
  "validation": {
    "format": "passed",
    "schema": "failed",
    "business": "skipped"
  },
  "errors": [
    {
      "code": "MISSING_TAG",
      "field": "32A",
      "message": "Tag 32A (Value Date/Currency/Amount) is required",
      "severity": "error"
    },
    {
      "code": "INVALID_FORMAT",
      "field": "50K",
      "message": "Account must start with /",
      "severity": "error"
    }
  ]
}

Parse Error (400 Bad Request)

{
  "status": "error",
  "error": {
    "code": "PARSE_ERROR",
    "message": "Cannot parse message",
    "details": {
      "position": 45,
      "expected": "Block 4 start",
      "found": "Invalid character"
    }
  }
}

Validation Levels

Format Validation

Basic structural checks:

SWIFT MT:

  • Block delimiters {1:, {2:, etc.
  • Field separators
  • Block sequence

ISO 20022:

  • Well-formed XML
  • Valid namespaces
  • Basic structure

Schema Validation

Message specification checks:

SWIFT MT:

  • Required tags present
  • Tag formats correct
  • Field lengths within limits
  • Valid code values

ISO 20022:

  • XSD schema compliance
  • Required elements present
  • Data types correct
  • Enumeration values valid

Business Validation

CBPR+ business rules (when enabled):

  • BIC format (8 or 11 characters)
  • IBAN checksum validation
  • Amount positive and formatted
  • Date formats (YYMMDD or YYYY-MM-DD)
  • Service level codes (G001-G004)
  • Charge bearer codes (SHAR, DEBT, CRED)
  • UETR format (UUID v4)

Error Codes

CodeDescription
PARSE_ERRORCannot parse message structure
BLOCK_STRUCTUREInvalid MT block structure
MISSING_TAGRequired tag missing
INVALID_FORMATField format incorrect
INVALID_LENGTHField length exceeded
INVALID_BICInvalid BIC code
INVALID_IBANInvalid IBAN
INVALID_AMOUNTAmount format error
INVALID_DATEDate format error
INVALID_CODEInvalid code value
SCHEMA_VIOLATIONXML schema error
BUSINESS_RULEBusiness rule violation

Examples

Basic Validation

curl -X POST http://localhost:3000/api/validate \
  -H "Content-Type: application/json" \
  -d '{
    "message": "{1:F01BNPAFRPPXXX0000000000}{2:I103DEUTDEFFXXXXN}{4:\n:20:REF123\n:23B:CRED\n:32A:250115USD50000,00\n:50K:/1234\nSENDER\n:59:/5678\nRECEIVER\n:71A:SHA\n-}"
  }'

With Business Validation

curl -X POST http://localhost:3000/api/validate \
  -H "Content-Type: application/json" \
  -d '{
    "message": "...",
    "business_validation": true
  }'

With Canonical JSON

curl -X POST http://localhost:3000/api/validate \
  -H "Content-Type: application/json" \
  -d '{
    "message": "...",
    "canonical_json": true
  }'

Validate ISO 20022

curl -X POST http://localhost:3000/api/validate \
  -H "Content-Type: application/json" \
  -d '{
    "message": "<?xml version=\"1.0\"?><Document xmlns=\"urn:iso:std:iso:20022:tech:xsd:pacs.008.001.12\">...</Document>",
    "business_validation": true
  }'

API Overview →

Try in Playground →

Generate API

Generate sample SWIFT MT and ISO 20022 messages.

Endpoint

POST /api/generate

Request

Headers

HeaderValue
Content-Typeapplication/json

Body

{
  "message_type": "string (required)",
  "scenario": "string (optional, default: 'standard')"
}

Parameters

ParameterTypeRequiredDescription
message_typestringYesMessage type to generate (MT103, pacs.008, etc.)
scenariostringNoScenario variant (standard, high_value, etc.)

Response

Success (200 OK)

{
  "status": "success",
  "message_type": "MT103",
  "scenario": "standard",
  "message": "{1:F01BNPAFRPPXXX0000000000}...",
  "metadata": {
    "generated_at": "2025-01-15T10:30:00Z",
    "package": "swift-cbpr-mt-mx",
    "version": "2.1.2"
  }
}

Unsupported Type (400 Bad Request)

{
  "status": "error",
  "error": {
    "code": "UNSUPPORTED_TYPE",
    "message": "Message type 'MT999' is not supported",
    "supported_types": ["MT103", "MT202", "MT940", "pacs.008", "pacs.009", "..."]
  }
}

Unknown Scenario (400 Bad Request)

{
  "status": "error",
  "error": {
    "code": "UNKNOWN_SCENARIO",
    "message": "Scenario 'custom' not found for MT103",
    "available_scenarios": ["standard", "high_value", "remittance"]
  }
}

Supported Message Types

SWIFT MT Messages

TypeDescriptionScenarios
MT101Request for Transferstandard
MT103Single Customer Credit Transferstandard, high_value, remittance
MT103STPStraight-Through Processingstandard
MT200Financial Institution Transferstandard
MT202General FI Transferstandard, cover
MT202COVCover Paymentstandard
MT205FI Transfer (Third Party)standard
MT900Confirmation of Debitstandard
MT910Confirmation of Creditstandard
MT940Customer Statementstandard, multi_entry
MT942Interim Transaction Reportstandard

ISO 20022 Messages

TypeDescriptionScenarios
pacs.002Payment Status Reportaccepted, rejected
pacs.004Payment Returnstandard
pacs.008FI to FI Customer Credit Transferstandard, high_value
pacs.009FI to FI FI Credit Transferstandard, cover
camt.029Resolution of Investigationstandard
camt.052Account Reportstandard
camt.053Bank Statementstandard
camt.054Debit/Credit Notificationdebit, credit
camt.056Cancellation Requeststandard

Scenario Details

MT103 Scenarios

standard: Basic customer credit transfer

  • Amount: $10,000 - $100,000
  • Standard party information
  • SHA charges

high_value: Large value transfer

  • Amount: $500,000 - $5,000,000
  • Full party details with addresses
  • Complete agent chain

remittance: With remittance information

  • Includes Tag 70 (remittance info)
  • Invoice/PO references
  • Regulatory reporting

pacs.008 Scenarios

standard: Basic ISO 20022 transfer

  • SR2025 compliant structure
  • UETR included
  • Standard party identification

high_value: Enhanced party details

  • LEI identifiers
  • Structured addresses
  • Full creditor reference

Examples

Generate MT103

curl -X POST http://localhost:3000/api/generate \
  -H "Content-Type: application/json" \
  -d '{
    "message_type": "MT103",
    "scenario": "standard"
  }'

Generate pacs.008

curl -X POST http://localhost:3000/api/generate \
  -H "Content-Type: application/json" \
  -d '{
    "message_type": "pacs.008",
    "scenario": "standard"
  }'

Generate High-Value MT103

curl -X POST http://localhost:3000/api/generate \
  -H "Content-Type: application/json" \
  -d '{
    "message_type": "MT103",
    "scenario": "high_value"
  }'

Generate MT940 Statement

curl -X POST http://localhost:3000/api/generate \
  -H "Content-Type: application/json" \
  -d '{
    "message_type": "MT940",
    "scenario": "multi_entry"
  }'

Sample Output

MT103 (standard)

{1:F01CITIUS33XXX0000000000}
{2:I103DEUTDEFFXXXXN}
{3:{121:a1b2c3d4-e5f6-7890-abcd-ef1234567890}}
{4:
:20:TRF20250115001
:23B:CRED
:32A:250115USD75000,00
:50K:/US33445566778899
ACME INTERNATIONAL INC
1234 CORPORATE BLVD
NEW YORK NY 10001
:57A:COBADEFFXXX
:59:/DE89370400440532013000
MUNICH TRADING GMBH
LEOPOLDSTRASSE 100
80802 MUNICH
:70:/INV/2025-00123
:71A:SHA
-}

pacs.008 (standard)

<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.12">
  <FIToFICstmrCdtTrf>
    <GrpHdr>
      <MsgId>MSG20250115001</MsgId>
      <CreDtTm>2025-01-15T10:30:00Z</CreDtTm>
      <NbOfTxs>1</NbOfTxs>
      <SttlmInf>
        <SttlmMtd>INDA</SttlmMtd>
      </SttlmInf>
    </GrpHdr>
    <CdtTrfTxInf>
      <PmtId>
        <InstrId>INSTR20250115001</InstrId>
        <EndToEndId>E2E20250115001</EndToEndId>
        <UETR>a1b2c3d4-e5f6-7890-abcd-ef1234567890</UETR>
      </PmtId>
      <PmtTpInf>
        <SvcLvl><Cd>G002</Cd></SvcLvl>
      </PmtTpInf>
      <IntrBkSttlmAmt Ccy="EUR">45000.00</IntrBkSttlmAmt>
      <IntrBkSttlmDt>2025-01-15</IntrBkSttlmDt>
      <ChrgBr>SHAR</ChrgBr>
      <Dbtr>
        <Nm>SENDER CORPORATION</Nm>
      </Dbtr>
      <DbtrAgt>
        <FinInstnId>
          <BICFI>BNPAFRPPXXX</BICFI>
        </FinInstnId>
      </DbtrAgt>
      <CdtrAgt>
        <FinInstnId>
          <BICFI>DEUTDEFFXXX</BICFI>
        </FinInstnId>
      </CdtrAgt>
      <Cdtr>
        <Nm>RECEIVER GMBH</Nm>
      </Cdtr>
    </CdtTrfTxInf>
  </FIToFICstmrCdtTrf>
</Document>

API Overview →

Try in Playground →

Admin API

Administrative endpoints for managing Reframe.

Reload Workflows

Hot reload transformation rules without restarting.

Endpoint

POST /admin/reload-workflows

Request

No request body required.

Response (Success)

{
  "status": "success",
  "message": "Workflows reloaded successfully",
  "package": {
    "id": "swift-cbpr-mt-mx",
    "version": "2.1.2",
    "workflows_loaded": 594
  },
  "timing_ms": 125
}

Response (Error)

{
  "status": "error",
  "message": "Failed to reload workflows",
  "error": {
    "code": "COMPILATION_ERROR",
    "details": "Invalid JSONLogic in MT103/document-mapping.json at line 45"
  }
}

Example

curl -X POST http://localhost:3000/admin/reload-workflows

Health Check

Check service health and engine status.

Endpoint

GET /health

Response (Healthy)

{
  "status": "healthy",
  "engines": {
    "transform": "ready",
    "generation": "ready",
    "validation": "ready"
  },
  "package": {
    "id": "swift-cbpr-mt-mx",
    "version": "2.1.2",
    "loaded_at": "2025-01-15T10:30:00Z"
  },
  "uptime_seconds": 86400
}

Response (Unhealthy)

{
  "status": "unhealthy",
  "engines": {
    "transform": "error",
    "generation": "ready",
    "validation": "ready"
  },
  "error": "Transform engine failed to initialize"
}

Example

curl http://localhost:3000/health

List Packages

List loaded transformation packages.

Endpoint

GET /packages

Response

{
  "packages": [
    {
      "id": "swift-cbpr-mt-mx",
      "name": "SWIFT CBPR+ MT <-> MX Transformations",
      "version": "2.1.2",
      "engine_version": "3.1.4",
      "loaded_at": "2025-01-15T10:30:00Z",
      "workflows": {
        "transform": 594,
        "validate": 12,
        "generate": 8
      },
      "scenarios": {
        "outgoing": 23,
        "incoming": 32
      }
    }
  ]
}

Example

curl http://localhost:3000/packages

OpenAPI Documentation

Interactive API documentation.

Endpoint

GET /swagger-ui

Opens the Swagger UI interface in a web browser.

Example

# Open in browser
open http://localhost:3000/swagger-ui

Configuration Endpoints

Get Current Configuration

GET /admin/config

Returns the current runtime configuration (excludes sensitive data).

{
  "server": {
    "host": "0.0.0.0",
    "port": 3000,
    "workers": 4
  },
  "logging": {
    "level": "info",
    "format": "compact"
  },
  "packages": [
    {
      "path": "/packages/swift-cbpr",
      "enabled": true
    }
  ]
}

Example

curl http://localhost:3000/admin/config

Metrics Endpoint

Prometheus-compatible metrics (if enabled).

Endpoint

GET /metrics

Response

# HELP reframe_requests_total Total number of requests
# TYPE reframe_requests_total counter
reframe_requests_total{endpoint="/api/transform",status="success"} 12345
reframe_requests_total{endpoint="/api/validate",status="success"} 8901

# HELP reframe_request_duration_seconds Request duration
# TYPE reframe_request_duration_seconds histogram
reframe_request_duration_seconds_bucket{endpoint="/api/transform",le="0.001"} 10234
reframe_request_duration_seconds_bucket{endpoint="/api/transform",le="0.01"} 12100

# HELP reframe_messages_transformed_total Total messages transformed
# TYPE reframe_messages_transformed_total counter
reframe_messages_transformed_total{direction="outgoing",type="MT103"} 5678
reframe_messages_transformed_total{direction="incoming",type="pacs.008"} 4321

Example

curl http://localhost:3000/metrics

Security Considerations

Admin Endpoints

Admin endpoints should be protected in production:

  • Use a reverse proxy to restrict access
  • Implement IP whitelisting
  • Add authentication if needed

Example: nginx Protection

location /admin/ {
    allow 10.0.0.0/8;
    deny all;
    proxy_pass http://reframe:3000;
}

Example: Authentication Header

# If authentication is configured
curl -H "Authorization: Bearer <token>" \
  http://localhost:3000/admin/reload-workflows

API Overview →

Hot Reload Guide →

GraphQL API

Query transformation history and analytics using GraphQL.

Endpoint

POST /graphql

Playground

Interactive GraphQL playground:

GET /graphql

Open in browser to explore the schema and run queries.

Schema Overview

Types

type Message {
  id: ID!
  message_type: String!
  direction: String!
  source_message: String!
  target_message: String!
  status: String!
  package_id: String!
  created_at: DateTime!
  timing_ms: Float!
  custom_fields: CustomFields
}

type CustomFields {
  sender_name: String
  receiver_name: String
  amount: Float
  currency: String
  sender_country: String
  receiver_country: String
  is_cross_border: Boolean
  amount_band: String
}

type MessageConnection {
  messages: [Message!]!
  total_count: Int!
  has_next_page: Boolean!
}

type Aggregation {
  group_key: String!
  count: Int!
  total_amount: Float
}

Queries

type Query {
  # Get a single message by ID
  message(id: ID!): Message

  # Query messages with filtering
  messages(
    filter: MessageFilter
    limit: Int = 100
    offset: Int = 0
    order_by: OrderBy
  ): MessageConnection!

  # Aggregate messages
  message_aggregations(
    package_id: String!
    group_by: [String!]!
    filter: MessageFilter
  ): [Aggregation!]!
}

Filters

input MessageFilter {
  package_id: String
  message_type: String
  direction: String
  status: String
  date_range: DateRange
  custom_field_filters: CustomFieldFilters
}

input DateRange {
  start: DateTime!
  end: DateTime!
}

input CustomFieldFilters {
  sender_country: String
  receiver_country: String
  is_cross_border: Boolean
  amount_band: String
  amount_min: Float
  amount_max: Float
}

input OrderBy {
  field: String!
  direction: SortDirection!
}

enum SortDirection {
  ASC
  DESC
}

Query Examples

Get Recent Messages

query {
  messages(
    filter: {
      package_id: "swift-cbpr-mt-mx"
    },
    limit: 10,
    order_by: { field: "created_at", direction: DESC }
  ) {
    messages {
      id
      message_type
      direction
      status
      created_at
      timing_ms
    }
    total_count
  }
}

Filter by Custom Fields

query {
  messages(
    filter: {
      package_id: "swift-cbpr-mt-mx",
      custom_field_filters: {
        is_cross_border: true,
        amount_band: "HIGH",
        sender_country: "US"
      }
    },
    limit: 100
  ) {
    messages {
      id
      message_type
      custom_fields {
        sender_name
        receiver_name
        amount
        currency
        sender_country
        receiver_country
      }
    }
    total_count
  }
}

Filter by Date Range

query {
  messages(
    filter: {
      package_id: "swift-cbpr-mt-mx",
      date_range: {
        start: "2025-01-01T00:00:00Z",
        end: "2025-01-31T23:59:59Z"
      }
    }
  ) {
    messages {
      id
      message_type
      created_at
    }
    total_count
  }
}

Get Message by ID

query {
  message(id: "msg-12345") {
    id
    message_type
    direction
    source_message
    target_message
    status
    created_at
    timing_ms
    custom_fields {
      sender_name
      receiver_name
      amount
      currency
    }
  }
}

Aggregate by Country

query {
  message_aggregations(
    package_id: "swift-cbpr-mt-mx",
    group_by: ["sender_country"],
    filter: {
      date_range: {
        start: "2025-01-01T00:00:00Z",
        end: "2025-01-31T23:59:59Z"
      }
    }
  ) {
    group_key
    count
    total_amount
  }
}

Aggregate by Multiple Dimensions

query {
  message_aggregations(
    package_id: "swift-cbpr-mt-mx",
    group_by: ["sender_country", "amount_band"],
    filter: {
      custom_field_filters: {
        is_cross_border: true
      }
    }
  ) {
    group_key
    count
    total_amount
  }
}

Using curl

Basic Query

curl -X POST http://localhost:3000/graphql \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query { messages(limit: 10) { messages { id message_type } } }"
  }'

Query with Variables

curl -X POST http://localhost:3000/graphql \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query GetMessages($limit: Int!) { messages(limit: $limit) { messages { id } } }",
    "variables": {"limit": 50}
  }'

Requirements

GraphQL queries require:

  1. MongoDB persistence enabled in configuration
  2. Message storage enabled for transformations

Configuration

{
  "database": {
    "mongodb_uri": "mongodb://localhost:27017",
    "database_name": "reframe",
    "store_messages": true
  }
}

Custom Fields

Custom fields are defined in the package’s api_config.json and computed during transformation. Common fields include:

FieldTypeDescription
sender_namestringDebtor name
receiver_namestringCreditor name
amountnumberSettlement amount
currencystringCurrency code
sender_countrystringSender country (from BIC)
receiver_countrystringReceiver country (from BIC)
is_cross_borderbooleanCross-border indicator
amount_bandstringHIGH/MEDIUM/LOW

Custom Fields Guide →

API Overview →

Kubernetes Deployment

Deploy Reframe on Kubernetes for production workloads.

Basic Deployment

Deployment

# reframe-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: reframe
  labels:
    app: reframe
spec:
  replicas: 3
  selector:
    matchLabels:
      app: reframe
  template:
    metadata:
      labels:
        app: reframe
    spec:
      containers:
      - name: reframe
        image: plasmatic/reframe:3.1.8
        ports:
        - containerPort: 3000
        env:
        - name: RUST_LOG
          value: "info"
        - name: TOKIO_WORKER_THREADS
          value: "4"
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "1000m"
        readinessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 10
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 15
          periodSeconds: 20

Service

# reframe-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: reframe
spec:
  selector:
    app: reframe
  ports:
  - protocol: TCP
    port: 80
    targetPort: 3000
  type: ClusterIP

Ingress

# reframe-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: reframe
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - api.example.com
    secretName: reframe-tls
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: reframe
            port:
              number: 80

Apply Resources

kubectl apply -f reframe-deployment.yaml
kubectl apply -f reframe-service.yaml
kubectl apply -f reframe-ingress.yaml

ConfigMap

Configuration File

# reframe-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: reframe-config
data:
  reframe.config.json: |
    {
      "server": {
        "host": "0.0.0.0",
        "port": 3000
      },
      "logging": {
        "level": "info",
        "format": "json"
      }
    }

Mount ConfigMap

spec:
  containers:
  - name: reframe
    volumeMounts:
    - name: config
      mountPath: /app/reframe.config.json
      subPath: reframe.config.json
  volumes:
  - name: config
    configMap:
      name: reframe-config

Custom Package

Using PersistentVolume

# reframe-pv.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: reframe-packages
spec:
  accessModes:
    - ReadOnlyMany
  resources:
    requests:
      storage: 1Gi
spec:
  containers:
  - name: reframe
    volumeMounts:
    - name: packages
      mountPath: /packages/custom
    env:
    - name: REFRAME_PACKAGE_PATH
      value: "/packages"
  volumes:
  - name: packages
    persistentVolumeClaim:
      claimName: reframe-packages

Horizontal Pod Autoscaler

# reframe-hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: reframe
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: reframe
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80

Pod Disruption Budget

# reframe-pdb.yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: reframe
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: reframe

Network Policy

# reframe-network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: reframe
spec:
  podSelector:
    matchLabels:
      app: reframe
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: ingress-nginx
    ports:
    - protocol: TCP
      port: 3000
  egress:
  - to:
    - namespaceSelector: {}
    ports:
    - protocol: TCP
      port: 443

Helm Chart

values.yaml

replicaCount: 3

image:
  repository: plasmatic/reframe
  tag: "3.1.8"
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80

ingress:
  enabled: true
  className: nginx
  hosts:
    - host: api.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: reframe-tls
      hosts:
        - api.example.com

resources:
  limits:
    cpu: 1000m
    memory: 512Mi
  requests:
    cpu: 250m
    memory: 256Mi

autoscaling:
  enabled: true
  minReplicas: 2
  maxReplicas: 10
  targetCPUUtilizationPercentage: 70

env:
  RUST_LOG: info
  TOKIO_WORKER_THREADS: "4"

Monitoring

ServiceMonitor (Prometheus)

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: reframe
spec:
  selector:
    matchLabels:
      app: reframe
  endpoints:
  - port: http
    path: /metrics
    interval: 30s

Operations

Check Status

kubectl get pods -l app=reframe
kubectl get svc reframe
kubectl get ingress reframe

View Logs

kubectl logs -l app=reframe -f

Scale

kubectl scale deployment reframe --replicas=5

Rolling Update

kubectl set image deployment/reframe reframe=plasmatic/reframe:3.2.0
kubectl rollout status deployment/reframe

Rollback

kubectl rollout undo deployment/reframe

Configuration Reference →

Configuration Reference

Complete configuration options for Reframe.

Configuration Sources

Configuration is loaded in priority order:

  1. Environment variables (highest)
  2. Configuration file (reframe.config.json)
  3. Built-in defaults (lowest)

Environment Variables

VariableDefaultDescription
REFRAME_HOST0.0.0.0Server bind address
REFRAME_PORT3000Server port
REFRAME_PACKAGE_PATH/packagesPackage directory
TOKIO_WORKER_THREADSCPU coresAsync worker threads
RUST_LOGinfoLog level
RUST_LOG_FORMATcompactLog format (compact/json/pretty)
MONGODB_URI-MongoDB connection string
MONGODB_DATABASEreframeDatabase name

Configuration File

Create reframe.config.json in the working directory:

{
  "server": {
    "host": "0.0.0.0",
    "port": 3000,
    "workers": 4
  },

  "logging": {
    "level": "info",
    "format": "compact",
    "file": null
  },

  "packages": [
    {
      "path": "/packages/swift-cbpr",
      "enabled": true
    }
  ],

  "database": {
    "mongodb_uri": "mongodb://localhost:27017",
    "database_name": "reframe",
    "store_messages": false
  },

  "api_docs": {
    "enabled": true,
    "title": "Reframe API",
    "version": "3.1.8"
  }
}

Section Details

Server

{
  "server": {
    "host": "0.0.0.0",
    "port": 3000,
    "workers": 4
  }
}
OptionTypeDefaultDescription
hoststring0.0.0.0Bind address
portnumber3000Listen port
workersnumberCPU coresTokio worker threads

Logging

{
  "logging": {
    "level": "info",
    "format": "compact",
    "file": {
      "path": "/var/log/reframe/reframe.log",
      "rotation": "daily",
      "max_files": 7
    }
  }
}
OptionTypeDefaultDescription
levelstringinfoLog level (trace/debug/info/warn/error)
formatstringcompactOutput format (compact/json/pretty)
file.pathstringnullLog file path
file.rotationstringdailyRotation (daily/hourly/never)
file.max_filesnumber7Files to keep

Packages

{
  "packages": [
    {
      "path": "/packages/swift-cbpr",
      "enabled": true
    },
    {
      "path": "/packages/custom",
      "enabled": false
    }
  ]
}
OptionTypeDescription
pathstringPath to package directory
enabledbooleanWhether to load this package

Database

{
  "database": {
    "mongodb_uri": "mongodb://localhost:27017",
    "database_name": "reframe",
    "store_messages": true,
    "ttl_days": 90
  }
}
OptionTypeDefaultDescription
mongodb_uristring-MongoDB connection URI
database_namestringreframeDatabase name
store_messagesbooleanfalseStore transformed messages
ttl_daysnumber90Message retention days

API Documentation

{
  "api_docs": {
    "enabled": true,
    "title": "Reframe API",
    "version": "3.1.8",
    "description": "ISO 20022 Transformation Engine",
    "contact": {
      "name": "Support",
      "email": "support@example.com"
    }
  }
}

Complete Example

{
  "server": {
    "host": "0.0.0.0",
    "port": 3000,
    "workers": 8
  },

  "logging": {
    "level": "info",
    "format": "json",
    "file": {
      "path": "/var/log/reframe/reframe.log",
      "rotation": "daily",
      "max_files": 30
    }
  },

  "packages": [
    {
      "path": "/packages/swift-cbpr",
      "enabled": true
    }
  ],

  "database": {
    "mongodb_uri": "mongodb://mongo:27017",
    "database_name": "reframe_prod",
    "store_messages": true,
    "ttl_days": 365
  },

  "api_docs": {
    "enabled": true,
    "title": "Reframe Production API",
    "version": "3.1.8"
  }
}

Docker Configuration

Environment Variables

docker run \
  -e REFRAME_PORT=8080 \
  -e RUST_LOG=debug \
  -e TOKIO_WORKER_THREADS=8 \
  plasmatic/reframe:latest

Configuration File Mount

docker run \
  -v /path/to/reframe.config.json:/app/reframe.config.json \
  plasmatic/reframe:latest

Kubernetes Configuration

ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: reframe-config
data:
  reframe.config.json: |
    {
      "server": {
        "port": 3000
      },
      "logging": {
        "level": "info",
        "format": "json"
      }
    }

Secret (for sensitive values)

apiVersion: v1
kind: Secret
metadata:
  name: reframe-secrets
type: Opaque
stringData:
  MONGODB_URI: "mongodb://user:pass@host:27017"

Validation

Reframe validates configuration on startup:

2025-01-15T10:30:00Z INFO reframe: Loading configuration
2025-01-15T10:30:00Z INFO reframe: Server: 0.0.0.0:3000
2025-01-15T10:30:00Z INFO reframe: Workers: 8
2025-01-15T10:30:00Z INFO reframe: Log level: info
2025-01-15T10:30:00Z INFO reframe: Package: /packages/swift-cbpr (enabled)

Invalid configuration causes startup failure with clear error messages.


Kubernetes Deployment →

Monitoring

Monitor Reframe in production environments.

Health Checks

HTTP Health Endpoint

curl http://localhost:3000/health

Response:

{
  "status": "healthy",
  "engines": {
    "transform": "ready",
    "generation": "ready",
    "validation": "ready"
  },
  "package": {
    "id": "swift-cbpr-mt-mx",
    "version": "2.1.2",
    "loaded_at": "2025-01-15T10:30:00Z"
  },
  "uptime_seconds": 86400
}

Docker Health Check

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
  interval: 30s
  timeout: 10s
  retries: 3
  start_period: 10s

Kubernetes Probes

readinessProbe:
  httpGet:
    path: /health
    port: 3000
  initialDelaySeconds: 5
  periodSeconds: 10

livenessProbe:
  httpGet:
    path: /health
    port: 3000
  initialDelaySeconds: 15
  periodSeconds: 20

Metrics

Prometheus Endpoint

curl http://localhost:3000/metrics

Available Metrics

# Request metrics
reframe_requests_total{endpoint,status}
reframe_request_duration_seconds{endpoint,le}

# Transformation metrics
reframe_transformations_total{direction,type,status}
reframe_transformation_duration_seconds{direction,type,le}

# Validation metrics
reframe_validations_total{format,status}

# Generation metrics
reframe_generations_total{type}

# System metrics
reframe_uptime_seconds
reframe_package_workflows_total

Prometheus Configuration

# prometheus.yml
scrape_configs:
  - job_name: 'reframe'
    static_configs:
      - targets: ['reframe:3000']
    metrics_path: /metrics
    scrape_interval: 30s

Grafana Dashboard

Key panels to include:

  • Request Rate: rate(reframe_requests_total[5m])
  • Error Rate: rate(reframe_requests_total{status="error"}[5m])
  • Latency P99: histogram_quantile(0.99, rate(reframe_request_duration_seconds_bucket[5m]))
  • Transformations by Type: sum by (type) (rate(reframe_transformations_total[5m]))

Logging

Log Levels

LevelDescription
errorErrors only
warnWarnings and errors
infoGeneral info (recommended for production)
debugDebug information
traceDetailed tracing

Log Formats

compact (default):

2025-01-15T10:30:00Z INFO reframe::api: Transform request direction=outgoing type=MT103

json (for log aggregation):

{"timestamp":"2025-01-15T10:30:00Z","level":"INFO","target":"reframe::api","message":"Transform request","direction":"outgoing","type":"MT103"}

pretty (for development):

2025-01-15T10:30:00.123Z  INFO reframe::api: Transform request
    direction: outgoing
    type: MT103

Log Aggregation

Fluentd

<source>
  @type tail
  path /var/log/reframe/*.log
  pos_file /var/log/fluentd/reframe.pos
  tag reframe
  <parse>
    @type json
  </parse>
</source>

Loki

scrape_configs:
  - job_name: reframe
    static_configs:
      - targets:
          - localhost
        labels:
          job: reframe
          __path__: /var/log/reframe/*.log

Alerting

Key Alerts

High Error Rate

- alert: ReframeHighErrorRate
  expr: rate(reframe_requests_total{status="error"}[5m]) > 0.1
  for: 5m
  labels:
    severity: critical
  annotations:
    summary: High error rate in Reframe

High Latency

- alert: ReframeHighLatency
  expr: histogram_quantile(0.99, rate(reframe_request_duration_seconds_bucket[5m])) > 1
  for: 5m
  labels:
    severity: warning
  annotations:
    summary: High latency in Reframe

Service Down

- alert: ReframeDown
  expr: up{job="reframe"} == 0
  for: 1m
  labels:
    severity: critical
  annotations:
    summary: Reframe service is down

Package Reload Failed

- alert: ReframePackageError
  expr: reframe_package_load_errors_total > 0
  for: 1m
  labels:
    severity: warning
  annotations:
    summary: Package reload failed

Tracing

OpenTelemetry (if enabled)

{
  "tracing": {
    "enabled": true,
    "exporter": "otlp",
    "endpoint": "http://jaeger:4317",
    "service_name": "reframe"
  }
}

Trace Context

Reframe propagates trace context through headers:

  • traceparent
  • tracestate

Dashboard Example

Key Metrics to Display

  1. Overview

    • Requests per second
    • Error rate percentage
    • Average latency
  2. Transformations

    • By direction (outgoing/incoming)
    • By message type
    • Success/failure rate
  3. System

    • CPU usage
    • Memory usage
    • Uptime
  4. Package

    • Loaded workflows
    • Last reload time
    • Reload errors

Best Practices

  1. Set appropriate log level - Use info for production
  2. Use JSON logging - Easier to parse and aggregate
  3. Configure alerts - Catch issues before users notice
  4. Monitor latency - P99 is more important than average
  5. Track by message type - Identify problematic transformations
  6. Set retention policies - Don’t fill up storage

Configuration Reference →

Kubernetes Deployment →

Technology Overview

The open-source foundation powering Reframe.

Architecture

Reframe is built on a modular architecture with specialized libraries:

┌─────────────────────────────────────────────────────────────┐
│                      Reframe Engine                         │
│                                                             │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │   Dataflow  │  │  Datalogic  │  │      Datafake       │  │
│  │  Workflows  │  │   Rules     │  │   Data Generation   │  │
│  └─────────────┘  └─────────────┘  └─────────────────────┘  │
│                                                             │
│  ┌──────────────────────────────────────────────────────┐   │
│  │  swift-mt-message  │  mx-message  │  quick-xml       │   │
│  │  MT Parsing        │  MX Parsing  │  XML Processing  │   │
│  └──────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘

Core Libraries

LibraryPurposeRole in Reframe
DataflowWorkflow orchestrationExecutes transformation pipelines
DatalogicJSONLogic evaluationProcesses business rules and mappings
DatafakeTest data generationGenerates sample messages

Why These Libraries?

Separation of Concerns

Each library handles a specific responsibility:

  • Dataflow: Orchestrates when and how workflows execute
  • Datalogic: Evaluates what transformations to apply
  • Datafake: Generates realistic test data

Performance

All libraries are:

  • Written in Rust for memory safety and speed
  • Pre-compiled at startup (zero runtime parsing)
  • Thread-safe for concurrent processing

Transparency

All business logic is:

  • Defined in JSON (not compiled code)
  • Auditable and version-controllable
  • Modifiable without rebuilding

Technology Stack

Core

TechnologyVersionPurpose
Rust1.89+Language
Tokio1.48Async runtime
Axum0.8HTTP framework
serde_json1.0JSON processing

Message Processing

LibraryPurpose
swift-mt-messageSWIFT MT parsing
mx-messageISO 20022 parsing
quick-xmlXML serialization

Database & API

TechnologyPurpose
MongoDBMessage storage (optional)
utoipaOpenAPI generation
async-graphqlGraphQL API

Open Source Ecosystem

All components are open source under Apache 2.0:

ProjectGitHubDocumentation
ReframeGoPlasmatic/ReframeThis site
DatalogicGoPlasmatic/datalogic-rsDocs
DataflowGoPlasmatic/dataflow-rsDocs
DatafakeGoPlasmatic/datafake-rsDocs

Each project includes an interactive playground for testing.

Performance Characteristics

Latency

OperationTypical Latency
MT103 → pacs.008< 1ms
pacs.008 → MT103< 1ms
Validation< 0.5ms
Sample generation< 2ms

Throughput

ConfigurationMessages/Second
Single instance (4 CPU)5,000+
Horizontal scalingLinear

Resource Usage

ResourceTypical Usage
Memory256-512 MB
CPULow (mostly I/O bound)
Startup time< 5 seconds

Datalogic →

Dataflow →

Datafake →

Datalogic

The JSONLogic rules engine powering Reframe transformations.

What is Datalogic?

Datalogic is a high-performance Rust implementation of JSONLogic - a standard for expressing business logic as JSON.

In Reframe, Datalogic evaluates all field mappings and business rules during transformation.

Role in Reframe

Transformation Pipeline
        │
        ▼
┌───────────────────┐
│  Field Mapping    │
│  {                │
│    "path": "...", │
│    "logic": {...} │◄──── Datalogic evaluates this
│  }                │
└───────────────────┘
        │
        ▼
   Transformed Data

Key Features

59 Built-in Operators

CategoryExamples
Comparison==, !=, >, <, >=, <=
Booleanand, or, !, !!
Arithmetic+, -, *, /, %, min, max
Stringcat, substr, in, upper, lower
Arraymap, filter, reduce, all, some
Controlif, ?:, ??
Date/Timenow, format_date, parse_date

Pre-Compilation

Rules are compiled once at startup:

  • No parsing during request processing
  • O(1) rule lookup
  • Zero-copy execution

Thread-Safe

  • Safe concurrent evaluation
  • Arc-wrapped compiled rules
  • Native async/Tokio support

Example Rules

Direct Mapping

{"var": "data.SwiftMT.fields.20.transaction_reference"}

Conditional Logic

{
  "if": [
    {"==": [{"var": "data.field"}, "A"]},
    "Result A",
    "Result B"
  ]
}

String Operations

{
  "cat": [
    {"var": "data.first"},
    " ",
    {"var": "data.last"}
  ]
}

Complex Transformation

{
  "if": [
    {"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "SHA"]},
    "SHAR",
    {"if": [
      {"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "OUR"]},
      "DEBT",
      "CRED"
    ]}
  ]
}

Interactive Playground

Try Datalogic expressions in the browser:

Datalogic Playground →

Resources

Usage in Reframe

Transformation Rules

{
  "path": "data.output.PmtId.InstrId",
  "logic": {"var": "data.SwiftMT.fields.20.transaction_reference"}
}

Workflow Conditions

{
  "id": "mt103-workflow",
  "condition": {
    "and": [
      {"==": [{"var": "metadata.direction"}, "outgoing"]},
      {"==": [{"var": "metadata.message_type"}, "MT103"]}
    ]
  }
}

Validation Rules

{
  "rules": [
    {
      "logic": {">": [{"var": "data.amount"}, 0]},
      "message": "Amount must be positive"
    }
  ]
}

Dataflow →

JSONLogic Rules Guide →

Dataflow

The workflow orchestration engine powering Reframe pipelines.

What is Dataflow?

Dataflow is an async-first workflow orchestration engine built in Rust. It executes transformation pipelines by routing messages through a series of workflows and tasks.

In Reframe, Dataflow manages the transformation pipeline - determining which workflows execute and in what order.

Role in Reframe

Message Input
      │
      ▼
┌───────────────────────────────────────────────┐
│              Dataflow Engine                  │
│                                               │
│  ┌──────────┐   ┌──────────┐   ┌───────────┐  │
│  │Workflow  │──▶│Workflo w │──▶│Workflow   │  │
│  │Priority:1│   │Priority:5│   │Priority:10│  │
│  └──────────┘   └──────────┘   └───────────┘  │
│                                               │
│  Each workflow contains tasks that:           │
│  • Map fields (using Datalogic)               │
│  • Validate data                              │
│  • Call custom functions                      │
└───────────────────────────────────────────────┘
      │
      ▼
Message Output

Key Features

Priority-Based Execution

Workflows execute in priority order (lowest first):

Priority 1:  parse-mt.json
Priority 2:  detect-variant.json
Priority 3:  bah-mapping.json
Priority 5:  document-mapping.json
Priority 10: combine-xml.json

Conditional Routing

Each workflow has a condition that determines if it runs:

{
  "condition": {
    "and": [
      {"==": [{"var": "metadata.direction"}, "outgoing"]},
      {"==": [{"var": "metadata.message_type"}, "MT103"]}
    ]
  }
}

Pre-Compiled Workflows

  • All JSONLogic compiled at startup
  • Zero runtime parsing
  • Indexed for O(1) access

Audit Trail

Every change is recorded:

{
  "audit_trail": [
    {
      "timestamp": "2025-01-15T10:30:00Z",
      "workflow_id": "mt103-mapping",
      "task_id": "map-amount",
      "path": "data.output.IntrBkSttlmAmt",
      "old_value": null,
      "new_value": "50000.00"
    }
  ]
}

Interactive Playground

Try Dataflow workflows in the browser:

Dataflow Playground →

Resources

Workflow Structure

{
  "id": "mt103-document-mapping",
  "name": "MT103 Document Mapping",
  "priority": 5,

  "condition": {
    "==": [{"var": "metadata.message_type"}, "MT103"]
  },

  "tasks": [
    {
      "id": "map-payment-id",
      "function": {
        "name": "map",
        "input": {
          "mappings": [
            {
              "path": "data.output.PmtId.InstrId",
              "logic": {"var": "data.SwiftMT.fields.20.transaction_reference"}
            }
          ]
        }
      }
    }
  ]
}

Task Types

Map Task

Transform data using JSONLogic:

{
  "function": {
    "name": "map",
    "input": {
      "mappings": [
        {"path": "output.field", "logic": {"var": "input.field"}}
      ]
    }
  }
}

Validation Task

Validate data against rules:

{
  "function": {
    "name": "validation",
    "input": {
      "rules": [
        {"logic": {"!!": {"var": "data.required"}}, "message": "Required field"}
      ]
    }
  }
}

Custom Function

Call registered functions:

{
  "function": {
    "name": "parse_mt",
    "input": {"source": "data.raw", "target": "data.parsed"}
  }
}

Datalogic →

Workflow Orchestration Guide →

Datafake

The test data generation library powering Reframe sample generation.

What is Datafake?

Datafake is a Rust library for generating realistic test data, compatible with the Faker.js API. It provides generators for common data types including financial identifiers.

In Reframe, Datafake generates sample SWIFT MT and ISO 20022 messages for testing.

Role in Reframe

Generate Request
{
  "message_type": "MT103",
  "scenario": "standard"
}
      │
      ▼
┌─────────────────────────────────────────────┐
│              Datafake Engine                │
│                                             │
│  Generate:                                  │
│  • BIC codes (sender/receiver)              │
│  • IBAN accounts                            │
│  • Currency amounts                         │
│  • Company names                            │
│  • Addresses                                │
│  • Transaction references                   │
│  • UUIDs (UETR)                             │
└─────────────────────────────────────────────┘
      │
      ▼
Sample Message

Key Features

Financial Data Generators

GeneratorExample Output
BICBNPAFRPPXXX
IBANFR7630006000011234567890189
CurrencyUSD, EUR, GBP
Amount50000.00
LEI5493001KJTIIGC8Y1R12

General Data Generators

GeneratorExample Output
Company nameAcme International Inc
Address123 Main Street, New York NY 10001
CountryUS, DE, GB
Date2025-01-15
UUIDf47ac10b-58cc-4372-a567-0e02b2c3d479

Deterministic Output

With seeding, generates reproducible data:

{
  "variables": {
    "ref": {"fake": ["uuid"]},
    "amount": {"fake": ["u64", 1000, 100000]}
  },
  "seed": 12345
}

Interactive Playground

Try Datafake generators in the browser:

Datafake Playground →

Resources

Scenario Configuration

Sample scenarios use Datafake in variable definitions:

{
  "description": "MT103 Standard Transfer",
  "variables": {
    "sender_bic": {"fake": ["bic"]},
    "receiver_bic": {"fake": ["bic"]},
    "currency": {"fake": ["enum", "USD", "EUR", "GBP"]},
    "amount": {"fake": ["u64", 5000, 500000]},
    "uetr": {"fake": ["uuid"]},
    "sender_name": {"fake": ["company_name"]},
    "receiver_name": {"fake": ["company_name"]},
    "reference": {"fake": ["alphanumeric", 16]}
  },
  "schema": {
    "basic_header": {
      "sender_bic": "{{sender_bic}}"
    },
    "fields": {
      "20": {"transaction_reference": "{{reference}}"},
      "32A": {
        "currency": "{{currency}}",
        "amount": "{{amount}}"
      }
    }
  }
}

Generator Types

String Generators

{"fake": ["alphanumeric", 10]}
{"fake": ["alpha", 5]}
{"fake": ["numeric", 8]}
{"fake": ["uuid"]}

Number Generators

{"fake": ["u64", 1000, 100000]}
{"fake": ["f64", 0.0, 100.0]}
{"fake": ["i32", -100, 100]}

Financial Generators

{"fake": ["bic"]}
{"fake": ["iban", "DE"]}
{"fake": ["currency_code"]}
{"fake": ["lei"]}

Selection Generators

{"fake": ["enum", "USD", "EUR", "GBP", "JPY"]}
{"fake": ["one_of", ["Option A", "Option B", "Option C"]]}

Date Generators

{"fake": ["date_future", 30]}
{"fake": ["date_past", 90]}
{"fake": ["datetime"]}

Datalogic →

Sample Generation Feature →

Message Types Reference

Complete list of supported SWIFT MT and ISO 20022 message types.

SWIFT MT Messages

Customer Payments (MT1xx)

TypeNameDescription
MT101Request for TransferCustomer request for multiple transfers
MT103Single Customer Credit TransferIndividual payment instruction
MT104Direct DebitDirect debit instruction
MT107General Direct DebitGeneral direct debit message

Cheques (MT1xx)

TypeNameDescription
MT110Advice of Cheque(s)Notification of cheque collection
MT111Stop Payment of a ChequeRequest to stop cheque payment
MT112Status of Request for Stop PaymentResponse to stop payment request

Cancellation & Investigation (MT19x/MT29x)

TypeNameDescription
MT192Request for CancellationCustomer payment cancellation request
MT196AnswersResponse to customer inquiries
MT199Free Format MessageGeneral purpose customer message
MT292Request for CancellationFI payment cancellation request
MT296AnswersResponse to FI inquiries
MT299Free Format Message for FIsGeneral purpose FI message

Financial Institution Transfers (MT2xx)

TypeNameDescription
MT200Financial Institution Transfer for Own AccountTransfer for bank’s own account
MT202General Financial Institution TransferFI-to-FI transfer
MT202COVCover PaymentCover for underlying customer payment
MT204Direct DebitFinancial institution direct debit
MT205Financial Institution Transfer ExecutionSerial FI transfer
MT205COVSerial Cover PaymentCover for serial transfers
MT210Notice to ReceiveNotification of incoming payment

Account Statements & Notifications (MT9xx)

TypeNameDescription
MT900Confirmation of DebitDebit confirmation to account owner
MT910Confirmation of CreditCredit confirmation to account owner
MT920Request MessageAccount statement request
MT935Rate Change AdviceInterest rate change notification
MT940Customer StatementEnd-of-day account statement
MT941Balance ReportAccount balance report
MT942Interim Transaction ReportIntraday transaction report
MT950Statement MessageFI account statement

ISO 20022 Messages

Payments Clearing & Settlement (pacs)

TypeNameDescription
pacs.002FIToFI Payment Status ReportPayment status notification
pacs.003FIToFI Customer Direct DebitDirect debit instruction
pacs.004Payment ReturnReturn of a payment
pacs.008FIToFI Customer Credit TransferCustomer payment instruction
pacs.009Financial Institution Credit TransferFI-to-FI transfer
pacs.010Financial Institution Direct DebitFI direct debit

Payment Initiation (pain)

TypeNameDescription
pain.001Customer Credit Transfer InitiationCustomer payment request
pain.008Customer Direct Debit InitiationDirect debit request

Cash Management (camt)

TypeNameDescription
camt.025ReceiptAcknowledgment of receipt
camt.029Resolution of InvestigationInvestigation response
camt.052Bank to Customer Account ReportIntraday account report
camt.053Bank to Customer StatementEnd-of-day statement
camt.054Bank to Customer Debit/Credit NotificationTransaction notification
camt.056FIToFI Payment Cancellation RequestPayment cancellation
camt.057Notification to Account OwnerAccount owner notification
camt.058Notification to Receive CancellationCancel notification to receive
camt.060Account Reporting RequestStatement request
camt.105Charges Payment NotificationCharges notification
camt.106Request for Payment of ChargesCharges request
camt.107Cheque Presentment NotificationCheque notification
camt.108Cheque Cancellation or Stop RequestStop cheque
camt.109Cheque Cancellation or Stop ReportStop cheque response

Administration (admi)

TypeNameDescription
admi.024System Event NotificationSystem event message

Error Codes Reference

Complete list of error codes returned by the Reframe API.

Error Response Format

{
  "success": false,
  "errors": [
    {
      "error_type": "validation_error",
      "code": "INVALID_FORMAT",
      "message": "Description of the error",
      "field": "field_name",
      "location": "Path or location",
      "details": { ... }
    }
  ]
}

Error Types

TypeDescription
parser_errorMessage parsing failed
validation_errorMessage failed validation
business_validation_errorBusiness rule violation
transformation_errorTransformation failed
schema_errorXSD schema violation
system_errorInternal system error

Parser Errors

CodeDescription
MT_PARSE_ERRORFailed to parse SWIFT MT message
XML_PARSE_ERRORFailed to parse XML message
INVALID_BLOCK_STRUCTUREInvalid SWIFT block structure
MISSING_REQUIRED_BLOCKRequired block is missing
INVALID_HEADERInvalid message header

Validation Errors

CodeDescription
INVALID_FORMATField format is invalid
INVALID_LENGTHField length exceeds limits
MISSING_REQUIRED_FIELDRequired field is missing
INVALID_FIELD_VALUEField value is not allowed
INVALID_CHARACTER_SETInvalid characters in field
INVALID_DATE_FORMATInvalid date or time format
INVALID_CURRENCY_CODEInvalid currency code
INVALID_AMOUNT_FORMATInvalid amount format
INVALID_BICInvalid BIC/SWIFT code
INVALID_IBANInvalid IBAN format

Business Validation Errors

CodeDescription
NVR_VIOLATIONNetwork Validation Rule violation
CBPR_VIOLATIONCBPR+ requirement not met
CROSS_FIELD_ERRORCross-field validation failed
CONDITIONAL_FIELD_ERRORConditional field requirement not met
DUPLICATE_REFERENCEDuplicate transaction reference
INVALID_DATE_RANGEDate range is invalid
CURRENCY_MISMATCHCurrency codes don’t match

Transformation Errors

CodeDescription
UNSUPPORTED_MESSAGE_TYPEMessage type not supported
UNSUPPORTED_SCENARIOTransformation scenario not found
MAPPING_ERRORField mapping failed
DATA_TRUNCATIONData was truncated during transformation
CHARACTER_CONVERSION_ERRORCharacter set conversion failed
TRANSFORMATION_FAILEDGeneral transformation failure

Schema Errors

CodeDescription
XSD_VALIDATION_ERRORXSD schema validation failed
INVALID_NAMESPACEInvalid XML namespace
INVALID_ELEMENTUnknown or invalid XML element
MISSING_REQUIRED_ELEMENTRequired XML element missing

System Errors

CodeDescription
INTERNAL_ERRORInternal server error
TIMEOUTOperation timed out
SERVICE_UNAVAILABLEService temporarily unavailable
CONFIGURATION_ERRORConfiguration error

Glossary

Key terms used in ISO 20022, SWIFT, and CBPR+ messaging.

ISO 20022 Terms

Business Application Header (BAH)

The header element in ISO 20022 messages containing routing and processing information. Includes sender/receiver BICs, message definition identifier, and creation timestamp.

Document

The root element of an ISO 20022 message containing the business payload. Each message type has a specific document structure defined by its XML schema.

Message Definition Identifier

A unique identifier for an ISO 20022 message type, following the pattern area.type.variant.version (e.g., pacs.008.001.12).

Message Type

A standardized ISO 20022 message format. Common types include:

  • pacs - Payments Clearing and Settlement
  • camt - Cash Management
  • pain - Payment Initiation

Schema

The XML Schema Definition (XSD) that defines the structure and validation rules for an ISO 20022 message.

Supplementary Data

Optional extension elements in ISO 20022 messages for carrying additional information not covered by the standard schema.


SWIFT Terms

Application Header

The second block of a SWIFT MT message containing message type, sender/receiver information, and processing details.

Basic Header

The first block of a SWIFT MT message identifying the application, service, and session information.

BIC (Bank Identifier Code)

An 8 or 11 character code that uniquely identifies a financial institution. Also known as SWIFT code.

Field Tag

A two or three character identifier for a data field in SWIFT MT messages (e.g., Tag 20, Tag 32A, Tag 50K).

FIN (Financial Information Network)

SWIFT’s messaging service for financial transaction messages using the MT format.

MT Message

SWIFT Message Type - the legacy text-based format for financial messages (e.g., MT103, MT202).

MX Message

SWIFT’s XML-based message format aligned with ISO 20022 standards.

Trailer Block

The fifth block of a SWIFT MT message containing message authentication and checksum information.

User Header

The third block of a SWIFT MT message containing optional banking priority and delivery information.


CBPR+ Terms

CBPR+ (Cross-Border Payments and Reporting Plus)

SWIFT’s guidelines for implementing ISO 20022 messages in cross-border payments, ensuring interoperability between financial institutions.

Coexistence Period

The transition period (2023-2025) during which both MT and MX message formats are supported for cross-border payments.

Market Practice

Agreed conventions for using ISO 20022 messages in specific contexts, ensuring consistent implementation across institutions.

SR2025 (Standards Release 2025)

SWIFT’s annual standards release for 2025, marking the end of the coexistence period and full transition to ISO 20022.

Translation Rules

The mapping specifications that define how MT message fields correspond to ISO 20022 elements and vice versa.

Usage Guidelines

CBPR+ documentation specifying how ISO 20022 messages should be structured and populated for cross-border payments.


Payment Terms

Charge Bearer

Indicates which party pays the transaction charges:

  • SHA (Shared) - Charges shared between parties
  • OUR - Sender pays all charges
  • BEN - Beneficiary pays all charges

Clearing System

The infrastructure for settling payments between financial institutions (e.g., CHIPS, Fedwire, TARGET2).

Credit Transfer

A payment instruction to move funds from debtor to creditor account.

Debtor

The party whose account is debited in a payment transaction (payer/sender).

Creditor

The party whose account is credited in a payment transaction (payee/beneficiary).

Instructing Agent

The financial institution instructing the next party in the payment chain.

Instructed Agent

The financial institution receiving the payment instruction.

Interbank Settlement Amount

The amount being transferred between financial institutions, excluding charges.

Interbank Settlement Date

The date on which the settlement between banks occurs.

Service Level

Indicates the type of processing for a payment:

  • G001 - SWIFT gpi (tracked payments)
  • G002 - SWIFT gpi for cover payments
  • G003 - SWIFT gpi for financial institution transfers
  • G004 - SWIFT gpi for direct debits

Settlement Method

How the payment is settled between banks:

  • INDA - Instructed Agent account
  • INGA - Instructing Agent account
  • COVE - Cover method
  • CLRG - Clearing system

UETR (Unique End-to-End Transaction Reference)

A UUID that uniquely identifies a payment throughout its lifecycle, used for gpi tracking.


Technical Terms

Dataflow

Reframe’s workflow orchestration engine that manages transformation pipelines.

Datalogic

Reframe’s JSONLogic implementation for evaluating business rules during transformation.

Datafake

Reframe’s test data generation library for creating sample messages.

Hot Reload

The ability to update transformation rules at runtime without restarting the service.

JSONLogic

A standard for expressing business logic as JSON, enabling portable and auditable rules.

Package

A collection of workflows and rules that define transformations for a specific message standard (e.g., CBPR+).

Pipeline

The sequence of processing stages a message passes through during transformation.

Workflow

A named set of tasks that execute in priority order during message processing.


Identifiers

IBAN (International Bank Account Number)

A standardized international account number format for identifying bank accounts.

A 20-character alphanumeric code that uniquely identifies legal entities in financial transactions.

MCC (Merchant Category Code)

A four-digit code classifying the type of business or merchant.

National ID

A country-specific identifier for organizations or individuals.


Message Categories

Customer Payments (MT1xx / pacs.008)

Messages for customer credit transfers initiated by corporate customers.

Financial Institution Transfers (MT2xx / pacs.009)

Messages for bank-to-bank transfers not involving customer accounts.

Cash Management (MT9xx / camt.xxx)

Messages for account statements, balance reports, and cash position management.

Securities (MT5xx)

Messages for securities trading, settlement, and custody operations.


Message Types Reference →

Error Codes Reference →

Frequently Asked Questions

Common questions about Reframe, the open source SWIFT MT to ISO 20022 transformation engine.


What is Reframe?

Reframe is an open source transformation engine for converting financial messages between formats. It specializes in SWIFT MT to ISO 20022 conversion using auditable JSONLogic rules.

Key features:

  • High-performance Rust engine with sub-millisecond latency
  • Transparent, auditable transformation rules
  • Free CBPR+ package with 41+ scenarios
  • Apache 2.0 licensed

Learn more about the architecture →


Is Reframe free to use?

Yes, Reframe is completely free and open source under the Apache 2.0 license. This includes:

  • The core Reframe transformation engine
  • The CBPR+ package with 41+ transformation scenarios
  • All documentation and examples

There are no licensing fees, usage limits, or hidden costs.

View the license on GitHub →


What is CBPR+ and does Reframe support it?

CBPR+ (Cross-Border Payments and Reporting Plus) is SWIFT’s framework for migrating from MT messages to ISO 20022.

Reframe includes a free CBPR+ package that supports:

TransformationDescription
MT103 → pacs.008Customer credit transfers
MT202 → pacs.009FI credit transfers
MT940 → camt.053Account statements
+ 38 more scenariosReturns, cancellations, status

Explore the CBPR+ Package →


Is Reframe SR2025 compliant?

Yes, the CBPR+ package is fully compliant with SWIFT Standards Release 2025 (SR2025), which becomes mandatory in November 2025.

SR2025 features supported:

  • Business Application Header v3
  • UETR (Unique End-to-End Transaction Reference)
  • Enhanced party identification with LEI
  • Structured remittance information
  • Latest message versions (pacs.008.001.12, etc.)

Learn about SR2025 compliance →


What message types does Reframe support?

SWIFT MT Messages

MT101, MT103, MT104, MT107, MT110, MT111, MT112, MT192, MT196, MT199, MT202, MT205, MT210, MT292, MT296, MT299, MT900, MT910, MT920, MT935, MT940, MT941, MT942, MT950

ISO 20022 Messages

pacs.002, pacs.003, pacs.008, pacs.009, pain.001, pain.008, camt.025, camt.029, camt.052, camt.053, camt.054, camt.056, camt.057, camt.060

View the complete message catalog →


How do I get started with Reframe?

Get started in under 5 minutes using Docker:

# Pull and run Reframe
docker run -d -p 3000:3000 plasmatic/reframe:latest

# Test the API
curl http://localhost:3000/health

Or try the interactive playground without any installation:

Try the Playground →

Read the Quick Start Guide →


What makes Reframe different from other transformation tools?

FeatureReframeProprietary Solutions
RulesAuditable JSONLogicBlack-box logic
LicenseApache 2.0 (Free)Expensive licensing
PerformanceSub-millisecond (Rust)Slower (JVM)
UpdatesHot-reload rulesVendor intervention
CustomizationFull access to rulesLimited or none

Learn about the open source advantage →


Can I use Reframe in production?

Yes, Reframe is production-ready with:

  • Health checks - Monitor service status
  • Hot-reload - Update rules without downtime
  • Kubernetes support - Enterprise deployment
  • High performance - Thousands of messages/second
  • Audit trails - Full transformation logging

Deployment guide →


Where can I get help?