Po Acknowledgment Matcher
Pricing
Pay per usage
Po Acknowledgment Matcher
Pricing
Pay per usage
Rating
0.0
(0)
Developer
ceeb
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
20 days ago
Last modified
Categories
Share
A conservative, machine-callable Apify Actor that compares a normalized purchase order with a supplier acknowledgment and returns structured discrepancies.
The V0 goal is narrow: answer "What did the supplier change?" without trying to become an ERP, procurement platform, or workflow system.
Current scope
V0 accepts normalized JSON in a standard Actor run or over the Standby HTTP API.
For a standard run, use example-input.json as the input. The run compares one
document pair, writes one comparison to its default dataset, and exits. Invalid
input fails without writing a comparison. Standby runs retain the HTTP endpoints
below and return results directly without writing a dataset. No billing event is
implemented in either mode.
It compares:
- purchase-order number
- supplier identity
- currency
- freight and document total
- line number and SKU
- quantity
- unit of measure
- unit price
- requested vs. confirmed delivery date
- acknowledgment line status
- missing PO lines
- extra acknowledgment lines
Matching is deliberately conservative:
- exact line number is preferred
- otherwise an exact unique SKU may match
- candidates are checked across both complete documents before pairing; contested candidates are always
REVIEW - the Actor never guesses an ambiguous line match
- numeric and date comparisons are deterministic after normalization
PDF extraction is intentionally deferred until the normalized matcher passes its benchmark suite.
API
Health
GET /GET /health
Compare
POST /matchContent-Type: application/json
Example request:
{"purchase_order": {"document_id": "PO-1001","supplier": {"id": "ACME"},"currency": "USD","freight": 0,"total": 1840,"lines": [{"line_number": "10","sku": "ABC-492","quantity": 100,"uom": "EA","unit_price": 18.40,"requested_date": "2026-10-12"}]},"acknowledgment": {"document_id": "ACK-77","purchase_order_number": "PO-1001","supplier": {"id": "ACME"},"currency": "USD","freight": 0,"total": 1915,"lines": [{"line_number": "10","sku": "ABC-492","quantity": 100,"uom": "EA","unit_price": 19.15,"confirmed_date": "2026-11-03","status": "accepted"}]}}
Example response:
{"status": "REVIEW","purchase_order_number": "PO-1001","acknowledgment_id": "ACK-77","summary": {"purchase_order_lines": 1,"acknowledgment_lines": 1,"matched_lines": 0,"review_lines": 1,"missing_lines": 0,"extra_lines": 0,"exception_count": 3},"exceptions": [{"code": "TOTAL_CHANGED","status": "REVIEW","field": "total","ordered": 1840,"acknowledged": 1915,"po_line": null,"ack_line": null,"sku": null,"delta": 75.0,"delta_pct": 4.0760869565,"evidence": {"purchase_order": {"path": "purchase_order.total", "value": 1840},"acknowledgment": {"path": "acknowledgment.total", "value": 1915}}}],"line_results": []}
The actual response includes every detected exception and every matched/missing/extra line result.
Optional tolerances
{"tolerances": {"price_abs": 0.01,"price_pct": 0,"quantity_abs": 0,"date_days": 0}}
A price difference is flagged only when it exceeds both the absolute and percentage thresholds.
Input validation
Both documents must provide a lines array of objects, and the PO must contain at least one line. An empty acknowledgment array is valid and reports missing PO lines. Null, empty, and whitespace-only acknowledgment values require review when the corresponding PO value is populated, including freight and total.
Supplied numbers and dates are validated even on unmatched lines. Numbers must be finite; nonzero numeric magnitudes must be at least 1e-100 and less than 1e101, keeping delta calculations representable in JSON. Tolerances must be nonnegative, and date_days must be an integer. Identifiers and text fields accept strings or numbers, not arrays, objects, or booleans.
Malformed JSON or invalid encoding returns HTTP 400; invalid document input returns HTTP 422; bodies over 2 MiB return HTTP 413. HTTP results are returned directly, without writing a dataset.
MATCH applies to the supplied PO fields; it does not establish that an upstream extraction captured every required business field.
Result statuses
MATCH— no configured discrepancy foundREVIEW— one or more discrepancies or ambiguities require attentionMISSING_IN_ACK— a PO line could not be found in the acknowledgmentEXTRA_IN_ACK— an acknowledgment line could not be tied to a PO line
Safety invariant
The commercial benchmark is asymmetric:
A doubtful line may become REVIEW, but it must never become a false MATCH.
That principle takes precedence over maximizing automatic match rate.
Development
Run unit tests:
$python -m unittest discover -s tests -v
Run the Actor locally with the Apify CLI:
$apify run
The Actor keeps the Apify Standby readiness endpoint required by the template.
V0 benchmark cases
The included tests cover:
- exact match
- changed price
- changed delivery date
- missing line
- extra line
- SKU fallback matching
- ambiguous duplicate SKU
- PO number mismatch
- supplier mismatch
- tolerances
- non-accepted line status
- invalid dates and malformed/non-finite values
- blank acknowledgment fields and missing document amounts
- contested candidates on either side and input-order invariance
- 100-line synthetic documents with price, quantity, and date changes
- HTTP health/readiness, error responses, body limits, and abort cleanup
CI runs the matcher and HTTP tests on Python 3.12 and 3.14 (the Docker runtime). The next publication gate is a private platform benchmark with representative procurement documents and zero false MATCH results. Local tests do not substitute for platform validation.
Not in V0
- OCR
- PDF parsing
- ERP integrations
- user accounts
- dashboards
- write-back to purchasing systems
- automatic approval/rejection decisions
- billing or monetization logic
