Tradesmen Technologies Tradesmen Technologies

API reference SaaS

SaaS Endpoints

POST /saas/subscribe

Creates a new SaaS subscription for the company. Stores the card in the TalusPay vault for recurring billing and charges the first month.

If the company has an active free trial (today is strictly before the trial end date), the card is stored in the vault but no charge is made. The billing day is set to the day of the free trial end date, and the first charge will occur on that date via the daily billing cron. If the company subscribes on the trial end date (edge case), they are charged normally as if no trial existed.

Authentication: Bearer token (ADMIN only)

Request Body:

{
  "maxEmployees": 3,
  "token": "tok_abc123...",
  "paymentType": "card"
}
Field Type Required Description
maxEmployees number Yes Number of users for the subscription (minimum 1)
token string Yes Payment token from TalusPay tokenizer
paymentType string No card (default) or ach

Response (201):

{
  "message": "Subscription created successfully",
  "subscriptionStatus": "ACTIVE",
  "maxEmployees": 3,
  "billingDayOfMonth": 15,
  "amountCharged": 7500,
  "transactionId": "txn_abc123"
}

Response when free trial is active (201):

{
  "message": "Subscription created successfully (free trial active — no charge until trial ends)",
  "subscriptionStatus": "ACTIVE",
  "maxEmployees": 3,
  "billingDayOfMonth": 1,
  "amountCharged": 0,
  "freeTrialEndDate": "2026-05-01"
}

Pricing: Base price of $45.00 (4500 cents) for the first user + $30.00 (3000 cents) for each additional user. Custom pricing may be configured per company. When the total is $0 (custom pricing) the card is vaulted, nothing is charged and transactionId is omitted.

Error Responses:

  • 400 - Missing or invalid fields, or a payment gateway error ("Payment error: ...")
  • 401 - Unauthorized
  • 402 - Payment declined (the vault record created for this attempt is removed)
  • 403 - Not an admin employee
  • 409 - Company already has an active subscription (checked before the body is validated)
  • 502 - TalusPay could not create the vault customer or store the payment method

PATCH /saas/max-employees

Increases the maximum number of employees for the company. Charges for the additional users using the stored payment method.

Authentication: Bearer token (ADMIN only)

Request Body:

{
  "maxEmployees": 5
}
Field Type Required Description
maxEmployees number Yes New maximum employee count (must be greater than current)

Response (200):

{
  "message": "Max employees increased successfully",
  "previousMax": 3,
  "newMax": 5,
  "additionalUsers": 2,
  "amountCharged": 4000,
  "transactionId": "txn_def456"
}

While the company's free trial is still active (today is strictly before the subscription's freeTrialEndDate), or when the computed charge is $0, nothing is charged: amountCharged still reports the computed amount and transactionId is omitted.

Error Responses:

  • 400 - New max not greater than current, no active subscription, missing or invalid maxEmployees, or a payment gateway error ("Payment error: ...")
  • 401 - Unauthorized
  • 402 - Payment declined
  • 403 - Not an admin employee

PUT /saas/payment-method

Updates the stored payment card for the company's SaaS subscription. Adds the new card to the TalusPay vault and removes the old one.

If the subscription status is PAYMENT_FAILED, the month whose charge was declined is still owed: the new payment method is charged immediately (same amount the billing run charges — billable employees x pricing) and the subscription returns to ACTIVE only if that charge is approved. On approval billingDayOfMonth is re-anchored to the day of this charge. If the charge is declined the endpoint returns 402, the new method is removed from the vault, and the subscription stays PAYMENT_FAILED with the previous method on file. An ACTIVE subscription is never charged by this endpoint.

Authentication: Bearer token (ADMIN only)

Request Body:

{
  "token": "tok_abc123...",
  "paymentType": "card"
}
Field Type Required Description
token string Yes Payment token from TalusPay tokenizer
paymentType string No card (default) or ach

Response (200):

{
  "message": "Payment method updated successfully",
  "subscriptionStatus": "ACTIVE",
  "paymentMethodLast4": "4242"
}

Response when reactivating a PAYMENT_FAILED subscription (200):

{
  "message": "Payment method updated and subscription reactivated",
  "subscriptionStatus": "ACTIVE",
  "paymentMethodLast4": "4242",
  "amountCharged": 4000,
  "transactionId": "txn_abc123",
  "billingDayOfMonth": 21
}

amountCharged is in cents (0 with no transactionId when the company's custom pricing totals $0). billingDayOfMonth is the new billing day.

Response when the recovery charge is declined (402):

{
  "message": "Payment declined",
  "details": "Insufficient funds"
}

The subscription remains PAYMENT_FAILED; the client should prompt for a different payment method.

paymentMethodLast4 is the last 4 digits of the newly stored card/bank account, or null if TalusPay did not surface it.

Error Responses:

  • 400 - No active or payment-failed subscription found, missing fields, or a payment gateway error ("Payment error: ...")
  • 401 - Unauthorized
  • 402 - The recovery charge on a PAYMENT_FAILED subscription was declined (subscription stays PAYMENT_FAILED)
  • 403 - Not an admin employee
  • 502 - Failed to store new payment method in TalusPay vault

POST /saas/cancel

Cancels the company's SaaS subscription.

  • For ACTIVE subscriptions, the status remains ACTIVE and the subscription is flagged with cancelAtPeriodEnd: true. The status flips to CANCELLED automatically on the next billing day (i.e., at the end of the paid-up period) — no further charges are made. The stored payment method is retained until finalization so the customer can POST /saas/reactivate during the grace period without re-entering their card.
  • For PAYMENT_FAILED subscriptions, the status flips to CANCELLED immediately and the stored payment method is deleted from the TalusPay vault, since there is no paid-up period to honor.

Authentication: Bearer token (ADMIN only)

Request Body: None

Response (200) — ACTIVE subscription scheduled to cancel at period end:

{
  "message": "Subscription scheduled to cancel at period end",
  "subscriptionStatus": "ACTIVE",
  "cancelAtPeriodEnd": true,
  "cancelledAt": "2026-04-02T15:30:00.000Z"
}

Response (200) — PAYMENT_FAILED subscription cancelled immediately:

{
  "message": "Subscription cancelled successfully",
  "subscriptionStatus": "CANCELLED",
  "cancelledAt": "2026-04-02T15:30:00.000Z"
}

Error Responses:

  • 401 - Unauthorized
  • 403 - Not an admin employee
  • 404 - No subscription found
  • 409 - Subscription is already cancelled or already scheduled to cancel

POST /saas/reactivate

Reactivates a subscription that was scheduled to cancel at period end, as if the cancellation had never happened. Clears the cancelAtPeriodEnd flag and cancelledAt timestamp. The stored payment method from the vault is reused, so no tokenization is needed. Only works during the grace period — once the subscription has already finalized to CANCELLED, a full re-subscribe via POST /saas/subscribe is required instead.

Authentication: Bearer token (ADMIN only)

Request Body: None

Response (200):

{
  "message": "Subscription reactivated successfully",
  "subscriptionStatus": "ACTIVE",
  "cancelAtPeriodEnd": false
}

Error Responses:

  • 401 - Unauthorized
  • 403 - Not an admin employee
  • 404 - No subscription found
  • 409 - Subscription is not scheduled to cancel (nothing to reactivate)

GET /saas/pricing

Returns the SaaS pricing for the authenticated company. Returns custom pricing if configured, otherwise default pricing.

Authentication: Bearer token

Response (200):

{
  "basePrice": 4500,
  "additionalUserPrice": 3000,
  "isCustomPricing": false
}
Field Type Description
basePrice number Price in cents for the first user
additionalUserPrice number Price in cents for each additional user
isCustomPricing boolean Whether this company has custom pricing

GET /saas/subscription

Returns the current SaaS subscription details for the authenticated company. Returns the same subscription object included in the login response.

Authentication: Bearer token

Response (200):

{
  "status": "ACTIVE",
  "tradesmenTechPublicKey": "pub_xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "freeTrialEndDate": null,
  "hasPaymentMethod": true,
  "paymentMethodLast4": "4242",
  "billingDayOfMonth": 15,
  "maxEmployees": 5,
  "lastPaymentDate": "2026-04-01T09:00:00.000Z",
  "lastPaymentAmount": 11500,
  "cancelAtPeriodEnd": false,
  "cancelledAt": null,
  "pricing": {
    "basePrice": 4500,
    "additionalUserPrice": 3000,
    "isCustomPricing": false
  }
}
Field Type Description
status string NEVER_SUBSCRIBED, ACTIVE, PAYMENT_FAILED, or CANCELLED. If the underlying subscription is CANCELLED but the company still has an unexpired free trial (today is strictly before freeTrialEndDate), the effective status is reported as ACTIVE for the duration of the trial.
tradesmenTechPublicKey string or null TalusPay public key for tokenizing SaaS payments
freeTrialEndDate string or null Trial end date (YYYY-MM-DD), or null if no trial
hasPaymentMethod boolean Whether the company has a card on file
paymentMethodLast4 string or null Last 4 digits of the card/bank account on file, or null if unknown (e.g. subscriptions created before this field existed)
billingDayOfMonth number or null Day of month for recurring billing, or null if not subscribed
maxEmployees number or null Subscribed employee limit, or null if not subscribed
lastPaymentDate string or null ISO timestamp of most recent charge, or null
lastPaymentAmount number or null Most recent charge in cents, or null
cancelAtPeriodEnd boolean true when cancel was requested and status will flip to CANCELLED on the next billing day
cancelledAt string or null ISO timestamp of when cancel was requested, or null
pricing.basePrice number Price in cents for the first user
pricing.additionalUserPrice number Price in cents for each additional user
pricing.isCustomPricing boolean Whether this company has a custom rate

Subscription Object in Login Response

The login endpoint (POST /accounts/login) includes a subscription object with all SaaS details:

{
  "subscription": {
    "status": "ACTIVE",
    "tradesmenTechPublicKey": "pub_xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "freeTrialEndDate": "2026-05-01",
    "hasPaymentMethod": true,
    "paymentMethodLast4": "4242",
    "billingDayOfMonth": 15,
    "maxEmployees": 5,
    "lastPaymentDate": "2026-04-01T09:00:00.000Z",
    "lastPaymentAmount": 11500,
    "cancelAtPeriodEnd": false,
    "cancelledAt": null,
    "pricing": {
      "basePrice": 4500,
      "additionalUserPrice": 3000,
      "isCustomPricing": false
    }
  }
}
Field Type Description
status string NEVER_SUBSCRIBED, ACTIVE, PAYMENT_FAILED, or CANCELLED. If the underlying subscription is CANCELLED but the company still has an unexpired free trial (today is strictly before freeTrialEndDate), the effective status is reported as ACTIVE for the duration of the trial.
tradesmenTechPublicKey string or null TalusPay public key for tokenizing SaaS payments
freeTrialEndDate string or null Trial end date (YYYY-MM-DD), or null if no trial
hasPaymentMethod boolean Whether the company has a card on file
paymentMethodLast4 string or null Last 4 digits of the card/bank account on file, or null if unknown (e.g. subscriptions created before this field existed)
billingDayOfMonth number or null Day of month for recurring billing, or null if not subscribed
maxEmployees number or null Subscribed employee limit, or null if not subscribed
lastPaymentDate string or null ISO timestamp of most recent charge, or null
lastPaymentAmount number or null Most recent charge in cents, or null
cancelAtPeriodEnd boolean true when cancel was requested and status will flip to CANCELLED on the next billing day
cancelledAt string or null ISO timestamp of when cancel was requested, or null
pricing.basePrice number Price in cents for the first user
pricing.additionalUserPrice number Price in cents for each additional user
pricing.isCustomPricing boolean Whether this company has a custom rate

Daily Billing (Cron)

A scheduled process runs daily at 9:00 AM UTC to process monthly SaaS billing:

  1. Scans all ACTIVE subscriptions
  2. For each company whose billingDayOfMonth matches today:
    • If cancelAtPeriodEnd is set, the subscription is finalized to CANCELLED and the stored payment method is deleted from the vault — nothing is charged.
    • If the subscription's free trial is still active (today is strictly before freeTrialEndDate), the company is skipped.
    • Counts actual billable employees in the database. Employees with hasAppAccess: false have no app access and are excluded from this count, so they are never charged a per-seat fee. (Employees created before hasAppAccess existed are treated as having access and are counted.)
    • Reduces maxEmployees to the actual billable count if fewer billable employees exist
    • Calculates the monthly charge based on the adjusted employee count. A $0 total (custom pricing) is recorded as paid (lastPaymentAmount: 0) without contacting the gateway.
    • Charges the stored payment method via the TalusPay vault
    • On success: updates lastPaymentDate and adjusted maxEmployees
    • On a declined charge: sets subscriptionStatus to PAYMENT_FAILED and emails the company (the company's email) that the payment was declined and how to update the payment method; the support inbox is notified separately. The subscription returns to ACTIVE only through a successful charge via PUT /saas/payment-method.
    • A subscription already charged earlier the same UTC day (a same-day subscribe or recovery charge) is skipped, so it is never billed twice in one day.
    • If the attempt itself errors (gateway or database failure), the subscription is left untouched (still ACTIVE, not retried until next month) and only the support inbox is notified.

If the billing day exceeds the number of days in the current month (e.g., billing day 31 in a 28-day month), the charge occurs on the last day of the month.