Settings
Read and change the workspace's settings — company profile, branding, units, estimating defaults, sales tax, proposal terms, job numbering and intake, takeoff, photo, scheduling and notification preferences — and its pipeline stages, job types and pick lists.
View as MarkdownThe settings API is one surface over TruTec's owner Settings pages. Each section is one card in Settings. Reading returns every section with its current values; changing a section runs that card's own save, so TruTec's checks, cleanup and side effects apply exactly as when an owner clicks Save.
Only the fields you send change. Some Settings cards save all of their fields at once; the API fills in the current value of every field you didn't send, so a change never resets anything else.
Who can change settings. Reads need Read jobs. Changes need Write jobs and a key created by a workspace owner who still owns the workspace (settings are owner-only in TruTec). Any other key gets 403 Owner key required. Partner keys act as the linked workspace's owner.
Not in the API. Billing and the plan, payment connections, API keys, members, roles and permissions, teams, sign-in and security, integration connections (QuickBooks, HubSpot, Jobber, email, cloud storage) and deleting the workspace are changed only in TruTec. Reading or changing those section names returns 403 Not available through the API with where to go. Invite members with POST /v1/users/invite.
Rates are fractions: 0.075 means 7.5%. Money is in dollars.
Note
Partner keys that act on behalf of several workspaces must also pass firm_id (query string, or JSON body on writes).
Sections#
| Section | Fields | Where in TruTec |
|---|---|---|
company |
name (2–200 characters), website, address (the office or yard address trucks leave from), timezone (an IANA name such as America/Chicago; set from the crew schedule, so only workspaces with crew scheduling can change it here) |
Settings › Workspace |
branding |
logo_from_url (write only: a public link to a PNG, JPG, WebP or GIF; TruTec copies it into the logo library and makes it the active logo), brand_color (customer portal color), drawing_accent_color (construction drawing exports), share_subdomain. Reading also returns logo_url, a temporary link to the active logo |
Settings › Workspace, Settings › Exports & portal |
units |
default_area_unit: sf or sy, the area unit new services start with |
Estimating › Defaults |
estimating |
default_markup_method (markup or margin), default_markup_rate, default_tax_rate, taxable_categories (any of material, crew, equipment, trucking, sub, misc, overhead, unit_costed), default_contingency_rate, minimum_job_charge, approval_margin_floor, default_burden_rate, overtime_burden_rate, overtime_after_hours, double_time_after_hours, double_time_multiplier, workday_hours, production_rate_basis (hour or day), estimate_number_start, proposal_quantity_rounding ({step, mode}), rounding ({labor_time_step_days, material_whole_units, proposal_increment, proposal_allocation}; keys you leave out keep their values), difficulty_multipliers ({easy, standard, hard}), auto_carry_takeoff_services, one_minimum_per_service, show_empty_cost_categories, labor_sets_enabled |
Catalog › Settings |
sales_tax |
areas ([{id, name, rate, match, state, place}]; match is state, county or city; the most specific match for a job's address wins), exempt_question and reason_question (requirements question ids) |
Settings › Workspace › Sales tax areas |
proposal_terms |
The company default terms on new proposals: title, body_html, items ([{text, title, bold, on}]), footer, footer_hidden |
Catalog › Proposal content |
proposal_clauses |
clauses: the reusable clause library, [{id, title, text, bold, is_default}]. Default clauses are added to every new proposal |
Catalog › Proposal content |
job_numbering |
prefix (up to 12 characters), start. Existing job numbers don't change |
Settings › Workspace › Job numbering |
job_creation |
required_fields (any of address, company, job_type, source, contact_email), require_assignment, disable_quick_create, warn_duplicate_addresses, assign_to_creator |
Settings › Workspace |
job_requirements |
questions: the requirements questions asked on every job |
Settings › Workspace › Requirements |
jobs_board |
remember_filters, lock_column_headers, show_prevailing_wage_fields, show_customer_review |
Settings › Workspace |
takeoffs |
show_address_pin_on_load, include_adjacent_crosshatch_with_ada, require_scale_verification (plan sheets lock until someone confirms the scale), show_legacy_takeoff_tools |
Settings › Workspace › Measurement preferences |
photos |
default_visibility (external = customer can see new photos, internal = team only), default_include_in_report |
Settings › Workspace › Measurement preferences |
scheduling |
working_hours_per_day, chip_text (auto, dark or light), chip_strength (soft, medium or bold), group_by (service_group, service, job, job_number, crew or null; needs crew scheduling) |
Settings › Workspace › Crew schedule |
notifications |
Emails to the team when a customer acts on a proposal: proposal_viewed, proposal_signed, proposal_accepted, proposal_declined, proposal_paid |
Settings › Notifications |
lists |
Read only: job_stages, job_types and pick_lists (lead_sources, customer_types, property_types, contact_types). Change them with the endpoints under Lists |
Jobs board, Settings |
Lists inside a section (sales_tax.areas, proposal_clauses.clauses, proposal_terms.items, job_requirements.questions) are replaced whole: read the section, change the list and send all of it back. Keep each entry's id to keep it.
estimating, proposal_terms and proposal_clauses need Estimating Pro; on other workspaces they're listed as unavailable and changes return 409.
Read settings#
Get every section#
GET /v1/settings
Permission: Read jobs
curl "https://trutec.ai/api/v1/settings" \
-H "X-API-Key: sk_your_api_key_here"
{
"data": {
"company": { "name": "Northgate Paving", "timezone": "America/Chicago", "address": "2200 Yard Rd, Austin, TX", "website": "northgatepaving.example" },
"job_numbering": { "prefix": "J", "start": 1000 },
"notifications": { "proposal_viewed": true, "proposal_signed": true, "proposal_accepted": true, "proposal_declined": true, "proposal_paid": true }
},
"sections": [
{ "key": "company", "title": "Company profile", "settings_page": "Settings › Workspace", "fields": ["name", "website", "address", "timezone"], "available": true, "unavailable_reason": null, "note": null }
],
"not_in_api": ["api_keys", "billing", "delete_workspace", "members", "roles", "security"]
}
(Response trimmed.) sections lists each section's fields and whether this workspace has it.
Get one section#
GET /v1/settings/{section}
Permission: Read jobs
Returns {"data": {...}} for that section. Errors: 404 for an unknown section, 403 for a section that isn't in the API, 409 for a section this workspace doesn't have.
Change settings#
Change a section#
PATCH /v1/settings/{section}
Permission: Write jobs, and a key created by a workspace owner
Send the fields to change. Returns the section after the save, and changed: each field you sent that changed, with before and after.
curl -X PATCH "https://trutec.ai/api/v1/settings/estimating" \
-H "X-API-Key: sk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"default_markup_method": "markup", "default_markup_rate": 0.3, "default_tax_rate": 0.075}'
{
"data": { "default_markup_method": "markup", "default_markup_rate": 0.3, "default_tax_rate": 0.075, "minimum_job_charge": 0.0 },
"changed": {
"default_markup_method": { "before": "margin", "after": "markup" },
"default_markup_rate": { "before": 0.0, "after": 0.3 },
"default_tax_rate": { "before": 0.0, "after": 0.075 }
}
}
(Response trimmed.)
curl -X PATCH "https://trutec.ai/api/v1/settings/sales_tax" \
-H "X-API-Key: sk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"areas": [{"name": "Travis County", "rate": 0.0825, "match": "county", "state": "TX", "place": "Travis"}]}'
Errors: 400 Unknown fields: … (with allowed_fields), <field> must be …, or TruTec's own reason (for example "That company name is already taken."). 403 API key lacks job write permission, Owner key required, Not available through the API. 404 unknown section. 409 a section this workspace doesn't have.
Lists#
Pipeline stages, job types and pick lists are edited one entry at a time, the way the jobs board and Settings edit them. These also need Write jobs and an owner's key; removing a stage or job type also needs Delete records. Read them with GET /v1/job-stages, GET /v1/job-types and the lists section.
Add a job stage#
POST /v1/job-stages
| Name | Type | Required | Description |
|---|---|---|---|
label |
string | Yes | Up to 80 characters. |
stage_type |
string | No | What it counts as in reports: open (default), won, lost, excluded or warranty. |
color |
string | No | Like #2563eb. |
default_probability |
integer | No | Win chance in percent, 0–100. |
Adds the stage at the end of the board. Returns 201 with the stage (the GET /v1/job-stages shape).
Change a job stage#
PATCH /v1/job-stages/{key}
Same fields; only what you send changes. Returns the stage and changed. Changing a won stage's type is refused while won jobs are locked and sit in it.
Remove a job stage#
DELETE /v1/job-stages/{key}
Permission: Write jobs and Delete records, owner key
Its jobs move to the stage before it (the next one when it's the first). The last stage can't be removed. Returns 204.
Reorder job stages#
POST /v1/job-stages/reorder
Body: {"keys": [...]} with every stage key once, in the new order. Returns the stages.
Job types#
| Endpoint | What it does |
|---|---|
POST /v1/job-types |
Add one: {label, category}. Returns 201 with {value, label, category}. |
PATCH /v1/job-types/{value} |
Rename or recategorize. Returns it and changed. |
DELETE /v1/job-types/{value} |
Remove it from the list (Delete records). Jobs that already have it keep it. 204. |
POST /v1/job-types/reorder |
{"values": [...]} in the new order; any left out follow. |
Pick lists#
GET /v1/pick-lists/{kind} and PATCH /v1/pick-lists/{kind}, where kind is lead_sources, customer_types, property_types or contact_types.
The PATCH body is {"add": [...], "remove": [...]} (option names, matched without regard to case; adding one that's there already does nothing). Returns the list after and changed (before, after). Removing an option that isn't in the list is a 404.
curl -X PATCH "https://trutec.ai/api/v1/pick-lists/lead_sources" \
-H "X-API-Key: sk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"add": ["Yard sign"], "remove": ["Newspaper"]}'