Skip to main content

Submit a Return

Call /v1/return when a customer initiates a return. Pinch evaluates the return against your Returns workflow and emits a decision for each returned line item.

Request​

POST /v1/return HTTP/1.1
Host: api.pinch.ai
Authorization: {api-key}
Content-Type: application/json

Body​

FieldTypeRequiredDescription
providerOrderIdstringyesThe order this return is against. Must match a previously sent order.
providerReturnIdstringyesYour platform's return identifier. Unique within your account.
statusstringyesREQUESTED, APPROVED, RECEIVED, COMPLETED, CANCELLED.
reasonstringyesCustomer-provided reason at the return level.
returnMethodobjectyes{ returnMethod } — Drop-Off, Pickup, In-Store.
refundModeobjectyes{ refundMode } — ORIGINAL_PAYMENT, STORE_CREDIT, EXCHANGE.
returnedLineItemsarrayyesSee returnedLineItems.
deviceFingerprintsarrayrecommendedSame shape as the Order API.
timestampstringyesEpoch ms as a string.

Returned line items​

Each entry in returnedLineItems:

FieldTypeRequiredDescription
lineItem.identifiersarrayyesSame identifier shape as the Order API. Must reference an item from the original order.
categorystringnoProduct category.
quantitystringyesQuantity being returned.
reasonstringyesPer-item reason.

Example request​

curl https://api.pinch.ai/v1/return \
-H "Authorization: {api-key}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"providerOrderId": "MC229151G",
"providerReturnId": "WETIIO2PG",
"status": "REQUESTED",
"reason": "Return - No longer want",
"returnMethod": { "returnMethod": "Drop-Off" },
"refundMode": { "refundMode": "ORIGINAL_PAYMENT" },
"returnedLineItems": [
{
"lineItem": {
"identifiers": [
{ "identifierType": "UPC", "identifier": "26SDSDSMC30" }
]
},
"category": "Dress",
"quantity": "1",
"reason": "Return - No longer want"
}
],
"deviceFingerprints": [{ "deviceIdentifier": "abc123visitorId" }],
"timestamp": "1721050915000"
}'

Response​

The response includes a decision per returned line item.

{
"providerReturnId": "WETIIO2PG",
"pinchReturnId": "pret_3f8a1c",
"returnedLineItems": [
{
"lineItem": {
"identifierType": "UPC",
"identifier": "26SDSDSMC30"
},
"decisionType": "APPROVE/DECLINE/REVIEW",
"decision": "APPROVE",
"subDecision": "High Customer Value",
"reason": "Customer Value Per Email exceeds VIP threshold",
"abuseScore": 18
}
]
}
FieldDescription
providerReturnIdEcho of your providerReturnId.
pinchReturnIdPinch's internal return identifier.
returnedLineItems[].decisionAPPROVE, DECLINE, or REVIEW.
returnedLineItems[].subDecisionThe specific workflow branch that matched.
returnedLineItems[].reasonWhy this decision was made.
returnedLineItems[].abuseScore0–100 abuse risk score at return time.

Decision semantics​

DecisionWhat you should do
APPROVEAccept the return and process the refund per your normal flow.
DECLINEBlock the return. Your RMS should refuse to issue a return label or refund.
REVIEWRoute to manual review. The return appears in the Pinch dashboard's Review queue with AI Analysis. Approve or deny from there before processing.

In a typical Shopify deployment, you don't act on the response directly — Pinch writes an customer tag (e.g. Pinch - Deny : Egregious) that your RMS reads. The API response is most useful for custom integrations.

Errors​

HTTPCodeMeaning
400invalid_requestMissing required field.
401unauthenticatedAPI key missing or invalid.
404order_not_foundThe referenced providerOrderId doesn't exist in Pinch. Send the order first.
409duplicate_returnproviderReturnId already exists.
422unprocessable_entityField values failed validation.
429rate_limitedSlow down.

See also​