Tradesmen Technologies Tradesmen Technologies

API reference Integration API

Integration API

Tradesmen Tech exposes a small public API so other services can create clients and jobs in your company. It is what the Tradesmen Tech Zapier integration uses, and any service that can send an HTTP request can call it directly.

Need more than clients and jobs? The full Tradesmen Tech API reference documents every endpoint the app itself uses, authenticated with your regular login.

Base URL

https://api.tradesmentechnologies.com/prod

All requests use HTTPS. Request and response bodies are JSON. Date-times are ISO 8601 strings; UTC (Z) is recommended.

Authentication

The API is authenticated with a webhook code: a 32-character key that identifies your company and travels in the URL path. There are no login tokens, headers, or OAuth flows.

To create one, open the Tradesmen Tech app and go to Menu → Zapier and Webhooks Integration, tap +, give the source a name (for example "Zapier" or "Website form"), and copy the code shown under the new entry. Each code can be deleted at any time, which immediately stops anything using it, and each code can independently allow or block job creation.

Treat a webhook code like a password. Anyone who has it can create clients and jobs in your company.

Using Zapier

The Tradesmen Tech app on Zapier wraps this API so you never write JSON. In Zapier, add an action step, search for Tradesmen Tech, and choose Create Client or Create Job. When Zapier asks you to connect an account, paste a webhook code. Every field in both actions is optional and maps one-to-one onto the fields documented below.

Verify a webhook code

GET /webhooks/incoming/{code}

Confirms a code is valid and returns the settings an integration needs to label a connection. Never returns the code or any secret. Zapier calls this when you connect an account.

Response 200 OK

{
  "companyName": "Acme Plumbing",
  "source": "Zapier",
  "allowJobCreation": true,
  "notifyCompanyOnNewCustomer": false
}

403 for an unknown code.

Create a client and, optionally, a job

POST /webhooks/incoming/{code}

Creates a client in your company. Include a job object to also create a job for that client. Every field is optional: an empty body {} creates a blank client, and "job": {} creates a job with default values.

Duplicate prevention

If a client with the same email already exists in your company, that client is reused instead of creating a duplicate. When no email is sent but a phoneNumber is, the same check runs on the normalized phone number. When neither is sent, a new client is always created.

An optional idempotencyKey makes retries safe: when the matched client carries the same key, the request returns the existing client and creates nothing.

Example request

POST /prod/webhooks/incoming/ABCDEFghijklmnopQRSTUVwxyz012345
Content-Type: application/json

{
  "firstName": "Jane",
  "lastName": "Smith",
  "email": "jane@example.com",
  "phoneNumber": "5125551234",
  "address": {
    "streetAddress": "123 Main St",
    "city": "Austin",
    "state": "TX",
    "zipCode": "78701"
  },
  "source": "Website form",
  "idempotencyKey": "form-submission-9f1c",
  "job": {
    "jobType": "PLUMBING",
    "status": "NEW",
    "description": "Leaking kitchen faucet",
    "startDateTime": "2026-10-01T15:00:00Z",
    "endDateTime": "2026-10-01T16:00:00Z",
    "address": {
      "streetAddress": "123 Main St",
      "city": "Austin",
      "state": "TX",
      "zipCode": "78701"
    }
  }
}

Responses

201 Created when a new client was created; 200 OK when an existing client was reused. jobId and displayId (the job number shown in the app) are present only when a job object was sent.

{
  "message": "Customer created successfully",
  "customerId": "6f1c2b1e-3d2a-4c8e-9a7b-0e5d4c3b2a10",
  "customerIsNew": true,
  "jobId": "0a9b8c7d-6e5f-4a3b-2c1d-0e9f8a7b6c5d",
  "displayId": 42
}

An idempotent replay answers 200 OK with "message": "Duplicate request detected" and no jobId.

Field reference

Field names follow the app's own create-client and create-job endpoints. The API uses the word customer in field and response names; the app calls the same record a client.

Client fields (top level, all optional)

FieldTypeNotes
firstNamestring
middleNamestring
lastNamestring
emailstringUsed for duplicate matching.
phoneNumberstringA 10-digit US number in any format; stored as E.164 (+1…). Used for duplicate matching when no email is sent. Invalid numbers are rejected with 400.
addressobjectstreetAddress, city, state, zipCode — each optional.
descriptionstringFree-text notes about the client.
additionalEmailsstring[]
additionalPhoneNumbersstring[]Each a valid 10-digit US number.
additionalAddressesobject[]Same shape as address.
parentCategoryIdstringId of a client category in your company.
customFieldsobjectMaps custom field ids to values.
smsOptedOutbooleanfalse = opted in to text messages. Only stored for a brand-new client.
sourcestringWhere the client came from; shown in the app.
idempotencyKeystringAny unique id from your side, e.g. a form submission id.

Job fields (inside job, all optional)

FieldTypeNotes
jobTypestringDefaults to OTHER. One of: APPLIANCE_REPAIR, AUTO_REPAIR, CARPENTRY, CARPET_CLEANING, CONCRETE, DRYWALL, ELECTRICAL, ESTHETICIAN, FENCING, FLOORING, GARAGE_DOOR, GENERAL_CONTRACTING, GLASS_AND_GLAZING, GUTTERS, HANDYMAN, HVAC, INSULATION, JUNK_REMOVAL, LANDSCAPING, LOCKSMITH, MASONRY, MOVING, PAINTING, PEST_CONTROL, PET_GROOMING, PLASTERING, PLUMBING, POOL_AND_SPA, POWER_WASHING, ROOFING, SEPTIC, SIDING, SOLAR, TREE_SERVICE, WELDING, WINDOW_AND_DOOR, WINDOW_CLEANING, OTHER.
statusstringDefaults to NEW. One of NEW, ACCEPTED, SCHEDULED, IN_PROGRESS, COMPLETED, PAID, CANCELLED, or a status of the pipeline named by pipelineId.
descriptionstringDefaults to the webhook's source name.
startDateTimestringISO 8601.
endDateTimestringISO 8601.
employeeIdsstring[]Employees to assign. Assigned employees are texted when the company has that notification turned on.
salesEmployeeIdstring
pipelineIdstringA custom pipeline in your company; 400 if it does not exist.
colorstringCalendar color, e.g. #FF0000.
customFieldsobjectMaps job custom field ids to values.
addressobjectWhen present, all four of streetAddress, city, state, zipCode are required. An address of empty strings is treated as absent.
destinationAddressobjectSame rules as address; for moves and deliveries.

A job created this way behaves exactly like one created in the app: it receives a sequential job number, syncs to connected Google Calendars, and follows the company's assignment and inventory rules.

Errors and limits

Errors return a JSON body with a human-readable message.

StatusMeaning
400A field failed validation: invalid phone number, address not an object, unknown jobType/status/pipelineId, incomplete job address, or a body that is not a JSON object.
403Unknown or deleted webhook code, or the code does not allow job creation and a job object was sent.
429Rate limit exceeded. The endpoint allows 10 requests per second with bursts of 20. Retry after a short delay.
500Unexpected server error. Safe to retry with the same idempotencyKey.

The job is validated before anything is written, so a rejected request never leaves a partially created client behind.

Questions

Email support@tradesmentechnologies.com. We typically respond within one business day.