Skip to main content
After running a matching job, you’ll need to review the results. This guide explains how to interpret match results, understand confidence scores, and approve or reject proposed matches.

Match status lifecycle


Matches progress through a defined lifecycle:
  • When the matching engine finds a pair of transactions that belong together, it creates a match in PROPOSED status.
  • High-confidence matches (score 90 or above) are auto-confirmed immediately.
  • Lower-confidence matches wait for manual review—an analyst can then confirm or reject them.
  • Rejected transactions return to the unmatched pool for another matching attempt.
Match Status Lifecycle

Status definitions

StatusDescriptionNext Actions
PROPOSEDMatch identified by the system, awaiting confirmationReview, confirm, or reject
CONFIRMEDMatch has been approved (auto or manual)No action needed
REJECTEDMatch was declinedTransactions return to unmatched pool

Confidence tiers


Matcher assigns a confidence score (0-100) to each proposed match. The score determines how the match is handled.

Confidence levels

TierScore rangeBehavior
Auto-Approved90-100High confidence matches are automatically confirmed without manual review.
Needs Review60-89Medium confidence matches require manual review before confirmation.
No MatchBelow 60Low confidence candidates are not proposed as matches and become exceptions.

Understanding the score

The confidence score is calculated from weighted components:
ComponentWeightWhat it Measures
Amount match40%How closely transaction amounts align
Currency match30%Whether currencies are the same
Date tolerance20%How close the transaction dates are
Rule match10%Whether a deterministic rule matched
Example Score Breakdown:
Match: BANK-001 ↔ LED-001

Amount: $1,000.00 vs $1,000.00 → 100% × 40% = 40 points
Currency: USD vs USD → 100% × 30% = 30 points
Date: 2024-01-15 vs 2024-01-15 → 100% × 20% = 20 points
Rule: EXACT rule matched → 100% × 10% = 10 points
 ─────────────────────────
Total Confidence: 100 points

Viewing match results


List matches for a context

cURL
curl -X GET "https://api.matcher.example.com/v1/contexts/ctx_abc123/matches" \
 -H "Authorization: Bearer $TOKEN"

Response

{
  "matches": [
    {
      "id": "match_001",
      "status": "CONFIRMED",
      "confidence": 100,
      "rule_id": "rule_exact001",
      "created_at": "2024-01-20T10:30:00Z",
      "confirmed_at": "2024-01-20T10:30:01Z",
      "items": [
        {
          "transaction_id": "txn_bank_001",
          "source_name": "Chase Bank",
          "amount": 1000.0,
          "currency": "USD",
          "date": "2024-01-15"
        },
        {
          "transaction_id": "txn_ledger_001",
          "source_name": "Main Ledger",
          "amount": 1000.0,
          "currency": "USD",
          "date": "2024-01-15"
        }
      ]
    },
    {
      "id": "match_002",
      "status": "PROPOSED",
      "confidence": 75,
      "rule_id": "rule_tolerance001",
      "created_at": "2024-01-20T10:30:00Z",
      "items": [
        {
          "transaction_id": "txn_bank_002",
          "source_name": "Chase Bank",
          "amount": 500.0,
          "currency": "USD",
          "date": "2024-01-16"
        },
        {
          "transaction_id": "txn_ledger_002",
          "source_name": "Main Ledger",
          "amount": 502.5,
          "currency": "USD",
          "date": "2024-01-17"
        }
      ]
    }
  ],
  "pagination": {
    "cursor": "eyJpZCI6Im1hdGNoXzAwMiJ9",
    "has_more": true
  }
}

Get match details

cURL
curl -X GET "https://api.matcher.example.com/v1/matches/match_002" \
 -H "Authorization: Bearer $TOKEN"

Response

{
  "id": "match_002",
  "status": "PROPOSED",
  "confidence": 75,
  "confidence_breakdown": {
    "amount": 35,
    "currency": 30,
    "date": 10,
    "rule": 0
  },
  "rule_id": "rule_tolerance001",
  "rule_name": "Amount Tolerance 1%",
  "context_id": "ctx_abc123",
  "created_at": "2024-01-20T10:30:00Z",
  "items": [
    {
      "transaction_id": "txn_bank_002",
      "source_id": "src_bank456",
      "source_name": "Chase Bank",
      "external_id": "BANK-2024-002",
      "amount": 500.0,
      "currency": "USD",
      "date": "2024-01-16",
      "reference": "Customer payment"
    },
    {
      "transaction_id": "txn_ledger_002",
      "source_id": "src_ledger789",
      "source_name": "Main Ledger",
      "external_id": "LED-2024-002",
      "amount": 502.5,
      "currency": "USD",
      "date": "2024-01-17",
      "reference": "Invoice #5678"
    }
  ],
  "variance": {
    "amount_diff": 2.5,
    "amount_diff_percent": 0.5,
    "date_diff_days": 1
  }
}

Filtering and searching


Filter matches to focus on items that need attention.

Filter by status

# Only proposed matches (need review)
curl -X GET "https://api.matcher.example.com/v1/contexts/ctx_abc123/matches?status=PROPOSED" \
 -H "Authorization: Bearer $TOKEN"

# Only confirmed matches
curl -X GET "https://api.matcher.example.com/v1/contexts/ctx_abc123/matches?status=CONFIRMED" \
 -H "Authorization: Bearer $TOKEN"

Filter by confidence range

# Low confidence matches (need careful review)
curl -X GET "https://api.matcher.example.com/v1/contexts/ctx_abc123/matches?confidence_min=60&confidence_max=75" \
 -H "Authorization: Bearer $TOKEN"

Filter by date range

# Matches from specific period
curl -X GET "https://api.matcher.example.com/v1/contexts/ctx_abc123/matches?date_from=2024-01-01&date_to=2024-01-31" \
 -H "Authorization: Bearer $TOKEN"

Filter by amount

# High-value matches
curl -X GET "https://api.matcher.example.com/v1/contexts/ctx_abc123/matches?amount_min=10000" \
 -H "Authorization: Bearer $TOKEN"

Combined filters

# Proposed high-value matches with low confidence
curl -X GET "https://api.matcher.example.com/v1/contexts/ctx_abc123/matches?status=PROPOSED&amount_min=10000&confidence_max=80" \
 -H "Authorization: Bearer $TOKEN"

Confirming matches


When you’ve reviewed a proposed match and determined it’s correct, confirm it.

Confirm single match

cURL
curl -X POST "https://api.matcher.example.com/v1/matches/match_002/confirm" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "notes": "Verified: $2.50 difference is bank fee"
 }'

Response

{
  "id": "match_002",
  "status": "CONFIRMED",
  "confirmed_at": "2024-01-20T14:30:00Z",
  "confirmed_by": "user_123",
  "notes": "Verified: $2.50 difference is bank fee"
}

Bulk confirm matches

Confirm multiple matches at once:
cURL
curl -X POST "https://api.matcher.example.com/v1/matches/bulk-confirm" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "match_ids": [
     "match_002",
     "match_003",
     "match_004"
   ],
   "notes": "Bulk approved after review"
 }'

Response

{
  "confirmed": 3,
  "failed": 0,
  "results": [
    {
      "id": "match_002",
      "status": "CONFIRMED"
    },
    {
      "id": "match_003",
      "status": "CONFIRMED"
    },
    {
      "id": "match_004",
      "status": "CONFIRMED"
    }
  ]
}

Confirm by filter

Confirm all matches meeting certain criteria:
# Confirm all proposed matches with confidence >= 85
curl -X POST "https://api.matcher.example.com/v1/contexts/ctx_abc123/matches/bulk-confirm" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "filter": {
     "status": "PROPOSED",
     "confidence_min": 85
   },
   "notes": "Approved: high confidence matches"
 }'

Rejecting matches


If a proposed match is incorrect, reject it. The transactions will return to the unmatched pool.

Reject single match

cURL
curl -X POST "https://api.matcher.example.com/v1/matches/match_005/reject" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "reason": "Different customers - BANK-005 is for Acme Corp, LED-005 is for Beta Inc",
   "notes": "Reference numbers appeared similar but belong to different invoices"
 }'

Response

{
  "id": "match_005",
  "status": "REJECTED",
  "rejected_at": "2024-01-20T14:45:00Z",
  "rejected_by": "user_123",
  "reason": "Different customers - BANK-005 is for Acme Corp, LED-005 is for Beta Inc"
}

What happens after rejection

When a match is rejected:
  1. The match record is marked as REJECTED
  2. All transactions in the match return to the unmatched pool
  3. Transactions may be matched again in the next matching run
  4. If no other match is found, they become exceptions

Reversing confirmed matches (unmatch)


Sometimes you need to reverse a confirmed match because it was approved incorrectly. The unmatch operation breaks an existing match and returns transactions to the unmatched pool.
Unmatching a confirmed match creates a full audit trail and may trigger approval workflows. This operation should be used carefully and only when necessary.

When to unmatch

Common scenarios for unmatching:
  • Incorrect match confirmed: The match was approved but transactions actually belong to different records
  • New information: Additional data shows the match is wrong
  • Source correction: The source system issued a correction or reversal
  • Duplicate transaction: One of the transactions was a duplicate that should be removed

Unmatch a confirmed match

cURL
curl -X POST "https://api.matcher.example.com/v1/matches/match_001/unmatch" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "reason": "INCORRECT_MATCH",
   "notes": "Bank txn is for Invoice #1234, ledger txn is for Invoice #5678. Different customers.",
   "require_approval": false
 }'

Response

{
  "match_id": "match_001",
  "status": "UNMATCHED",
  "unmatched_at": "2024-01-20T15:45:00Z",
  "unmatched_by": "user_456",
  "reason": "INCORRECT_MATCH",
  "notes": "Bank txn is for Invoice #1234, ledger txn is for Invoice #5678. Different customers.",
  "original_match": {
    "confirmed_at": "2024-01-15T10:00:00Z",
    "confirmed_by": "user_123",
    "confidence": 85
  },
  "action": {
    "exceptions_created": [
      "exc_new_001",
      "exc_new_002"
    ],
    "status": "Both transactions returned to unmatched pool"
  }
}

Unmatch reasons

ReasonDescriptionTypical Scenario
INCORRECT_MATCHMatch was wrongDifferent invoices/customers
SOURCE_CORRECTIONSource system issued correctionBank reversal, ledger adjustment
DUPLICATE_TRANSACTIONOne transaction is a duplicateImport error, double-posting
DATA_ERRORTransaction data was incorrectWrong amount entered
MANUAL_OVERRIDEOverride previous decisionNew information available

Unmatch with approval requirement

For high-value or sensitive matches, require manager approval:
cURL
curl -X POST "https://api.matcher.example.com/v1/matches/match_large_001/unmatch" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "reason": "INCORRECT_MATCH",
   "notes": "Match involves $500K transaction - requires verification",
   "require_approval": true,
   "approve_by": "user_manager"
 }'

Response

{
  "match_id": "match_large_001",
  "status": "PENDING_UNMATCH_APPROVAL",
  "unmatch_requested_at": "2024-01-20T15:45:00Z",
  "unmatch_requested_by": "user_456",
  "reason": "INCORRECT_MATCH",
  "approval": {
    "required": true,
    "approver": "user_manager",
    "status": "PENDING"
  },
  "original_match": {
    "amount": 500000.0,
    "confirmed_at": "2024-01-15T10:00:00Z"
  }
}

Approve unmatch request

Manager approves the unmatch:
curl -X POST "https://api.matcher.example.com/v1/matches/match_large_001/approve-unmatch" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "approved": true,
   "notes": "Reviewed and approved - transactions are for different entities"
 }'

What happens after unmatch

When a match is unmatched:
  1. Match status changes: From CONFIRMED to UNMATCHED
  2. Audit trail created: Full record of who unmatched and why
  3. Transactions returned: All transactions return to unmatched pool
  4. Exceptions created: New exceptions are created for each transaction
  5. Webhook triggered: match.unmatched event is emitted
  6. Re-matching possible: Transactions can be matched again in next run

Bulk unmatch

Unmatch multiple matches at once (requires elevated permissions):
cURL
curl -X POST "https://api.matcher.example.com/v1/matches/bulk-unmatch" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "match_ids": [
     "match_001",
     "match_002",
     "match_003"
   ],
   "reason": "SOURCE_CORRECTION",
   "notes": "Bank issued correction file - all matches from 2024-01-15 are invalid",
   "require_approval": true
 }'

Unmatch by filter

Unmatch all matches meeting criteria (requires admin permissions):
curl -X POST "https://api.matcher.example.com/v1/contexts/ctx_abc123/matches/bulk-unmatch" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "filter": {
     "date_from": "2024-01-15",
     "date_to": "2024-01-15",
     "source_id": "src_bank456"
   },
   "reason": "SOURCE_CORRECTION",
   "notes": "Bank correction file received - all Jan 15 transactions need rematch",
   "require_approval": true,
   "approve_by": "user_director"
 }'
Bulk unmatch by filter is a powerful operation that can affect many matches. Always use with require_approval: true and carefully review the filter criteria.

Unmatch permissions

Different unmatch operations require different permission levels:
OperationRequired PermissionNotes
Unmatch single matchmatching:match:unmatchStandard operation
Unmatch without approvalmatching:match:unmatchFor low-value matches
Unmatch with approvalmatching:match:unmatchTriggers approval workflow
Bulk unmatch (limited)matching:match:bulk_unmatchMax 50 matches
Bulk unmatch by filtermatching:match:admin_unmatchNo limit, requires approval

Viewing unmatch history

See all unmatch operations for a context:
curl -X GET "https://api.matcher.example.com/v1/contexts/ctx_abc123/unmatches" \
 -H "Authorization: Bearer $TOKEN" \
 -G \
 -d "date_from=2024-01-01"

Response

{
  "unmatches": [
    {
      "match_id": "match_001",
      "unmatched_at": "2024-01-20T15:45:00Z",
      "unmatched_by": "user_456",
      "reason": "INCORRECT_MATCH",
      "original_confirmation": {
        "confirmed_at": "2024-01-15T10:00:00Z",
        "confirmed_by": "user_123",
        "confidence": 85
      },
      "approval_required": false,
      "exceptions_created": 2
    }
  ],
  "summary": {
    "total_unmatches": 15,
    "by_reason": {
      "INCORRECT_MATCH": 8,
      "SOURCE_CORRECTION": 4,
      "DUPLICATE_TRANSACTION": 3
    }
  }
}

Best practices

Always provide detailed notes explaining why the unmatch is necessary. This helps with audits and future investigations.
Set amount thresholds that require manager approval before unmatching (e.g., matches > $10,000).
Check the newly created exceptions to ensure they’re properly categorized and assigned.
If you’re unmatching many matches, review your match rules - they may need adjustment.
Track unmatch frequency by user, reason, and source. Patterns may indicate training needs or process issues.

Match review workflow


A typical daily review workflow:
1

Check Summary

Review the match run summary to understand overall results.
curl -X GET "https://api.matcher.example.com/v1/jobs/run_123/summary" \
-H "Authorization: Bearer $TOKEN"
2

Review Low Confidence

Focus on proposed matches with confidence 60-80 that need careful review.
curl -X GET "https://api.matcher.example.com/v1/contexts/ctx_abc123/matches?status=PROPOSED&confidence_max=80" \
-H "Authorization: Bearer $TOKEN"
3

Confirm Valid Matches

Approve matches that are correct after verification.
4

Reject Invalid Matches

Reject matches that are incorrect so transactions can be re-matched.
5

Bulk Approve Remaining

After individual review, bulk approve remaining high-confidence matches.

Understanding variances


When matches have differences, review the variance details:

Amount variance

{
  "variance": {
    "amount_diff": 2.5,
    "amount_diff_percent": 0.5
  }
}
Common causes of amount variance:
  • Bank fees
  • Currency conversion differences
  • Rounding differences
  • Partial payments

Date variance

{
  "variance": {
    "date_diff_days": 2
  }
}
Common causes of date variance:
  • Settlement timing
  • Time zone differences
  • Posting vs. transaction date
  • Weekend/holiday processing

Audit trail


All match confirmations and rejections are recorded in the audit log:
curl -X GET "https://api.matcher.example.com/v1/matches/match_002/audit" \
 -H "Authorization: Bearer $TOKEN"
{
  "events": [
    {
      "timestamp": "2024-01-20T10:30:00Z",
      "action": "CREATED",
      "user": "system",
      "details": {
        "confidence": 75,
        "rule": "rule_tolerance001"
      }
    },
    {
      "timestamp": "2024-01-20T14:30:00Z",
      "action": "CONFIRMED",
      "user": "user_123",
      "details": {
        "notes": "Verified: $2.50 difference is bank fee"
      }
    }
  ]
}

Best practices


Review matches with the lowest confidence scores first. These are most likely to be incorrect and need the most attention.
If you find yourself rejecting many auto-approved matches, consider raising the auto-approval threshold. If you’re approving most 60-70% matches, consider lowering the review threshold.
Always add notes when confirming or rejecting matches. This creates an audit trail and helps team members understand the reasoning.
Bulk confirm is efficient but use it only after reviewing a sample. Never bulk confirm without understanding what you’re approving.
Regardless of confidence score, give extra attention to high-value matches. The impact of an incorrect match is proportional to the amount.

Next steps