Tradesmen Technologies Tradesmen Technologies

API reference Notifications

Notifications Service API Endpoints

The production API base URL is https://api.tradesmentechnologies.com/.

Authentication

All endpoints require a Bearer token in the Authorization header: Authorization: Bearer <your_token>

Mutating requests may carry an Idempotency-Key header so a retry never acts twice — see Idempotent Retries in the Accounts API documentation.

Base Path

/prod/notifications


Enums

SmsMessageType

  • ON_MY_WAY
  • TECHNICIAN_ARRIVED
  • JOB_COMPLETED
  • JOB_ASSIGNED

SMS Opt-Out

SMS opt-out (STOP) and HELP keyword handling are managed automatically by AWS Pinpoint SMS Voice V2 at the phone number level. When a recipient replies STOP, Pinpoint blocks future messages to that number. When a recipient replies HELP, Pinpoint sends a configurable auto-response. No application-level opt-out tracking is needed.


Endpoints

Send SMS

Send an SMS notification to the customer associated with a job.

  • Method: POST
  • Path: /prod/notifications/sms
  • Headers: Authorization: Bearer <token>
  • Request Body:
    {
      "jobId": "uuid",
      "messageType": "ON_MY_WAY",
      "employeeId": "uuid",
      "phoneNumber": "4445556666"
    }
    
  • Note: jobId and messageType are required. employeeId is optional and only applies to customer-facing messages (ON_MY_WAY, TECHNICIAN_ARRIVED, JOB_COMPLETED) — when provided, that employee's full name (first and last name) is used as the technician name in the message. The employee must belong to the caller's company; a 400 is returned if it does not. The employee does not need to be on the job's assigned employee list (the UI lets a user pick any company employee when the job has nobody assigned). When omitted, the job's first assigned employee is used; if the job has no assigned employees, the message goes out without a technician name. Ignored for JOB_ASSIGNED (which sends to all assigned employees). phoneNumber is optional and only applies to customer-facing messages — it selects which single number to text. When provided it must be a valid 10-digit US number that matches the customer's primary phoneNumber or one of their additionalPhoneNumbers (a 400 is returned otherwise); when omitted, the customer's primary phoneNumber on file is used. The SMS is always sent to exactly one number. The message content is determined by the messageType.
  • Message Templates: Every message starts with the fixed platform brand prefix Tradesmen Tech: (the registered 10DLC sender name — not the company's own name). Technician name and appointment time are included when available; {firstName} falls back to "there" when the recipient has no first name.
    • ON_MY_WAY: "Tradesmen Tech: Hi {firstName}, your technician {technicianName} from {companyName} is on the way for your {time} appointment!" (the "from {companyName}" clause uses the company's name on record and is included only when the company has one)
    • TECHNICIAN_ARRIVED: "Tradesmen Tech: Hi {firstName}, your technician {technicianName} has arrived for your {time} appointment!"
    • JOB_COMPLETED: "Tradesmen Tech: Hi {firstName}, your service appointment has been completed. Thank you!"
    • JOB_ASSIGNED (sent to employees, not customers): "Tradesmen Tech: Hi {firstName}, you have been scheduled for a job on {jobDateTime}. Please check the app for details."
  • First-message opt-out notice: The first SMS ever sent to a given customer (or, for JOB_ASSIGNED, to a given employee) gets an extra line appended: "Reply STOP to opt out of text messages." The recipient's smsConsentNotified flag is then set so later messages omit it.
  • Technician page link (ON_MY_WAY only): When the company has the showEmployeePageInOmw feature flag enabled, the ON_MY_WAY message gets an extra line linking to the technician's public web page: "Meet your technician: https://{webClientDomain}/technician/?company={companyId}&employee={employeeId}&job={jobId}". The job parameter scopes the page's live-location requests to this job's tracking session, so once the job ends the link can no longer reveal the technician's location. The link is included whenever the flag is on — the technician does not need a configured profile; the page renders the employee's name, role, and contact info, omitting the photo/bio if no profile exists. The link is only appended to ON_MY_WAY, not the other message types.
  • GPS tracking session (side effect): Sending ON_MY_WAY while showEmployeePageInOmw is enabled also opens a live-GPS tracking session for the resolved technician (whether resolved from employeeId or the job's first assigned employee). The named technician's mobile app — polling GET /location/session (see the Location Service API) — sees the session and begins streaming GPS, so a dispatcher can trigger tracking even when they are not the technician on the way. Sending TECHNICIAN_ARRIVED or JOB_COMPLETED for the same jobId closes the session (so the app stops streaming) — this is keyed on the jobId, so it ends the job's live session regardless of which employee the closing text resolves to or which user sends it. A session also auto-expires after a 4-hour TTL backstop. Session bookkeeping is best-effort and never affects whether the SMS is sent or the response status.
  • Success Response (customer messages): 200 OK
    {
      "message": "SMS sent successfully",
      "messageId": "uuid",
      "snsMessageId": "string"
    }
    
  • Success Response (JOB_ASSIGNED): 200 OK
    {
      "message": "SMS sent to 2 employees",
      "messagesSent": 2
    }
    
  • Error Responses:
    • 400 Bad Request — Missing required fields, invalid messageType, invalid phoneNumber or one that does not match the customer's numbers on file, customer has no phone number, the job has no client (customerId is null), or no employees assigned to job.
    • 401 Unauthorized — Missing or invalid token.
    • 403 Forbidden — Recipient has opted out of SMS messages (managed by AWS).
    • 404 Not Found — Job or customer not found.
    • 500 Internal Server Error

Get SMS History

Retrieve the SMS message history for a specific job.

  • Method: GET
  • Path: /prod/notifications/sms/{jobId}
  • Headers: Authorization: Bearer <token>
  • Path Parameters:
    • jobId (required) — The ID of the job.
  • Success Response: 200 OK
    {
      "messages": [
        {
          "jobId": "uuid",
          "sentAt": "ISO-8601",
          "messageId": "uuid",
          "companyId": "uuid",
          "customerId": "uuid",
          "employeeId": "uuid",
          "phoneNumber": "+15551234567",
          "messageType": "ON_MY_WAY",
          "messageBody": "Tradesmen Tech: Hi John, your technician Sam Jones from Test Co is on the way for your 9:00 AM appointment!",
          "snsMessageId": "string"
        }
      ]
    }
    
  • Note: Messages are returned in reverse chronological order (most recent first). For customer messages employeeId is the employee who sent the text. For JOB_ASSIGNED rows (one per employee texted) employeeId is the recipient employee, sentAt is "{ISO-8601}#{employeeId}" (the timestamp suffixed with the employee ID so the rows of one send do not collide), and customerId is an empty string when the job has no client. Besides the SmsMessageType values, messageType may be DOCUMENT: a document texted to the customer through POST /jobs/documents/{documentId}/send-sms (see the Jobs API); that row also carries the documentId. DOCUMENT is not accepted by Send SMS.
  • Error Responses:
    • 400 Bad Request — Missing jobId path parameter.
    • 401 Unauthorized — Missing or invalid token.
    • 404 Not Found — Job not found.
    • 500 Internal Server Error