Acks
هذا المحتوى غير متوفر بلغتك بعد.
The cursor answers what changed. Acks answer what haven’t you taken yet — which survives a lost cursor, a restored database or a purged staging table.
Rejecting an order the ERP can't book
POST /orders/ord_01J9X/ack
curl -X POST 'https://api.slflo.com/api/integration/v1/orders/ord_01J9X/ack' \ -H 'Authorization: Bearer $SLFLO_TOKEN' \ -H 'Idempotency-Key: SO-0012345' \ -H 'Content-Type: application/json' \ -d '{"outcome":"REJECTED","reason_code":"CUSTOMER_ON_HOLD","message":"Customer CUST-0042 is on hold in D365"}'Response
HTTP 200
{ "data": { "id": "ord_01J9X", "number": "SO-000123", "status": "ERP_FAILED", "version": 18343, "result": "applied", "ack": { "outcome": "REJECTED", "reason_code": "CUSTOMER_ON_HOLD", "message": "Customer CUST-0042 is on hold in D365", "external_ref": null, "external_number": null, "acked_version": 18343, "acked_at": "2026-10-05T10:42:00Z" } }}What an ack does
Section titled “What an ack does”- Order ACCEPTED → the order moves to
ERP_CONFIRMEDand remembers your key: it appears as the order’sexternal_ref, andfilter[external_ref]andGET /lookupfind it by it. - Order REJECTED → the order moves to
ERP_FAILED. The office sees yourmessageon the order and can send it again after fixing the cause (unblocking the customer, say). That makes it pending again, and your next pull sees it. - The ack is stored at a version —
ack.acked_versionin the answer. An order ack moves the order, so it is the order’s newversion. - Invoices, payments, returns:
POST /invoices/{id}/ack,/payments/{id}/ack,/returns/{id}/acktake the same body. The ack is kept at the version it answered: a document that changes after its ack — a reversed payment, a bounced cheque — is pending again until you ack its new version. That’s how you learn about it.
Many at once
Section titled “Many at once”POST /acks answers up to 500 documents of one kind — entity is order, invoice,
payment or return — in one request:
{"entity": "payment", "items": [{"id": "pay_01J9", "outcome": "ACCEPTED", "external_ref": "JRN-000881"}]}Each item gets its own result — applied, unchanged, or an error — and one bad item never
fails the rest.
Answers you may get
Section titled “Answers you may get”| Situation | Answer |
|---|---|
| The same ack again | unchanged |
| A different answer for an order you already answered | 409 ALREADY_ACKNOWLEDGED (unless the office sent it again since) |
| Your key already used for another record | 409 EXTERNAL_REF_CONFLICT |
| An order not waiting for the ERP | 409 ORDER_NOT_AWAITING_ACK |
| The company isn’t in ERP mode API (orders only) | 409 ERP_MODE_NOT_API — see ERP mode |
You may follow the cursor (stream style) or only filter[ack]=pending (queue style). The
reference connector uses the cursor plus acks, and falls back to pending after a cursor reset.
Try it
Section titled “Try it”Ack the sandbox’s first invoice with a journal number of yours, then send the same call again:
id=$(curl -sg "$SLFLO_BASE/invoices?filter[seq_after]=0&per_page=1" -H "Authorization: Bearer $SLFLO_TOKEN" | jq -r '.data[0].id')for try in 1 2; do curl -s -X POST "$SLFLO_BASE/invoices/$id/ack" -H "Authorization: Bearer $SLFLO_TOKEN" \ -H "Content-Type: application/json" -H "Idempotency-Key: ack-$id-$try" \ -d '{"outcome":"ACCEPTED","external_ref":"JRN-000001","external_number":"JRN-000001"}' | jq -c '.data | {result, acked_version: .ack.acked_version}'done# {"result":"applied","acked_version":…} then {"result":"unchanged","acked_version":…}On the shared sandbox someone may have acked it already: then you see unchanged (the same
answer) or 409 ALREADY_ACKNOWLEDGED (a different one), as the table above says.

