Warranty
Send customers their warranty packet when a job is done, send warranty work notices, and track every coverage item and when it ends.
View as MarkdownTruTec's warranty program has three parts:
- A warranty packet is the customer's warranty document for one job: a certificate listing each covered item (for example Sealcoating, 6,300 SY, 12 months) and when its coverage ends. When a job reaches a completed stage, TruTec makes a draft packet and reminds the office to send it. Sending emails the customer a link to their certificate.
- A work notice tells the customer that a repair is being done under their warranty. TruTec decides the wording from the coverage: if the item has expired, or the job has no live coverage, the notice says the work is done at no charge instead (
kindgoodwill). - The tracker lists every item on a sent packet, soonest to end first, as
active,expiring(ends within 90 days) orexpired.
Packets are built from a warranty template: the document text with merge fields, standard coverage items, and rules that set each sold service's term (for example any service with "Crack" in its name gets 6 months). Rows come from the job's sold estimate when it has one, otherwise from the template's standard items. Templates are edited in TruTec (Warranty > Templates).
These endpoints can email your customer.
POST /v1/jobs/{job_id}/warranty/send,POST /v1/warranty-packets/{packet_id}/sendandPOST /v1/jobs/{job_id}/warranty/send-noticeemail the customer from the sending person's connected mailbox, exactly like Send in TruTec. Preview first withPOST /v1/jobs/{job_id}/warranty/preview. Nothing else here emails anyone.
Sends and voids act as the person who created the API key (a partner key acts as the workspace owner). Crew logins can't send or void warranty documents.
The packet object#
| Field | Type | Description |
|---|---|---|
id, job_id, template_id |
integer | |
status |
string | draft (made when the job was completed, waiting to be sent), sent or void. |
name, customer_name |
string | |
effective_date |
string | When coverage starts (YYYY-MM-DD). |
sent_at, sent_to_email |
Last send. sent_to_email is null when it was shared as a link only. |
|
public_url |
string or null | The customer's certificate link while the packet is sent. Share it yourself when no email went out. |
first_viewed_at, last_viewed_at, view_count |
When the customer opened it. | |
items |
array | Coverage items (below). |
created_by, created_at |
The coverage item object#
| Field | Type | Description |
|---|---|---|
id, job_id, packet_id |
integer | |
label, quantity |
string | What is covered and how much was sold, e.g. Sealcoating, 6,300 SY. |
term_months |
integer | |
starts_on, ends_on |
string | Dates. |
status |
string | active, expiring (ends within 90 days) or expired. |
days_left |
integer | Negative once expired. |
notes |
string or null |
The work notice object#
| Field | Type | Description |
|---|---|---|
id, job_id |
integer | |
status |
string | sent or void. |
kind |
string | warranty, or goodwill for work done at no charge outside live coverage. |
title, scheduled_for |
What is being done and when. | |
coverage_item_id, coverage_item, packet_id |
The coverage item it falls under, if any. | |
sent_at, sent_to_email, public_url, first_viewed_at, last_viewed_at, view_count |
As on packets. |
A job's warranty#
Get a job's warranty#
GET /v1/jobs/{job_id}/warranty
Permission: Read jobs
Everything the job's Warranty page shows: packets (newest first), notices, coverage (items on sent packets), the workspace's templates, and suggested_packet: what a send would hold right now (template, recipient, customer name, subject and rows, with from_estimate_id when the rows come from the sold estimate).
| Name | Type | Required | Description |
|---|---|---|---|
template_id |
integer | No | Suggest the packet from this template instead of the default. |
effective_date |
string | No | Coverage start for the suggestion. Default today. |
curl "https://trutec.ai/api/v1/jobs/70412/warranty" \
-H "X-API-Key: sk_your_api_key_here"
Preview a document#
POST /v1/jobs/{job_id}/warranty/preview
Permission: Read jobs
Returns the packet (kind packet, the default) or work notice (kind notice) as HTML with merge fields filled in. Takes the same fields as the send endpoints below. Nothing is saved or sent.
Send the job's warranty packet#
POST /v1/jobs/{job_id}/warranty/send
Permission: Write jobs. Emails the customer.
Fills in the job's draft packet (or starts one), freezes the document, adds each row to the tracker, marks it sent and emails the customer a link to their certificate. Every field is optional; the defaults are what suggested_packet shows.
| Field | Type | Description |
|---|---|---|
template_id |
integer | Default: the workspace default template. |
effective_date |
string | Coverage start. Default today. |
to_email |
string or null | Left out: the job's contact email. null or "": nobody is emailed; the packet is sent as a link (public_url). |
customer_name |
string | Default: the job's company or contact. |
rows |
array | {label, quantity, term_months, notes} per covered item (up to 100). term_months defaults to the template's term for that service. |
cover_subject, cover_body |
string | The email's subject and message. Default: the template's. |
body_html |
string | The warranty document (simple HTML with merge fields such as {{customer_name}}). Default: the template's. |
curl -X POST "https://trutec.ai/api/v1/jobs/70412/warranty/send" \
-H "X-API-Key: sk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"to_email": "[email protected]", "effective_date": "2026-10-13"}'
{
"data": {
"id": 3310,
"job_id": 70412,
"status": "sent",
"name": "Standard paving warranty — Northgate Plaza reseal",
"template_id": 41,
"customer_name": "Northgate Properties",
"effective_date": "2026-10-13",
"sent_at": "2026-10-13T16:02:11Z",
"sent_to_email": "[email protected]",
"public_url": "https://trutec.ai/warranty/certificate/Qm9n...",
"view_count": 0,
"items": [
{ "id": 9120, "label": "Sealcoating", "quantity": "6,300 SY", "term_months": 12,
"starts_on": "2026-10-13", "ends_on": "2027-10-13", "status": "active", "days_left": 365 }
]
},
"emailed": true
}
If the email can't be delivered the packet is still sent: the response has emailed: false and email_error, and you can share public_url yourself.
Send a work notice#
POST /v1/jobs/{job_id}/warranty/send-notice
Permission: Write jobs. Emails the customer. Returns 201.
| Field | Type | Description |
|---|---|---|
title |
string | Required. What's being done, e.g. Crack repair at the entrance. |
coverage_item_id |
integer | One of this job's coverage items (from coverage). |
scheduled_for |
string | When the work is planned. |
to_email, customer_name |
As for packets. | |
body_html |
string | Default: the standard warranty wording, or the no-charge wording when coverage has run out. |
Packets, notices and the tracker#
List warranty packets#
GET /v1/warranty-packets
Permission: Read jobs
Newest first. Filter by job_id and status (draft lists packets waiting to be sent). limit (default 50, maximum 200) and offset.
Get a warranty packet#
GET /v1/warranty-packets/{packet_id}
Permission: Read jobs
Send a packet again#
POST /v1/warranty-packets/{packet_id}/send
Permission: Write jobs. Emails the customer.
Sends a draft for the first time, or a sent packet again, with any changes. Same fields as sending from the job; the defaults are the packet's own recipient, customer name, template and coverage start. Its coverage items are rebuilt from the rows. A void packet can't be sent (409).
Void a packet#
POST /v1/warranty-packets/{packet_id}/void
Permission: Write jobs
The customer's link stops working and the packet's items leave the tracker. A void packet can't be sent again; send a new one from the job.
List work notices#
GET /v1/warranty-notices
Permission: Read jobs
Newest first. Filter by job_id, status (sent, void) and kind (warranty, goodwill).
Void a work notice#
POST /v1/warranty-notices/{notice_id}/void
Permission: Write jobs
List coverage (the tracker)#
GET /v1/warranty-items
Permission: Read jobs
Every item on a sent packet, soonest to end first, each with the work notices sent under it. counts totals active, expiring and expired across the workspace (or the job).
| Name | Type | Required | Description |
|---|---|---|---|
status |
string | No | active, expiring or expired. |
job_id |
integer | No | |
limit, offset |
integer | No | Default 50, maximum 200. |
List warranty templates#
GET /v1/warranty-templates
Permission: Read jobs
Active templates, default first, with standard_items and coverage_rules ({keyword, term_months}: the first keyword found in a sold service's name sets its term).
Errors: 400 bad dates, rows or fields; 403 missing permission, or the key's creator is a crew login or no longer in the workspace; 404 a job, packet, notice, template or coverage item that isn't in this workspace; 409 sending a void packet.