# Invoice matching

Accounts payable sends a batch of invoices. Momor fetches every invoice’s purchase order at once, compares each pair, and asks about any invoice that differs before it is approved or held.

- **Trigger:** Accounts payable API key
- **Steps:** 3
- **Waits for:** Accounts payable, only when an invoice differs
- **Uses:** ERP tool server

Trigger: Accounts payable → Loop: Fetch each order → Data: Hand them over → Model: Compare → Wait: Ask about differences → Output: Respond

[Open in Designer](/workflows/designer)

## How it works

- **Fetch.** For each runs the ERP’s purchase-order tool once per invoice, all at once. A retry fetches only the orders that failed.
- **Hand over.** Deliver results puts every purchase order into the conversation, beside the invoices the request carried.
- **Compare.** Ask the model compares each invoice with its order. Where they differ, it asks accounts payable, naming the invoice and the difference, and waits for the answer.
- **Respond.** The comparison’s reply lists every invoice as Matched, Approved or Held, and is the run’s result.

> **The model writes the question**
> Listing `Clarification` in the model step’s `Operations` lets the model ask, in its own words, as often as the batch needs. Each question is a wait on the run; the model continues once it has the answers. Compare the fixed question a `Wait` step asks in [Refund approval](/docs/workflows/examples/refund-approval/).

## The workflow

```yaml title="InvoiceMatching.yaml"
Workflow: InvoiceMatching
Description: Matches each invoice in a batch against its purchase order and asks about any that differ.
Triggers:
  - New: Batch
    Schema:
      type: object
      required: [Invoices]
      properties:
        Invoices:
          type: array
          items:
            type: object
            required: [Number, PurchaseOrder, Amount]
            properties:
              Number: { type: string }
              PurchaseOrder: { type: string }
              Amount: { type: number }
Operations:
  - Tool: PurchaseOrders
    Locator: mcp://7d3a0c19-6e42-4b85-a1f9-58c2e0b4d6a3/get_purchase_order
  - Wait: Clarification
    Locator: embedded://momor.ai/services/tools/clarification
Output:
  Structured:
    type: object
    required: [Invoices]
    properties:
      Invoices:
        type: array
        items:
          type: object
          required: [Number, Status]
          properties:
            Number: { type: string }
            Status: { type: string, enum: [Matched, Approved, Held] }
            Note: { type: string }
Steps:
  - ForEach: Orders
    Items: { Field: Trigger.Invoices }
    Each: Invoice
    Operation: PurchaseOrders
    Input:
      number: { Field: Invoice.PurchaseOrder }
    Attempts: 2
  - DeliverResults: HandOver
  - ModelCall: Compare
    Instructions: >-
      Compare each invoice in the request with its purchase order. Where the amount or the lines differ,
      ask accounts payable whether to approve it, naming the invoice and the difference.
      Then list every invoice as Matched, Approved or Held.
    Operations: [Clarification]
    Output:
      Structured:
        type: object
        required: [Invoices]
        properties:
          Invoices:
            type: array
            items:
              type: object
              required: [Number, Status]
              properties:
                Number: { type: string }
                Status: { type: string, enum: [Matched, Approved, Held] }
                Note: { type: string }
```

> **Before you upload it**
> Replace the `mcp://` locator with your ERP tool server’s connection id and tool name, and the `number` input with the field that tool expects.
