Refund reversals
When a payment is refunded or disputed, Kotally queues a refund reversal — a suggested credit clawback for the member who received the grant. Use these endpoints to review the queue and decide whether to apply or dismiss each item. Requires the refunds scope.
List pending reversals
Section titled “List pending reversals” GET
/api/v2/refund-reversals Requires ?location_id= matching the API client’s location.
curl "https://app.<your-domain>/api/v2/refund-reversals?location_id=loc_1" \ -H "Authorization: Bearer ktly_<your-token>"Response (200)
Section titled “Response (200)”{ "ok": true, "location_id": "loc_1", "pending": [ { "id": "rev_abc123", "status": "pending", "location_id": "loc_1", "contact_id": "kotally-contact-uuid", "entitlement_id": "kotally-entitlement-uuid", "original_payment_event_id": "pay_original", "refund_payment_event_id": "pay_refund", "granted_credits": 10, "suggested_credits": 10, "applied_credits": null, "created_at": "2026-05-01T12:00:00.000Z" } ]}Apply a reversal
Section titled “Apply a reversal” POST
/api/v2/refund-reversals/{id}/apply Claws back credits from the member’s entitlement. Idempotent via request_id. Optional credits overrides the suggested amount (must be positive and not exceed what was granted).
Request body
Section titled “Request body”| Field | Type | Required | Notes |
|---|---|---|---|
location_id | string | yes | Must match the API client’s location |
request_id | string | yes | Idempotency key |
credits | integer | no | Credits to claw back; defaults to suggested_credits |
curl -X POST "https://app.<your-domain>/api/v2/refund-reversals/rev_abc123/apply" \ -H "Authorization: Bearer ktly_<your-token>" \ -H "Content-Type: application/json" \ -d '{ "location_id": "loc_1", "request_id": "apply-rev-abc123" }'Response (200)
Section titled “Response (200)”{ "ok": true, "reason_code": "reversal_applied", "correlation_id": "a1b2c3d4-...", "id": "rev_abc123", "credits_reversed": 10, "reversal": { "id": "rev_abc123", "status": "applied", "contact_id": "kotally-contact-uuid", "applied_credits": 10 }}If the reversal was already resolved, reason_code is already_resolved.
Dismiss a reversal
Section titled “Dismiss a reversal” POST
/api/v2/refund-reversals/{id}/dismiss Keeps the member’s credits — use when the refund should not trigger a clawback. Idempotent via request_id.
Request body
Section titled “Request body”| Field | Type | Required | Notes |
|---|---|---|---|
location_id | string | yes | Must match the API client’s location |
request_id | string | yes | Idempotency key |
curl -X POST "https://app.<your-domain>/api/v2/refund-reversals/rev_abc123/dismiss" \ -H "Authorization: Bearer ktly_<your-token>" \ -H "Content-Type: application/json" \ -d '{ "location_id": "loc_1", "request_id": "dismiss-rev-abc123" }'Response (200)
Section titled “Response (200)”{ "ok": true, "reason_code": "reversal_dismissed", "correlation_id": "a1b2c3d4-...", "id": "rev_abc123", "reversal": { "id": "rev_abc123", "status": "dismissed", "contact_id": "kotally-contact-uuid" }}Errors
Section titled “Errors”| Status | When |
|---|---|
400 | Validation error (missing location_id or request_id) |
404 | Reversal not found for this location |
See the Overview for idempotency replay and the full error model.