Skip to content
TruTecDevelopers
Get an API key

Subcontract agreements

Send subcontractors an agreement to e-sign, text them the link, track who has signed, sign for your company, and delete unsigned ones.

View as Markdown

An agreement is one of your templates (a subcontract, master service agreement or rate sheet PDF, with the places to sign marked) sent to one subcontractor for electronic signature. They open a private link (no account), fill in their company details, sign, and upload an insurance certificate when the template asks for one. Your company signs too, before or after them. Once both have signed, TruTec assembles the executed copy (the PDF plus a signature and audit page), files it and emails it to the subcontractor.

Templates are set up in TruTec (Agreements): uploading the PDF and placing the signature marks needs the editor. The API sends, tracks and signs.

Writes act as the user who created the API key, with that user's estimating role (owner, admin or estimator). A member's key never acts as anyone else: the signing request comes from that user's connected mailbox, and that user is the one who signs for the company.

Warning

POST /v1/agreement-templates/{id}/send emails the subcontractor and POST /v1/agreements/{id}/text-link texts them. POST /v1/agreements/{id}/countersign is a legal signature in the key creator's name and, when the subcontractor has already signed, emails them the executed copy. Confirm with the person before calling any of them, especially from an AI assistant.

Note

Partner keys that act on behalf of several workspaces must also pass firm_id (query string, or JSON body on writes).

The agreement object#

Field Type Description
id integer
name string The template's name when sent.
template_id integer
job_id integer or null
vendor object id, name, email, phone.
status string sent, signed (the subcontractor signed) or void.
waiting_on string or null recipient (the subcontractor), company (you), or null when both signed.
fully_executed boolean Both signed.
sent_at, viewed_at, signed_at string or null
signer object or null Who signed for the subcontractor: name, title, company, email, phone.
countersigned_at, countersigner_name, countersigner_title Your company's signature.
insurance_required, insurance_received boolean Certificate of insurance.
executed_copy_available boolean The executed PDF exists (download it in TruTec).
company_fields array Single agreement only: your company's marks (index, kind, label, page). Text ones are filled when countersigning.
created_at, updated_at string

Read#

GET /v1/agreement-templates lists templates: id, name, pages, ready_to_send (it has a place for the recipient to sign), company_signs, insurance_required. Permission: Read jobs.

GET /v1/agreements lists agreements, newest first. Filters: vendor_id, template_id, status, updated_after (then oldest change first), limit, offset.

GET /v1/agreements/{id} returns one.

Send for signature#

POST /v1/agreement-templates/{template_id}/send

Permission: Write jobs (role: owner, admin or estimator)

Emails the subcontractor a "Review and sign" link from the key user's connected mailbox (the system sender otherwise), using the template's cover email. The key user is emailed their own link to sign for the company.

Name Type Description
vendor_id integer A subcontractor in your vendor book.
vendor_name, vendor_email string Instead of vendor_id: adds a new subcontractor and sends to them. With vendor_id, vendor_email also updates their email.
curl -X POST "https://trutec.ai/api/v1/agreement-templates/18/send" \
  -H "X-API-Key: sk_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"vendor_id": 55}'
{
  "data": {
    "id": 940, "name": "Master subcontract agreement", "template_id": 18, "job_id": null,
    "vendor": {"id": 55, "name": "Ridge Striping LLC", "email": "[email protected]", "phone": null},
    "status": "sent", "waiting_on": "recipient", "fully_executed": false,
    "sent_at": "2026-10-13T17:40:02Z", "viewed_at": null, "signed_at": null, "signer": null,
    "countersigned_at": null, "countersigner_name": null, "countersigner_title": null,
    "insurance_required": true, "insurance_received": false, "executed_copy_available": false,
    "company_fields": [{"index": 3, "kind": "signature", "label": null, "page": 4}],
    "created_at": "2026-10-13T17:40:02Z", "updated_at": "2026-10-13T17:40:02Z"
  },
  "delivered": true,
  "sent_from": "[email protected]"
}

Errors: 400 Place at least one Recipient signature field before sending. (finish the template in TruTec), vendor_email is required for a new subcontractor, Add an email for this vendor first. 404 Agreement template not found, Vendor not found.

POST /v1/agreements/{id}/text-link with optional phone (saved on the vendor first). Texts the subcontractor the link from your workspace's texting number. 409 for a withdrawn agreement; 400 when there's no usable cell number or texting isn't set up; 502 when the text could not be sent.

Sign for your company#

POST /v1/agreements/{id}/countersign

Permission: Write jobs (role: owner, admin or estimator)

Signs as the API key's creator with a typed signature, recorded with the time and the caller's IP address, the same as signing on the page. When the subcontractor has already signed, the executed copy is assembled, filed and emailed to the subcontractor. Signing an agreement that is already countersigned changes nothing.

Name Type Required Description
name string Yes The signer's name.
signature_typed string Yes The signature, typed.
title string No
initials_typed string When the company has initials marks
field_values object When the company has text marks Text by company_fields index, e.g. {"5": "10/13/2026"}.

Returns the agreement. Errors: 400 Add your name., Fill in: …, This agreement was withdrawn.

Delete an unsigned agreement#

DELETE /v1/agreements/{id}

Permission: Write jobs and Delete records (role: owner, admin or estimator)

For a test send, the wrong vendor or a duplicate. Its signing link stops working. An agreement with any signature on it is a legal record and can't be deleted (409). Returns 204.