Returns Intelligence

Classify a return request, evaluate it against your return policy, and get a suggested next step.

Endpoint
POST https://kovca.io/api/v1/returns/triage

Authenticate with your API key in the Authorization: Bearer header. Kovca suggests actions; it doesn't approve, reject, or process returns.

Request body

FieldTypeDescription
customer_messagestring, requiredThe customer's request in their own words. 1–4,000 characters.
product.namestring, optionalProduct name, up to 200 characters.
product.categorystring, optionalProduct category, up to 100 characters.
order.days_since_deliveryinteger, optionalWhole days between delivery and the request, 0–3650.
return_policy.window_daysinteger, optionalReturn window in days, 0–3650.
return_policy.exceptionsstring[], optionalUp to 10 exceptions in your own words, 500 characters each.
Example request
{
  "customer_message": "I bought these headphones 45 days ago and the left speaker stopped working. I'd like a refund.",
  "product": {
    "name": "Wireless Headphones",
    "category": "electronics"
  },
  "order": {
    "days_since_delivery": 45
  },
  "return_policy": {
    "window_days": 30,
    "exceptions": [
      "Defective products may qualify for additional review"
    ]
  }
}

Response

200 OK
{
  "request_id": "req_3nWq8ZtLs2KfP0aV",
  "reason": "defective",
  "priority": "medium",
  "suggested_action": "manual_review",
  "requires_human_review": true,
  "eligibility": {
    "status": "requires_review"
  },
  "signals": [
    "outside_return_window",
    "policy_exception_may_apply",
    "reported_defect"
  ],
  "missing_information": []
}
FieldTypeDescription
request_idstringUnique ID for this request.
reason"defective" | "damaged" | "wrong_item" | "not_as_described" | "changed_mind" | "missing_parts" | "delivery_issue" | "other"Why the customer wants to return the item.
priority"low" | "medium" | "high"Operational urgency, not the customer's tone.
suggested_action"approve_for_processing" | "request_information" | "troubleshoot" | "offer_replacement" | "manual_review" | "reject_request"The recommended next step. See below.
requires_human_reviewbooleanTrue when the action is manual_review, the priority is high, or urgency is unclear.
eligibility.status"eligible" | "ineligible" | "requires_review" | "insufficient_information" | "not_evaluated"Result of applying your return policy. See below.
signalsstring[]Observations from the list below. Order is not significant.
missing_information("days_since_delivery" | "return_reason")[]Facts needed before Kovca can go further.

Return reasons

  • defective: The item does not work or stopped working properly.
  • damaged: The item arrived physically damaged, broken, dented, or scratched.
  • wrong_item: The customer received a different item, size, color, or model than they ordered.
  • not_as_described: The item works but differs from its description, listing, or photos.
  • changed_mind: The customer no longer wants the item, ordered by mistake, or found a better price.
  • missing_parts: The package is missing parts, accessories, or some of the ordered items.
  • delivery_issue: The item never arrived, was lost in transit, or arrived far too late to be useful.
  • other: Some other reason that does not fit the options above.

Eligibility

Eligibility is computed from the numbers you send. It isn't inferred, and Kovca never invents policies, warranty terms, or legal rights.

  • eligible: days_since_delivery is less than or equal to window_days.
  • ineligible: days_since_delivery is greater than window_days and no supplied exception applies.
  • requires_review: Outside the window but an exception may apply, the policy has no window_days, or the item never arrived.
  • insufficient_information: The policy has window_days but days_since_delivery was not supplied.
  • not_evaluated: No return_policy was supplied. Kovca never assumes a policy.

Suggested actions

Kovca applies these in order and returns the first that matches.

  1. manual_review if the request contains conflicting information.
  2. request_information if the reason is unclear or eligibility needs days_since_delivery.
  3. reject_request if eligibility is ineligible.
  4. manual_review if eligibility is requires_review.
  5. troubleshoot for a defect that troubleshooting often fixes.
  6. offer_replacement when the customer asks for one for a defective, damaged, wrong, or incomplete item.
  7. approve_for_processing if eligibility is eligible.
  8. manual_review otherwise, including when no policy was supplied.
  • approve_for_processing: The supplied policy and facts support the return. Only suggested when a return window was evaluated as eligible.
  • request_information: Ask the customer or your systems for the missing information listed in missing_information.
  • troubleshoot: Offer troubleshooting before processing a return.
  • offer_replacement: The customer asked for a replacement for a faulty, damaged, wrong, or incomplete item.
  • manual_review: A person should decide, for example because of a possible policy exception, conflicting details, or no policy.
  • reject_request: The request is outside the supplied return window and none of the supplied exceptions applies.

Signals

  • reported_defect: The customer reports that the item doesn't work.
  • within_return_window: Days since delivery are within the policy's return window.
  • outside_return_window: Days since delivery exceed the policy's return window.
  • policy_exception_may_apply: One of the supplied policy exceptions may cover this request.
  • missing_order_details: The policy has a return window but days_since_delivery was not supplied.
  • conflicting_information: The message contradicts itself or the supplied order or product details. This is an observation, not a finding of fraud.
  • reason_unclear: The message doesn't make the reason for the return clear.
  • troubleshooting_may_resolve: The reported fault is the kind that setup or a reset often fixes.
  • replacement_requested: The customer asks for a replacement or exchange rather than a refund.
  • delivery_not_confirmed: The customer says the item never arrived, so the delivery-based return window can't be applied.

Ambiguous requests

When the reason is unclear, Kovca returns reason_unclear, adds return_reason to missing_information, and suggests request_information. In that case reason is the closest match and should not be relied on. Conflicting details always go to a person.

Examples

curl https://kovca.io/api/v1/returns/triage \
  -H "Authorization: Bearer $KOVCA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "customer_message": "I bought these headphones 45 days ago and the left speaker stopped working. I'\''d like a refund.",
  "product": {
    "name": "Wireless Headphones",
    "category": "electronics"
  },
  "order": {
    "days_since_delivery": 45
  },
  "return_policy": {
    "window_days": 30,
    "exceptions": [
      "Defective products may qualify for additional review"
    ]
  }
}'

Errors

  • 400 INVALID_REQUEST: a field is missing, the wrong type, out of range, or not allowed. The message names the field.
  • 401 UNAUTHORIZED, 429 RATE_LIMITED, 503 SERVICE_UNAVAILABLE, 504 TIMEOUT: see Errors and limits.

Limitations

  • Kovca evaluates only the policy you send. It doesn't know your platform's policies, warranties, or consumer law.
  • Exceptions are matched by meaning, not applied automatically. A matching exception sends the request to review; it never approves it.
  • Signals are observations to help your team, not findings of fraud.
  • The message and context are processed to produce the result and are not stored by Kovca.