Skip to content

Warranty claims

Warranty claims track post-repair issues on tickets that are still inside your shop’s warranty window. Coverage is derived: a ticket is covered when the shop’s warranty period, counted from the ticket’s latest paid invoice, has not yet expired. A claim opens against a covered ticket, moves through a status lifecycle — open → approved / rejected, then approved → resolved / rejected — and can link the no-charge rework ticket created to fix the issue.

{
"object": "warranty_claim",
"id": 27,
"ticket_id": "TK-10042",
"rework_ticket_id": "TK-10113",
"status": "approved",
"reason": "Screen developed dead pixels two weeks after replacement.",
"resolution_notes": null,
"warranty_expires_at": "2026-08-30T00:00:00.000Z",
"created_at": "2026-07-01T15:20:00.000Z",
"resolved_at": null
}
FieldTypeDescription
idintegerUnique claim ID
ticket_idstringThe original (covered) ticket
rework_ticket_idstring|nullThe linked no-charge rework ticket, when one exists
statusstringopen, approved, rejected, or resolved
reasonstring|nullWhy the claim was opened
resolution_notesstring|nullNotes recorded while resolving
warranty_expires_atstring|nullThe coverage expiry snapshotted when the claim opened
created_atstring|nullISO-8601 creation timestamp
resolved_atstring|nullISO-8601 resolution timestamp

GET /api/v1/warranty_claims

Returns a cursor-paginated list of warranty claims, newest first. Filter by ticket_id or status.

Scope required: warranty.read

ParameterTypeDescription
ticket_idstringFilter to one ticket’s claims
statusstringFilter by claim status: open, approved, rejected, resolved
limitintegerPage size, 1–100 (default: 25)
cursorstringOpaque cursor from a previous response’s next_cursor
Terminal window
curl "https://app.benchkey.com/api/v1/warranty_claims?status=open" \
-H "Authorization: Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa"
const res = await fetch(
"https://app.benchkey.com/api/v1/warranty_claims?status=open",
{ headers: { Authorization: "Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa" } }
);
const { data, has_more, next_cursor } = await res.json();
{
"object": "list",
"data": [ { "object": "warranty_claim", "id": 27, "status": "open", "..." } ],
"has_more": false,
"next_cursor": null
}

See Pagination for how to page through results.


GET /api/v1/warranty_claims/:id

Returns a single claim.

Scope required: warranty.read

Terminal window
curl "https://app.benchkey.com/api/v1/warranty_claims/27" \
-H "Authorization: Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa"

Returns the warranty claim object. Returns 404 if no claim with that ID exists.


GET /api/v1/warranty_claims/active

Returns the active warranty coverages for exactly one of: a ticket (ticket_id), a customer email (customer), or a customer phone (phone — the same lookup the in-app intake banner uses). Coverage is derived from the shop’s warranty window and each ticket’s latest paid invoice; expired or never-covered tickets yield an empty list.

Customer and phone lookups return at most 5 coverages.

Scope required: warranty.read

Supply exactly one:

ParameterTypeDescription
ticket_idstringLook up one ticket’s coverage
customerstringLook up by customer email
phonestringLook up by customer phone
Terminal window
curl "https://app.benchkey.com/api/v1/warranty_claims/active?customer=jane.smith@example.com" \
-H "Authorization: Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa"
{
"object": "list",
"data": [
{
"object": "warranty_coverage",
"ticket_id": "TK-10042",
"customer_name": "Jane Smith",
"active": true,
"expires_at": "2026-08-30T00:00:00.000Z",
"terms_summary": "90-day limited warranty"
}
],
"has_more": false,
"next_cursor": null
}
FieldTypeDescription
ticket_idstringThe covered ticket
customer_namestring|nullThe ticket’s customer
activebooleanAlways true in this list — expired coverage is omitted
expires_atstringISO-8601 coverage expiry
terms_summarystringHuman summary of the shop’s warranty terms (e.g. "90-day limited warranty")

POST /api/v1/warranty_claims

Opens a claim against a ticket whose derived warranty is active (the shop’s warranty window counted from the ticket’s latest paid invoice). Fails with 409 when the ticket has no warranty, the warranty has expired, or the ticket already has an open/approved claim.

Scope required: warranty.write

Send an Idempotency-Key header to make retries safe. See Idempotency.

FieldRequiredTypeDescription
ticket_idyesstringThe covered ticket’s ID
reasonnostring|nullWhy the claim is being opened (max 1000 characters)
Terminal window
curl -X POST https://app.benchkey.com/api/v1/warranty_claims \
-H "Authorization: Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: claim-TK-10042-$(uuidgen)" \
-d '{
"ticket_id": "TK-10042",
"reason": "Screen developed dead pixels two weeks after replacement."
}'
const res = await fetch("https://app.benchkey.com/api/v1/warranty_claims", {
method: "POST",
headers: {
Authorization: "Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa",
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
ticket_id: "TK-10042",
reason: "Screen developed dead pixels two weeks after replacement.",
}),
});
const claim = await res.json(); // HTTP 201, status: "open"

Returns the opened warranty claim object with HTTP 201 and status: "open".


PATCH /api/v1/warranty_claims/:id

Transition the claim’s status, set resolution notes, or link/clear the no-charge rework ticket. Legal status moves: open → approved | rejected, approved → resolved | rejected — an illegal move returns 409. Setting rework_ticket_id to null clears the link; a ticket already linked to another claim returns 409.

Scope required: warranty.write

At least one of:

FieldTypeDescription
statusstringopen, approved, rejected, or resolved (subject to the legal transitions above)
resolution_notesstring|nullNotes recorded on the claim (max 1000 characters)
rework_ticket_idstring|nullThe no-charge rework ticket to link; null clears the link
Terminal window
curl -X PATCH "https://app.benchkey.com/api/v1/warranty_claims/27" \
-H "Authorization: Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa" \
-H "Content-Type: application/json" \
-d '{ "status": "approved", "rework_ticket_id": "TK-10113" }'
const res = await fetch(
"https://app.benchkey.com/api/v1/warranty_claims/27",
{
method: "PATCH",
headers: {
Authorization: "Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa",
"Content-Type": "application/json",
},
body: JSON.stringify({ status: "approved", rework_ticket_id: "TK-10113" }),
}
);
const claim = await res.json();

Returns the updated warranty claim object.


HTTP statusCodeMeaning
400invalid_queryA list filter parameter was supplied as an array or object instead of a single scalar value, an unrecognized status filter, or /active was called with zero or multiple lookup parameters (“Provide exactly one of: ticket_id, customer, phone”)
400invalid_cursorThe pagination cursor is malformed
400invalid_bodyRequest body is not a JSON object
400unknown_fieldBody contains a field this endpoint doesn’t accept
400missing_fieldticket_id is absent on create
400invalid_fieldA field value is invalid — e.g. a non-string reason, reason/resolution_notes over 1000 characters, or an unrecognized status value
404not_foundNo claim with that ID, or the referenced ticket does not exist for this tenant
409conflictThe ticket has no active warranty, already has an open/approved claim, the status transition is illegal, or the rework ticket is already linked to another claim
422create_failedThe claim could not be created
403insufficient_scopeAPI key lacks warranty.read or warranty.write

See Errors for the full error envelope format.