Job details, tags & share links
The job page's detail fields, job number, tags, site, division and operations assignee; the customer portal conversation; and the links you hand out (review requests, photo reports, chosen photos, assessment reports, capital plans).
View as MarkdownEverything here runs the job page's own actions as the person who created the API key, so the same rules apply: a member who only sees their own jobs can only change those, owners and schedulers set divisions, and every change lands in the job's activity log under that person.
Share and review links are never sent by TruTec through these endpoints: each call returns a link for you to send. The one endpoint here that reaches a customer directly is the portal reply: the customer sees it in their portal.
Note
Partner keys that act for several workspaces must also send firm_id (query string, or JSON body on writes).
Job details#
PATCH /v1/jobs/{job_id} covers the sales fields (name, contact, address, value, dates, stage...). These cover the rest of the job page.
Get job details#
GET /v1/jobs/{job_id}/details
Permission: Read jobs
{
"data": {
"job_id": 70412,
"job_number": 1034,
"display_job_number": "J-1034",
"accounting_job_number": "26-118",
"property_reference": "PR-4471",
"own_property_reference": null,
"external_work_order_number": "WO-88120",
"description_customer_visible": false,
"bid_due_date": "2026-10-30",
"customer_type": "Property management",
"property_type": "Retail",
"bond_required": false,
"liquidated_damages": true,
"liquidated_damages_per_day": 500.0,
"davis_bacon": null,
"linked_contact_id": 5512,
"location_id": 812,
"location": {"id": 812, "name": "Oak Hills Plaza", "address": "1200 Commerce Dr, Austin, TX"},
"tags": [{"id": 14, "name": "HOA", "color": "#2563eb"}],
"operations": {
"division": "seal", "division_name": "Sealcoating",
"division_options": [{"key": "seal", "name": "Sealcoating"}, {"key": "paving", "name": "Paving"}],
"assignee_user_id": 118, "assignee": {"id": 118, "name": "Pat Rivera"}
}
}
}
property_reference is the job's own Property ID, else its site's (own_property_reference is only what was typed on the job). bond_required, liquidated_damages and davis_bacon are null until someone answers. operations is null when crew scheduling is off.
Update job details#
PATCH /v1/jobs/{job_id}/details
Permission: Write jobs
Only the fields sent change.
| Name | Type | Description |
|---|---|---|
job_number |
integer | Renumber this one job. Must be unused in the workspace (400 names the job that has it). New jobs keep counting up from the highest number. |
accounting_job_number |
string or null | Up to 80 characters. |
property_reference |
string or null | The customer's Property ID for this job. Blank or null goes back to the site's. |
external_work_order_number |
string or null | The customer's work order number. |
description_customer_visible |
boolean | Show the job description to the customer. |
bid_due_date |
string or null | YYYY-MM-DD. |
customer_type, property_type |
string or null | |
bond_required, liquidated_damages, davis_bacon |
boolean or null | |
liquidated_damages_per_day |
number or null | Dollars. |
linked_contact_id |
integer | Makes this saved contact the job's main contact (fills the job's contact fields). To take someone off the job use DELETE /v1/jobs/{job_id}/contacts/{contact_id}. |
Returns the details. Errors: 400 with the app's reason (for example a job number already used, or a contact from another customer); 404 for a job or contact outside the workspace.
Division and operations assignee#
PATCH /v1/jobs/{job_id}/operations-assignment
Permission: Write jobs. The key's user must be an owner or able to edit the schedule.
For workspaces with crew scheduling (403 otherwise).
| Name | Type | Description |
|---|---|---|
division |
string or null | A key from division_options; null = follows the service. |
operations_assignee_user_id |
integer or null | Who runs the job on the operations side; null clears. |
Set the job's site#
PUT /v1/jobs/{job_id}/location
Permission: Write jobs
| Body | What it does |
|---|---|
{"location_id": 812} |
Link the job to that site. A job with no address takes the site's; a job with no company is filed under the site's company. |
{"create_from_address": true} |
Save the job's address as a site (or link the site that already has it). The job needs an address. |
{"location_id": null} |
Take the job off its site. |
Returns {"data": {"job_id", "location_id", "location", "client_account_id"}}.
Tags#
| Endpoint | Permission | What it does |
|---|---|---|
GET /v1/job-tags |
Read jobs | The workspace's tags (q searches names). |
POST /v1/job-tags |
Write jobs | Add a tag: name (up to 50 characters), color (#rrggbb). 409 with the existing tag when the name is taken. |
POST /v1/jobs/{job_id}/tags |
Write jobs | Tag a job: {"tag_ids": [14, 22]}. Returns the job's tags. |
DELETE /v1/jobs/{job_id}/tags/{tag_id} |
Write jobs | Take a tag off the job (the tag stays). 204. |
Customer portal conversation#
The conversation on a job in the customer's portal: their questions and the project team's replies, including comments the customer pinned on the map.
List portal messages#
GET /v1/jobs/{job_id}/portal-messages
Permission: Read jobs
Oldest first; limit keeps the most recent N (default 100, max 200). Each message has id, body, author_type (customer or staff), author_name, created_at, and for map comments map_comment, latitude, longitude, location_id, location_name.
Reply in the customer portal#
POST /v1/jobs/{job_id}/portal-messages
Permission: Write jobs
Warning
The customer sees this reply in their portal, signed by the key's user. TruTec doesn't email or text it, but treat it as a message to the customer.
{"body": "We're on site Thursday at 7 AM."} (up to 2,000 characters). Returns 201 with the message.
Review links#
| Endpoint | Permission | What it does |
|---|---|---|
POST /v1/jobs/{job_id}/review-request |
Write jobs | Make a review link for the job's customer (client_name and client_email default from the job). 201 with review_url. Nothing is sent. |
GET /v1/reviews |
Read jobs | Review links and written reviews, newest first. Filter job_id, submitted (true = written, false = still waiting). |
A review has id, job_id, client_name, client_email, submitted, rating (1-5), content, is_public, review_url, submitted_at, created_at.
Photo links#
The job's photo report link#
One public link per job showing its customer-visible photos marked for the report.
| Endpoint | Permission | What it does |
|---|---|---|
GET /v1/jobs/{job_id}/photo-share-link |
Read jobs | The link and its settings (enabled: false until one is made). |
POST /v1/jobs/{job_id}/photo-share-link |
Write jobs | Make it (201) or return the existing one (200). Optional access_code, expires_in_days. |
PATCH /v1/jobs/{job_id}/photo-share-link |
Write jobs | access_code (4-64 characters) protects it, public: true removes the code, expires_in_days (1-365, or null for never). |
{"data": {"job_id": 70412, "enabled": true, "share_url": "https://trutec.ai/photos/share/3f9a1c22b0de",
"access_mode": "code", "has_access_code": true, "expires_at": "2026-11-12T15:02:10Z", "is_expired": false}}
Links to chosen photos#
A link to exactly the photos you pick (customer-visible photos on the job), for 7, 30 or 90 days. Photos added to the job later never appear in it.
| Endpoint | Permission | What it does |
|---|---|---|
GET /v1/jobs/{job_id}/photo-selection-shares |
Read jobs | The job's chosen-photo links, newest first. |
POST /v1/jobs/{job_id}/photo-selection-shares |
Write jobs | photo_ids (required), title, expires_in_days (7, 30 or 90; default 30). 201. A photo that is internal or on another job is a 400. |
POST /v1/jobs/{job_id}/photo-selection-shares/{share_id}/revoke |
Write jobs | Turn it off for good. |
Assessment report links#
POST /v1/site-assessments/{assessment_id}/share-link
Permission: Write jobs
The site assessment report's public link. Send service_type_ids (services that have pins in the assessment) to make a separate link showing only those services' pins, for a sub bidding part of the work; each such call makes a new link, optionally named with label. Returns {"data": {"assessment_id", "share_url", "scoped", "service_type_ids", "label"}}.
Capital plan links#
A read-only page of a site's multi-year capital plan to send the property manager. For workspaces with capital planning (403 otherwise).
| Endpoint | What it does |
|---|---|
POST /v1/locations/{location_id}/plan-share-link |
Turn the link on (or return it). |
POST /v1/locations/{location_id}/plan-share-link/disable |
Turn it off; the old link stops working. |
POST /v1/locations/{location_id}/plan-share-link/rotate |
A new link; the old one stops working. |
Permission: Write jobs. Each returns {"data": {"location_id", "enabled", "share_url"}}.