Homebase360 API (1.4.0)

Download OpenAPI specification:

API for integration with Homebase360 customer and job management system

Health Check

Test API authentication

Simple endpoint to verify API key authentication is working correctly. Returns basic information about the authenticated business account.

Authorizations:
ApiKeyAuth

Responses

Request samples

curl -X GET "https://us-central1-homebase-360.cloudfunctions.net/api/v1/ping" \
  -H "x-api-key: your-api-key-here" \
  -H "Content-Type: application/json"

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Customers

Get customers

Retrieves customer information based on search criteria. Multiple search parameters can be combined and will return customers matching ANY of the provided criteria (logical OR). If no criteria is provided, returns empty array.

Authorizations:
ApiKeyAuth
query Parameters
customerId
string
Example: customerId=Ekk9AvDeDihAEU8CMT0W

Specific customer ID to look for

phone
string
Example: phone=+13031234567

Customer's mobile phone number (E.164 format, e.g. +13038284444)

email
string
Example: email=john.smith@example.com

Customer's email address

name
string
Example: name=deri

Fuzzy, typo-tolerant search by customer name (first, last, or display name). E.g. "deri" matches "Derick". Returns up to limit matches, ordered by relevance; not paginated (no cursor).

identifiers
string
Example: identifiers=abc123,+13038284444,john@example.com

Comma-separated list of customer IDs, phone numbers, or email addresses (max 100 identifiers)

limit
integer <= 100
Default: 25
Example: limit=50

Maximum number of results to return (max 100, default 25)

Responses

Request samples

curl -X GET "https://us-central1-homebase-360.cloudfunctions.net/api/v1/customers?customerId=Ekk9AvDeDihAEU8CMT0W" \
  -H "x-api-key: your-api-key-here" \
  -H "Content-Type: application/json"

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ]
}

Create a new customer

Creates a new customer with the provided information. Requires at least firstName or lastName, and at least one contact method (phone or email).

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
firstName
string

Customer's first name

lastName
string

Customer's last name

object (Phone)

All phone numbers must be in E.164 format (e.g. +13038284444)

email
Array of strings

List of email addresses (max 2). Can also provide as comma or semicolon-separated string.

address
Array of strings

List of physical addresses (max 2). Can also provide as semicolon or asterisk-separated string.

notes
string
Default: ""

Additional notes about the customer

tags
Array of strings

Tags for categorization. Can also provide as comma, semicolon, or asterisk-separated string.

notifications
boolean
Default: true

Whether the customer should receive notifications

Responses

Request samples

Content type
application/json
{
  • "firstName": "John",
  • "lastName": "Smith",
  • "phone": {
    },
  • "email": [
    ],
  • "address": [
    ],
  • "notes": "Prefers afternoon appointments",
  • "tags": [
    ],
  • "notifications": true
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Update an existing customer

Updates an existing customer's information

Authorizations:
ApiKeyAuth
path Parameters
customerId
required
string

ID of the customer to update

Request Body schema: application/json
required
firstName
string

Customer's first name

lastName
string

Customer's last name

object (Phone)

All phone numbers must be in E.164 format (e.g. +13038284444)

email
Array of strings

List of email addresses

address
Array of strings

List of physical addresses

notes
string

Additional notes about the customer

tags
Array of strings

Tags for categorization

notifications
boolean

Whether the customer should receive notifications

Responses

Request samples

Content type
application/json
{
  • "firstName": "John",
  • "lastName": "Smith Updated",
  • "phone": {
    },
  • "notes": "Updated notes",
  • "notifications": false
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Jobs

Get jobs/schedule

Retrieves jobs based on search criteria.

  • No params → current day's jobs (ordered by start time).
  • customerId alone → all jobs for that customer, ordered newest-first by dateAdded (paginate with cursor).
  • sort=dateAdded → all jobs ordered by creation date (defaults to newest-first).
  • sort=lastUpdated → all jobs ordered by last modification time (defaults to newest-first). Useful for change-feed / sync integrations that need to surface recent edits and reschedules.
  • startDate/endDate → jobs whose start falls in the range, ordered by start time.

When sort is provided, the default today-window filter is NOT applied — the caller almost always wants results across all time, not just today.

Authorizations:
ApiKeyAuth
query Parameters
jobId
string

Specific job ID to look for

customerId
string

Filter jobs by customer ID. When used alone, returns all jobs for that customer ordered newest-first by dateAdded.

startDate
string <date-time>

Start date in ISO 8601 format (e.g. "2023-05-15T00:00:00Z") - jobs starting on/after this date

endDate
string <date-time>

End date in ISO 8601 format (e.g. "2023-05-15T23:59:59Z") - jobs starting on/before this date

sort
string
Enum: "dateAdded" "lastUpdated"

Sort field.

  • dateAdded — order by creation date (newest-first by default).
  • lastUpdated — order by last modification time (newest-first by default). Useful for change-feed integrations. Any other value returns 400.
orderDirection
string
Enum: "asc" "desc"

Sort direction. Defaults to desc when sort is provided (or customerId is used alone), asc otherwise.

limit
integer <= 100
Default: 50

Maximum number of results to return (max 100)

cursor
string

Cursor token for pagination (returned as nextPageToken from the previous response).

status
string

Comma-separated derived statuses to include (matches derivedStatus): notStarted, driving, inProgress, finished, unpaid, partiallyPaid, paid, prepaid, cancelled, missed. Filtered server-side while filling the page.

paymentType
string

Only jobs with a recorded payment of this type (e.g. card, cash, check)

leadSource
string

Job/lead source name — "online", "direct", or a custom source name (case-insensitive)

recurring
string
Enum: "true" "false"

"true" = recurring jobs only, "false" = one-off jobs only

includeCancelled
string
Default: "true"
Enum: "true" "false"

"false" drops cancelled jobs (the web Jobs report default)

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "nextPageToken": "string"
}

Create a new job

Creates a new job associated with a customer

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
customerId
required
string

Customer ID (must exist in your account)

start
required
string <date-time>

Start date and time in ISO 8601 format

end
required
string <date-time>

End date and time in ISO 8601 format (must be after start)

required
Array of objects (LineItem) non-empty

List of items/services for the job (minimum 1 item required)

note
string
Default: ""

Note for the job (optional)

LeadSource (string) or object

Lead source information (optional). Accepts string format or legacy object format for backwards compatibility

salespersonEmail
string

Email of an existing employee to set as the salesperson on the lead source (used with string leadSource). The salesperson gains view access to the job. If no employee matches, the job is still created without a salesperson.

Responses

Request samples

Content type
application/json
{
  • "customerId": "Ekk9AvDeDihAEU8CMT0W",
  • "start": "2023-05-15T14:30:00Z",
  • "end": "2023-05-15T16:30:00Z",
  • "lineItems": [
    ],
  • "note": "Please call customer before arrival"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Update an existing job

Updates an existing job's information. Passing lineItems replaces the whole list and recomputes the job total — to change one item, use POST /v1/jobs/{jobId}/line-items. Line-item changes are rejected once the job has been paid (409); other fields stay editable.

Authorizations:
ApiKeyAuth
path Parameters
jobId
required
string

ID of the job to update

Request Body schema: application/json
required
start
string <date-time>

New start date and time in ISO 8601 format

end
string <date-time>

New end date and time in ISO 8601 format

note
string

New note for the job

Array of strings or string

Replacement assignment — array of employee emails, or a comma-separated string. [] clears all assignments.

Array of objects (LineItem)

Replacement array of line items (recomputes the job total). To change one item, use the line-items endpoint instead.

leadSource
string (LeadSource)

Source of the lead. Use "Online" for online sources, "Direct" for direct contact/referrals, or provide a custom source name (e.g., "Facebook Ad", "Google Ads", "Referral Partner"). Custom sources will be automatically created and associated with your business.

salespersonEmail
string

Email of an existing employee to set as the salesperson on the lead source (grants them view access to the job). Send "" or null to clear the salesperson. Returns 400 if no employee matches the email.

Responses

Request samples

Content type
application/json
{
  • "start": "2023-05-15T15:00:00Z",
  • "end": "2023-05-15T17:00:00Z",
  • "note": "Customer requested a later time"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Edit a job's line items

Edits a job's line items with surgical operations instead of replacing the whole list — so you can change, add, or remove a single item without re-sending (and risking the loss of) the others.

Operations are applied in order against the current list:

  • add — append a new item
  • update — change only the provided fields of a matched item (the rest are kept)
  • remove — delete a matched item
  • replace_all — replace the whole list (must be the only operation)

Items are matched by name (case-insensitive); when several items share a name, pass a 0-based index to disambiguate. The job total is recomputed automatically. Removing the last remaining item is rejected. Once the job has been paid, line-item edits are rejected (409).

Authorizations:
ApiKeyAuth
path Parameters
jobId
required
string

ID of the job to edit

Request Body schema: application/json
required
required
Array of objects (LineItemOperation) non-empty

Ordered list of line-item operations to apply

Responses

Request samples

Content type
application/json
{
  • "operations": [
    ]
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Tasks

Get tasks

Retrieves tasks (to-dos / reminders, optionally attached to a customer), with cursor-based pagination.

  • No params → today's scheduled tasks, ordered by start. Unscheduled tasks (no start) are excluded — pass sort=createdAt to list all tasks.
  • taskId → that single task.
  • startDate/endDate → tasks whose start falls in the range, ordered by start (combinable with status/employeeId; not combinable with customerId).
  • status, employeeId, or customerId → equality filters, paginated by document id.
  • sort=createdAt / sort=updatedAt → all tasks (including unscheduled), newest-first. Applies to the otherwise-unfiltered listing.
Authorizations:
ApiKeyAuth
query Parameters
taskId
string

Specific task ID to look for

customerId
string

Filter tasks for a specific customer

status
string
Enum: "pending" "completed"

Filter by completion status

employeeId
string

Filter by assigned employee's user ID

startDate
string <date-time>

ISO 8601 — tasks starting on/after this time

endDate
string <date-time>

ISO 8601 — tasks starting on/before this time

sort
string
Enum: "createdAt" "updatedAt"

Order all tasks by creation or last-update time (newest-first by default). Applies to the otherwise-unfiltered listing; any other value returns 400.

orderDirection
string
Enum: "asc" "desc"

Sort direction. Defaults to asc for date/today-window queries, desc when sort is provided.

limit
integer <= 100
Default: 50

Maximum number of results to return (max 100)

cursor
string

Cursor token for pagination (returned as nextPageToken from the previous response).

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "nextPageToken": "string"
}

Create a new task

Creates a task (to-do / reminder), optionally attached to a customer and assigned to employees. title and instructions are required.

When assignees and notification methods are set, assigned employees are notified automatically; when a reminder is set, it is delivered automatically before the task's start time.

Notes:

  • start and end must BOTH be provided or BOTH omitted (a task is either scheduled or unscheduled).
  • reminder requires start/end (it fires relative to start).
  • Tasks created via the API have no human creator, so createdBy is null. An unassigned task has no viewers and will not appear in any technician's in-app task list — assign at least one employee for it to be visible in the app.
Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
title
required
string

Task title (required; may be empty string but not null)

instructions
required
string

Task details/instructions (required; may be empty string but not null)

customerId
string

Existing customer ID to attach to the task (optional)

start
string <date-time>

Start date/time, ISO 8601. Must be paired with end.

end
string <date-time>

End date/time, ISO 8601. Must be paired with start.

assignedTo
Array of strings

Array of employee emails to assign the task to (optional)

reminder
string
Default: "none"
Enum: "none" "start" "thirtyMin" "oneHour" "twoHour" "fiveHour" "twentyFourHour"

Single reminder before start (default none). Requires start/end.

object (NotificationMethods)

Notification preferences applied to both assignment and reminder notifications.

note
string

Initial note added to the task's note history (optional)

Responses

Request samples

Content type
application/json
{
  • "title": "Call customer to confirm",
  • "instructions": "Confirm the Tuesday window cleaning appointment.",
  • "customerId": "Ekk9AvDeDihAEU8CMT0W",
  • "start": "2026-06-16T09:00:00-06:00",
  • "end": "2026-06-16T09:30:00-06:00",
  • "assignedTo": [
    ],
  • "reminder": "oneHour",
  • "notificationMethods": {
    },
  • "note": "High-priority customer"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Update an existing task

Updates a task. Only the provided fields change. Set status to completed to mark a task done (or pending to reopen it); completedBy is null for API-driven completions. A provided note is appended to the task's note history. Reassigning employees (adding new ones) notifies the newly-assigned employees automatically.

Notes:

  • start and end must be updated together. Pass both as null to clear the schedule.
  • Changing reminder resets its sent-state so the new reminder can fire; a non-none reminder requires the task to have a start (existing or set in the same call).
  • Pass assignedTo as [] to unassign everyone. Any email that doesn't match an employee returns 400.
Authorizations:
ApiKeyAuth
path Parameters
taskId
required
string

ID of the task to update

Request Body schema: application/json
required
status
string
Enum: "pending" "completed"

completed marks the task done; pending reopens it

title
string
instructions
string
start
string or null <date-time>

New start, ISO 8601. Pass together with end; pass both as null to clear the schedule.

end
string or null <date-time>

New end, ISO 8601. Pass together with start.

assignedTo
Array of strings

Full replacement list of employee emails. [] clears assignments.

reminder
string
Enum: "none" "start" "thirtyMin" "oneHour" "twoHour" "fiveHour" "twentyFourHour"

Single reminder before start

object (NotificationMethods)

Notification preferences applied to both assignment and reminder notifications.

note
string

Note appended to the task's note history

Responses

Request samples

Content type
application/json
Example
{
  • "status": "completed",
  • "note": "Confirmed with customer."
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Employees

Get employees

Retrieves the business's employees (team members), with cursor-based pagination. Read-only.

Use this to discover employee names, emails, and ids — pass an employee's email to dispatchedTo (jobs) or assignedTo (tasks/leads) when assigning work, and their employeeId to the employeeId filter on GET /v1/tasks (and similar).

  • No params → all employees, ordered by first name.
  • employeeId → that single employee (scoped to your business).
  • email → exact (case-insensitive) match.
  • search → case-insensitive substring match on name (first + last + display) and email.
Authorizations:
ApiKeyAuth
query Parameters
employeeId
string

Fetch a specific employee by ID

email
string

Exact email address (case-insensitive)

search
string

Substring to match against employee name or email

limit
integer <= 100
Default: 50

Maximum number of results to return (max 100)

cursor
string

Cursor token for pagination (returned as nextPageToken from the previous response).

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "nextPageToken": "string"
}

Leads

Get leads

Retrieves leads based on search criteria.

Non-archived leads are returned by default. Pass includeArchived=true to include archived leads alongside, or includeArchived=only to return archived leads only.

Ordering (all served by a single archived + dateAdded composite index):

  • No other filter (only the default archived filter applies) → newest-first by dateAdded.
  • startDate / endDate filter applied → ordered by dateAdded ascending. Filters operate on dateAdded.
  • customerId, status, or employeeId filter applied → results paginated in document-ID order.
Authorizations:
ApiKeyAuth
query Parameters
leadId
string

Fetch a specific lead by ID

customerId
string

Fetch all leads for a specific customer

status
string
Enum: "new" "first_contact" "second_contact" "third_contact" "on_hold"

Filter by lead status

employeeId
string

Filter by assigned employee ID

startDate
string <date-time>

ISO-8601 date — only return leads with dateAdded on or after this date

endDate
string <date-time>

ISO-8601 date — only return leads with dateAdded on or before this date

includeArchived
string
Enum: "true" "only"

Archive filter. true includes archived leads alongside non-archived. only returns archived leads only. Omitted (default) returns non-archived only.

cursor
string

Cursor token from a previous response (nextPageToken) to retrieve the next page of results

limit
integer <= 100
Default: 25

Maximum number of results to return

Responses

Request samples

curl -X GET "https://us-central1-homebase-360.cloudfunctions.net/api/v1/leads?status=new&limit=10" \
  -H "x-api-key: your-api-key-here" \
  -H "Content-Type: application/json"

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ]
}

Create a new lead

Creates a new lead with smart customer lookup/creation. This intelligent endpoint handles three scenarios:

Scenario 1: Existing Customer by ID Provide the customerId field to create a lead for an existing customer. Returns 404 if customer not found.

Scenario 2: Phone-based Lookup/Merge Provide customer details including phone.mobile. The API will:

  • Search for an existing customer with that mobile phone number
  • If found: Merge new data with existing customer, update customer record, create lead
  • If not found: Create new customer, create lead

Scenario 3: New Customer Provide customer details without customerId or phone.mobile. The API will:

  • Always create a new customer
  • Create lead for the new customer

You can either provide a customerId, or a name and a contact method: firstName/lastName and any-phone/email.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
customerId
string

Method 1: Existing customer ID

firstName
string

Method 2: Customer's first name (at least firstName or lastName required if using customer details)

lastName
string

Method 2: Customer's last name (at least firstName or lastName required if using customer details)

object (Phone)

All phone numbers must be in E.164 format (e.g. +13038284444)

email
Array of strings

Method 2: List of email addresses

address
Array of strings

Method 2: List of physical addresses

notes
string

Method 2: Additional notes about the customer

tags
Array of strings

Method 2: Tags for categorization

notifications
boolean

Method 2: Whether customer should receive notifications

Array of objects (LineItem)

Array of line items (optional for leads)

note
string

Note about the lead

leadSource
string (LeadSource)

Source of the lead. Use "Online" for online sources, "Direct" for direct contact/referrals, or provide a custom source name (e.g., "Facebook Ad", "Google Ads", "Referral Partner"). Custom sources will be automatically created and associated with your business.

status
string
Default: "new"
Enum: "new" "first_contact" "second_contact" "third_contact" "on_hold"

Initial status of the lead

assignedTo
Array of strings

Array of employee IDs to assign the lead to

Responses

Request samples

Content type
application/json
Example
{
  • "customerId": "Ekk9AvDeDihAEU8CMT0W",
  • "lineItems": [
    ],
  • "note": "Customer interested in monthly service",
  • "leadSource": "Online",
  • "status": "new"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Update an existing lead

Updates an existing lead's information. Only non-archived leads can be updated.

Authorizations:
ApiKeyAuth
path Parameters
leadId
required
string

ID of the lead to update

Request Body schema: application/json
required
status
string
Enum: "new" "first_contact" "second_contact" "third_contact" "on_hold"

Updated lead status

note
string

Updated note for the lead

Array of objects (LineItem)

Replacement array of line items

assignedTo
Array of strings

Replacement array of employee IDs

leadSource
string (LeadSource)

Source of the lead. Use "Online" for online sources, "Direct" for direct contact/referrals, or provide a custom source name (e.g., "Facebook Ad", "Google Ads", "Referral Partner"). Custom sources will be automatically created and associated with your business.

Responses

Request samples

Content type
application/json
{
  • "status": "first_contact",
  • "note": "Called customer, discussed options. Following up next week."
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Edit a lead's line items

Edits a lead's line items with surgical operations instead of replacing the whole list — so you can change, add, or remove a single item without re-sending (and risking the loss of) the others.

Operations are applied in order against the current list:

  • add — append a new item
  • update — change only the provided fields of a matched item (the rest are kept)
  • remove — delete a matched item
  • replace_all — replace the whole list (must be the only operation)

Items are matched by name (case-insensitive); when several items share a name, pass a 0-based index to disambiguate. Removing the last remaining item is rejected. Converted leads cannot be edited.

Authorizations:
ApiKeyAuth
path Parameters
leadId
required
string

ID of the lead to edit

Request Body schema: application/json
required
required
Array of objects (LineItemOperation) non-empty

Ordered list of line-item operations to apply

Responses

Request samples

Content type
application/json
{
  • "operations": [
    ]
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Estimates

Get estimates

Retrieves estimates (quotes) based on search criteria.

Ordering:

  • No filters → newest-created first by dateAdded.
  • sort=lastUpdated → most-recently-modified first.
  • startDate / endDate → ordered by dateAdded ascending (filters operate on dateAdded).
  • customerId alone → newest-created first.
Authorizations:
ApiKeyAuth
query Parameters
estimateId
string

Fetch a specific estimate by ID (short-circuits all other filters)

customerId
string

Fetch all estimates for a specific customer

startDate
string <date-time>

ISO-8601 date — only return estimates with dateAdded on or after this date

endDate
string <date-time>

ISO-8601 date — only return estimates with dateAdded on or before this date

sort
string
Enum: "dateAdded" "lastUpdated"

Sort field — dateAdded (creation time) or lastUpdated (last modification). Unknown values return 400.

orderDirection
string
Enum: "asc" "desc"

Sort direction. Defaults to desc for sortable branches, asc for date-range queries.

cursor
string

Cursor token from a previous response (nextPageToken) to retrieve the next page of results

limit
integer <= 100
Default: 25

Maximum number of results to return

Responses

Request samples

curl -X GET "https://us-central1-homebase-360.cloudfunctions.net/api/v1/estimates?limit=10" \
  -H "x-api-key: your-api-key-here" \
  -H "Content-Type: application/json"

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "nextPageToken": "string"
}

Create an estimate

Creates an estimate (an unsent draft quote). Provide either an existing customerId or new-contact details (a name plus phone or email), in which case a customer is found-or-created automatically — the same contract as creating a lead.

The estimate is created in the pending public status with no sent timestamp (a draft). Delivering the estimate to the customer (PDF + email/SMS) remains an in-app action; this endpoint does not send anything.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
customerId
string

Method 1: Existing customer ID

firstName
string

Method 2: Customer's first name (at least firstName or lastName required if using customer details)

lastName
string

Method 2: Customer's last name (at least firstName or lastName required if using customer details)

object (Phone)

All phone numbers must be in E.164 format (e.g. +13038284444)

email
Array of strings

Method 2: List of email addresses

address
Array of strings

Method 2: List of physical addresses

Array of objects (LineItem)

Services/products being quoted. Defaults to a single placeholder item if omitted.

object or null

Estimate-level discount off the line-item subtotal; pass null to clear. Not allowed on multi-option estimates.

note
string

Note shown on the estimate

leadSource
string (LeadSource)

Source of the lead. Use "Online" for online sources, "Direct" for direct contact/referrals, or provide a custom source name (e.g., "Facebook Ad", "Google Ads", "Referral Partner"). Custom sources will be automatically created and associated with your business.

salespersonEmail
string

Email of an existing employee to set as the salesperson on the lead source

Responses

Request samples

Content type
application/json
{
  • "customerId": "cust456",
  • "lineItems": [
    ],
  • "note": "Quote for spring cleaning"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Update an existing estimate

Updates an existing estimate. Only the provided fields change. Updatable fields are lineItems, note, and leadSource. Passing lineItems replaces the whole array and recomputes the total — to change a single item, prefer POST /estimates/{estimateId}/line-items.

Approved estimates (the customer accepted the quote) and estimates already converted to a job are immutable and return 409.

Authorizations:
ApiKeyAuth
path Parameters
estimateId
required
string

ID of the estimate to update

Request Body schema: application/json
required
Array of objects (LineItem)

Replacement array of line items (recomputes the total). To change one item, use the line-items endpoint instead.

object or null

Estimate-level discount off the line-item subtotal; pass null to clear. Not allowed on multi-option estimates.

note
string

Updated note shown on the estimate

leadSource
string (LeadSource)

Source of the lead. Use "Online" for online sources, "Direct" for direct contact/referrals, or provide a custom source name (e.g., "Facebook Ad", "Google Ads", "Referral Partner"). Custom sources will be automatically created and associated with your business.

salespersonEmail
string

Email of an existing employee to set as the salesperson (used with leadSource)

Responses

Request samples

Content type
application/json
{
  • "note": "Updated quote after site visit",
  • "lineItems": [
    ]
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Edit an estimate's line items

Edits an estimate's line items with surgical operations instead of replacing the whole list — so you can change, add, or remove a single item without re-sending (and risking the loss of) the others.

Operations are applied in order against the current list:

  • add — append a new item
  • update — change only the provided fields of a matched item (the rest are kept)
  • remove — delete a matched item
  • replace_all — replace the whole list (must be the only operation)

Items are matched by name (case-insensitive); when several items share a name, pass a 0-based index to disambiguate. The estimate total is recomputed automatically. Removing the last remaining item is rejected. Approved or converted-to-job estimates are immutable (409).

Authorizations:
ApiKeyAuth
path Parameters
estimateId
required
string

ID of the estimate to edit

Request Body schema: application/json
required
required
Array of objects (LineItemOperation) non-empty

Ordered list of line-item operations to apply

Responses

Request samples

Content type
application/json
{
  • "operations": [
    ]
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Send an estimate to the customer

Delivers an existing estimate to the customer — a PDF by email and/or a link by text — through the same pipeline the app uses. Sends immediately. Rejected once the estimate is approved or converted to a job.

Authorizations:
ApiKeyAuth
path Parameters
estimateId
required
string
Request Body schema: application/json
optional
via
string
Default: "both"
Enum: "email" "sms" "both"
email
string

Override recipient email (defaults to the customer's)

phone
string

Override recipient mobile (E.164; defaults to the customer's)

message
string

Optional custom message

Responses

Request samples

Content type
application/json
{
  • "via": "email",
  • "email": "string",
  • "phone": "string",
  • "message": "string"
}

Response samples

Content type
application/json
{
  • "success": false,
  • "error": "Error message"
}

Messages

Send an SMS/MMS message

Sends an SMS or MMS message to a customer's mobile phone. Requires an active subscription (any plan). Subject to daily rate limits (500 SMS/day).

Provide either mobilePhone or customerId (or both):

  • mobilePhone: must be the phone.mobile of an existing customer
  • customerId: customer must have a valid phone.mobile on file
  • Both: mobilePhone must match the customer's phone.mobile
Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
mobilePhone
string

Customer's mobile phone in E.164 format. Must belong to an existing customer.

customerId
string

Customer ID. Customer must have a mobile phone on file.

message
string <= 200 characters

Message text. Max 200 characters. Required if no mediaUrl.

mediaUrl
string <uri>

HTTPS URL of media to send as MMS. Required if no message.

Responses

Request samples

Content type
application/json
Example
{
  • "mobilePhone": "+13031234444",
  • "message": "Your appointment is confirmed for tomorrow at 2pm"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

List messages (texts and calls)

Lists messages across all of the business's conversations, newest-first by createdAt. Returns both text messages and calls (calls are stored as message documents). Use this to pull "messages from a given time period" and to see what came in and whether it was answered.

Data availability (forward-only): text messages are returned from the date this endpoint was deployed onward — historical texts are not surfaced by this business-wide query. Calls are available for full history. To read an entire single thread including older messages, use GET /conversations/{phone}/messages.

Authorizations:
ApiKeyAuth
query Parameters
direction
string
Enum: "inbound" "outbound"

Filter by message direction

type
string
Enum: "text" "call"

Filter by message type

startDate
string <date-time>

Only messages at/after this ISO 8601 time

endDate
string <date-time>

Only messages at/before this ISO 8601 time

automated
string
Enum: "true" "false" "exclude"

Filter automated (system) messages. "exclude" is an alias for "false" (human-only) — useful to ignore appointment-reminder noise. Applies to texts; calls have no automated flag.

phone
string

Scope to one customer's thread (E.164)

customerId
string

Scope to one customer's thread by customer ID

limit
integer <= 100
Default: 50

Maximum number of results to return (max 100)

cursor
string

Cursor token for pagination (returned as nextPageToken from the previous response).

Responses

Request samples

curl -X GET "https://us-central1-homebase-360.cloudfunctions.net/api/v1/messages?direction=inbound&limit=25" \
  -H "x-api-key: your-api-key-here"

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "nextPageToken": "string"
}

Get messaging stats and limits

Returns the current messaging usage stats and daily rate limits for the business.

Authorizations:
ApiKeyAuth

Responses

Request samples

curl -X GET "https://us-central1-homebase-360.cloudfunctions.net/api/v1/messages/stats" \
  -H "x-api-key: your-api-key-here" \
  -H "Content-Type: application/json"

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Conversations

List conversations

Lists conversations (one per customer phone number), newest-first by lastMessageTime. Built to answer "which conversations are unanswered?".

Two ways to find unanswered threads:

  • awaitingReply=true — the precise signal: a customer messaged or called in and no human has replied since (automated reminders do not count as a reply). Reflects activity from when this feature was deployed onward.
  • unread=true — the broad signal: the thread is marked unread. Works across all history, including pre-feature conversations.

unansweredForMinutes=N returns awaiting-reply threads whose last inbound was more than N minutes ago — ideal for "alert me to anything unanswered too long".

Authorizations:
ApiKeyAuth
query Parameters
awaitingReply
string
Value: "true"

Only threads awaiting a human reply

unread
string
Value: "true"

Only threads marked unread (legacy-safe; works across all history)

unansweredForMinutes
integer

Only awaiting-reply threads whose last inbound is older than N minutes

phone
string

Fetch a single conversation by customer phone (E.164)

customerId
string

Fetch a single conversation by customer ID

limit
integer <= 100
Default: 50

Maximum number of results to return (max 100)

cursor
string

Cursor token for pagination (returned as nextPageToken from the previous response).

Responses

Request samples

curl -X GET "https://us-central1-homebase-360.cloudfunctions.net/api/v1/conversations?awaitingReply=true&limit=25" \
  -H "x-api-key: your-api-key-here"

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "nextPageToken": "string"
}

Get one conversation's messages

Returns the full message thread (texts and calls) for a single customer phone number, newest-first. Unlike GET /messages, this reads the thread directly and therefore includes older, pre-feature messages too (direction/type are inferred for those legacy messages).

Authorizations:
ApiKeyAuth
path Parameters
phone
required
string

Customer phone number in E.164 (e.g. +13031234444)

query Parameters
direction
string
Enum: "inbound" "outbound"

Filter by message direction

type
string
Enum: "text" "call"

Filter by message type

startDate
string <date-time>

Only messages at/after this ISO 8601 time

endDate
string <date-time>

Only messages at/before this ISO 8601 time

limit
integer <= 100
Default: 50

Maximum number of results to return (max 100)

cursor
string

Cursor token for pagination (returned as nextPageToken from the previous response).

Responses

Request samples

curl -X GET "https://us-central1-homebase-360.cloudfunctions.net/api/v1/conversations/+13031234444/messages?limit=25" \
  -H "x-api-key: your-api-key-here"

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "nextPageToken": "string"
}

Subscriptions

Get service subscriptions

Retrieves recurring service subscriptions (plans sold to your customers). Results are sanitized — internal Firestore plumbing and Stripe connect-account metadata are stripped before being returned.

Legacy subscriptions bill via Stripe and keep the original Stripe-backed shape. Subscriptions with billingVersion: "v3" are billed by the internal engine (card or offline collection) and additionally expose their billing intent (paymentCollection), cadence (billingConfig), visit schedule, term, and billing-schedule working set, plus a compact v3Billing summary block with their price, cadence, and next processing time.

Results are always returned newest-first by createdAt.

Authorizations:
ApiKeyAuth
query Parameters
subscriptionId
string

Fetch a specific subscription by ID

customerId
string

Filter subscriptions by customer ID

status
string
Enum: "draft" "sent" "pending" "active" "paused" "completed" "canceled" "cancelled" "incomplete" "past_due"

Filter by subscription lifecycle status (pending/paused/completed are v3-engine statuses)

limit
integer <= 100
Default: 25

Maximum number of results to return (max 100)

cursor
string

Cursor token for pagination (returned as nextPageToken from the previous response).

Responses

Request samples

curl -X GET "https://us-central1-homebase-360.cloudfunctions.net/api/v1/subscriptions?status=active&limit=25" \
  -H "x-api-key: your-api-key-here" \
  -H "Content-Type: application/json"

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "nextPageToken": "string"
}

Create a subscription draft

Creates a v3 service subscription as a DRAFT built from one of the business's subscription templates, optionally sending the customer the review-and-sign link (email/SMS). The API never activates or charges: the customer reviews, signs, and (for auto_card) enters payment through the normal accept-link flow, exactly as if the draft was created in the dashboard.

Visits are seeded automatically on the template's cadence (evenly spread from the start month); the visit grid can be fine-tuned in the dashboard while the subscription is a draft.

With send, the response status is "sent" when at least one channel (email/SMS) succeeded, otherwise the doc stays "draft" and can be re-sent from the dashboard.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
customerId
required
string

Existing customer ID

templateId
required
string

Subscription template to build from

requestId
string^[A-Za-z0-9_-]{6,64}$

Optional idempotency token, bound to the request payload (first write wins). Retrying with the same requestId and the IDENTICAL body returns the subscription's current state without modifying it — nothing is overwritten and an already-sent subscription is never re-sent (a failed send is retried). The same requestId with a different body is a 409. Recommended for any integration that retries on timeouts.

startDate
string^\d{4}-\d{2}-\d{2}$

Service/billing anchor date, strictly YYYY-MM-DD (default today). Invalid calendar dates (e.g. 2026-02-30) and ISO datetimes are rejected — a timezone offset could shift the anchor a calendar day.

object
dayOfMonth
integer [ 1 .. 28 ]

billing_cycle only — calendar billing day. Defaults to the start date's day (clamped to 28); note the dashboard's creation form defaults to the 1st instead.

Array of objects

Recurring price line items; defaults to the template's line items

object
note
string

Internal note on the subscription

boolean or object

true sends the review link to the customer's own contact info (email and/or mobile). An object sends to EXACTLY the channels provided — { email } never also texts the customer's phone on file, and an object without email or phone is a 400. Strictly validated — any value other than true, false, or an object is rejected with a 400 (a string like "false" will never trigger a send).

Responses

Request samples

Content type
application/json
{
  • "customerId": "string",
  • "templateId": "string",
  • "requestId": "string",
  • "startDate": "2026-08-01",
  • "paymentCollection": {
    },
  • "dayOfMonth": 1,
  • "lineItems": [
    ],
  • "discount": {
    },
  • "note": "string",
  • "send": true
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Get a subscription's invoices

Retrieves the permanent payment ledger of one subscription, newest first. Invoice kind distinguishes scheduled bills ("bill"), standalone technician tips ("tip"), and post-payment job balances ("balance"). Money fields ending in Cents are integer cents.

Authorizations:
ApiKeyAuth
path Parameters
subscriptionId
required
string
query Parameters
limit
integer <= 100
Default: 25
cursor
string

Cursor token for pagination

Responses

Request samples

curl -X GET "https://us-central1-homebase-360.cloudfunctions.net/api/v1/subscriptions/sub_abc123/invoices?limit=25" \
  -H "x-api-key: your-api-key-here" \
  -H "Content-Type: application/json"

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "nextPageToken": "string"
}

Subscription Templates

Get subscription templates

Retrieves the business's subscription templates — the recurring-plan blueprints (cadence, term, pricing line items, optional linked agreement) that subscriptions are built from.

Authorizations:
ApiKeyAuth
query Parameters
templateId
string

Fetch a specific template by ID

limit
integer <= 100
Default: 25
cursor
string

Responses

Request samples

curl -X GET "https://us-central1-homebase-360.cloudfunctions.net/api/v1/subscription-templates" \
  -H "x-api-key: your-api-key-here" \
  -H "Content-Type: application/json"

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "nextPageToken": "string"
}

Create a subscription template

Creates a subscription template. When lineItems are provided the display amount is derived from their subtotal (dashboard behavior); linking an agreement via agreementTemplateId forces requireSignature: true and clears inline terms.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
title
required
string
description
string
type
required
string
Enum: "fixed" "indefinite"
duration
integer

Term length in YEARS (required when type is "fixed")

visits
required
integer [ 1 .. 12 ]

Visits per year

paymentFrequency
required
string
Enum: "weekly" "bi-weekly" "monthly" "quarterly" "tri-annual" "6 months" "yearly"
Array of objects
amount
string

Legacy flat amount — only used when no lineItems

initialPriceEnabled
boolean
initialPrice
string

Required when initialPriceEnabled is true

initialPriceTaxRate
object or null

The initial price's own tax — both name and a numeric 0-100 rate required; malformed values are rejected, never coerced to 0%.

allowOtherPayments
boolean

Offer alternate payment methods at checkout on subscriptions built from this template

requireSignature
boolean

Only takes effect when there is something to sign (inline terms or a linked agreement); normalized to false otherwise

object

Inline terms (ignored when an agreement is linked)

agreementTemplateId
string

Link an existing agreement (must be active and enabled for service subscriptions)

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "type": "fixed",
  • "duration": 0,
  • "visits": 1,
  • "paymentFrequency": "weekly",
  • "lineItems": [
    ],
  • "amount": "string",
  • "initialPriceEnabled": true,
  • "initialPrice": "string",
  • "initialPriceTaxRate": { },
  • "allowOtherPayments": true,
  • "requireSignature": true,
  • "terms": {
    },
  • "agreementTemplateId": "string"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Update a subscription template

Updates a subscription template. Only provided fields change; amount re-derives when lineItems change. Existing subscriptions keep their embedded template snapshot — edits only affect future subscriptions built from the template.

Authorizations:
ApiKeyAuth
path Parameters
templateId
required
string
Request Body schema: application/json
required
object

Any subset of the create-template fields

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Agreements

Get agreements

Retrieves the business's agreements — the structured agreement documents (sections, content bodies, branding) that subscription templates link via agreementTemplateId. Read-only: agreements are created and edited in the dashboard. Subscriptions embed a frozen snapshot at creation, so agreement edits only affect future subscriptions.

Authorizations:
ApiKeyAuth
query Parameters
agreementId
string
limit
integer <= 100
Default: 25
cursor
string

Responses

Request samples

curl -X GET "https://us-central1-homebase-360.cloudfunctions.net/api/v1/agreements" \
  -H "x-api-key: your-api-key-here" \
  -H "Content-Type: application/json"

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "nextPageToken": "string"
}

Webhooks

Subscribe to webhook events

Registers a URL to receive HTTP POST callbacks whenever the specified events occur on the authenticated business. Used by REST-Hook integrations such as Zapier.

Each subscription is scoped to the API key that created it: deactivating the API key auto-deletes its subscriptions. Subscriptions created through this endpoint do NOT appear in the Homebase360 dashboard webhook list (which is reserved for webhooks the user adds manually).

Common event names: customer.created, customer.details_changed, job.created, job.details.line_items_changed, job.status_changed, lead.created, lead.details_changed, lead.status_updated. See the full list in webhooks/webhookEvents.js.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
url
required
string <uri>

Fully-qualified http(s) URL Homebase360 will POST to

events
required
Array of strings

One or more event names from the registry

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{}

List webhook subscriptions for this API key

Returns every webhook endpoint created via this API key, newest first. Endpoints created from the Homebase360 dashboard are NOT included. Signing secrets are never returned in this response.

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ]
}

Unsubscribe a webhook

Removes a subscription previously created with POST /webhooks. Only subscriptions owned by the calling API key can be deleted; attempting to delete an endpoint owned by another key (or one created from the dashboard) returns 404.

Authorizations:
ApiKeyAuth
path Parameters
endpointId
required
string
Example: ep_a1b2c3d4e5f6a1b2c3d4e5f6

Opaque ID returned from the create call

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Invoices

Get invoices

Invoices with computed totals (invoiceTotal, paidAmount, outstanding, status), payment types and line items. By default lists job + custom invoices newest-first by creation date; pass type=subscription to list recurring-plan invoices instead (paginated separately). Subscription invoices are itemized from their parent plan's line items (lineItemsSource: subscription | plan | none) and carry a pricing breakdown in dollars when available.

Authorizations:
ApiKeyAuth
query Parameters
invoiceId
string
customerId
string
type
string
Enum: "job" "custom" "subscription"
status
string
Enum: "paid" "unpaid" "partially_paid" "partially_refunded" "refunded" "void"
paymentType
string
startDate
string <date-time>
endDate
string <date-time>
limit
integer <= 100
Default: 25
cursor
string

Responses

Request samples

curl -X GET "https://us-central1-homebase-360.cloudfunctions.net/api/v1/invoices?type=subscription&startDate=2026-10-01T00:00:00Z" \
  -H "x-api-key: your-api-key-here"

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "nextPageToken": "string"
}

Expenses

Get expenses

Business expense records, newest first by expense date. amount is in dollars.

Authorizations:
ApiKeyAuth
query Parameters
expenseId
string
category
string
startDate
string <date-time>
endDate
string <date-time>
limit
integer <= 100
Default: 50
cursor
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "nextPageToken": "string"
}

Reports

Business summary report

Server-computed summary for a date range matching the app's Reports Overview: jobs (serviced by start date, sold by creation date), invoices, estimates and conversion, all-time subscription MRR/ARR with trend, expenses, profit, per-salesperson and per-field-tech rows. All money in dollars (2 dp). Reads are capped at 5000 docs per collection; capped sections carry truncated: true. fieldTechs.hoursWorked is job-timer time — clock in/out hours live at /time-entries/summary.

Authorizations:
ApiKeyAuth
query Parameters
startDate
required
string <date-time>
endDate
required
string <date-time>

Max range 366 days

includeCancelled
string
Default: "true"
Enum: "true" "false"

"false" drops cancelled jobs from jobs.serviced count/byStatus

includeTax
string
Default: "true"
Enum: "true" "false"

Subscription MRR/ARR with or without tax

includePaidCancellations
string
Default: "true"
Enum: "true" "false"

"false" counts only active subscriptions toward MRR

trendMonths
integer [ 1 .. 24 ]
Default: 12
employeeId
string

Limit fieldTechs to one technician

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Sales leaderboard report

Per-salesperson revenue SOLD (jobs by creation date + subscription contract value over the contract window) and revenue SERVICED (completed jobs by start date + subscription visit value), counts, sell-through % and commission — the app's Leaderboard report. Money in dollars.

Authorizations:
ApiKeyAuth
query Parameters
startDate
required
string <date-time>
endDate
required
string <date-time>
linkedJobsMode
string
Enum: "none" "separate" "all"
includeSubscriptions
string
Default: "true"
Enum: "true" "false"
includeJobs
string
Default: "true"
Enum: "true" "false"
contractWindow
string
Default: "12"

Months of contract value per subscription sold, or "duration"

servicedStatuses
string
Default: "finished,paid,unpaid,partiallyPaid"

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Timesheets

List time entries (timesheets)

Clock in/out entries employees record in the mobile app, newest clock-in first. Each entry has status (open = still clocked in, completed, autoClosed = system-closed after the max shift) and a SEPARATE approved flag — a completed entry can still be unapproved. needsReview marks auto-closed or duplicate entries; edited + original show manager corrections. Soft-deleted entries are skipped unless includeDeleted=true. GPS stamps are omitted unless includeLocation=true.

Authorizations:
ApiKeyAuth
query Parameters
timeEntryId
string
employeeId
string

users doc id from /employees

startDate
string <date-time>

Clock-in on/after

endDate
string <date-time>

Clock-in on/before

status
string
Enum: "open" "completed" "autoClosed"
approved
string
Enum: "true" "false"
needsReview
string
Enum: "true" "false"
includeDeleted
string
Default: "false"
Enum: "true" "false"
includeLocation
string
Default: "false"
Enum: "true" "false"
limit
integer <= 100
Default: 50
cursor
string

Responses

Request samples

curl -X GET "https://us-central1-homebase-360.cloudfunctions.net/api/v1/time-entries?approved=false&startDate=2026-10-06T00:00:00-06:00&endDate=2026-10-12T23:59:59-06:00" \
  -H "x-api-key: your-api-key-here"

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "nextPageToken": "string"
}

Create a manual time entry

Adds a completed shift on an employee's behalf (a missed clock-in, a paper timesheet) — the same as "Add Entry" on the web Timesheets tab. The entry is flagged edited (manager-entered) and is born APPROVED unless approved: false is sent. Max 24 hours; clockOutAt must be after clockInAt.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
employeeId
required
string

users doc id from /employees

clockInAt
required
string <date-time>
clockOutAt
required
string <date-time>
notes
string
approved
boolean
Default: true

Responses

Request samples

Content type
application/json
{
  • "employeeId": "string",
  • "clockInAt": "2019-08-24T14:15:22Z",
  • "clockOutAt": "2019-08-24T14:15:22Z",
  • "notes": "string",
  • "approved": true
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Timesheet summary (payroll roll-up)

Per-employee clock hours for a date range, split by approval state. totalHours counts CLOSED entries only (completed + autoClosed); entries still clocked in are reported separately as openEntries / openHours. Each employee row carries a per-day breakdown. Hours are decimal (2 dp), matching the web Timesheets CSV. These are clock hours — NOT the job-timer hours in /reports/business-summary.

Authorizations:
ApiKeyAuth
query Parameters
startDate
required
string <date-time>
endDate
required
string <date-time>

Max range 366 days

employeeId
string
approved
string
Enum: "true" "false"
status
string
Enum: "open" "completed" "autoClosed"
needsReview
string
Enum: "true" "false"

Responses

Request samples

curl -X GET "https://us-central1-homebase-360.cloudfunctions.net/api/v1/time-entries/summary?startDate=2026-10-06T00:00:00-06:00&endDate=2026-10-12T23:59:59-06:00" \
  -H "x-api-key: your-api-key-here"

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Approve or un-approve time entries (bulk)

Sets approved on many entries at once. Target entries by explicit ids OR by a clock-in date range (optionally one employee). Entries still clocked in are never approved and are listed in skipped. Range mode refuses to touch more than 500 entries in one call.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
timeEntryIds
Array of strings <= 500 items
startDate
string <date-time>

Range mode (with endDate)

endDate
string <date-time>
employeeId
string

Range mode: only this employee

approved
boolean
Default: true

false un-approves

Responses

Request samples

Content type
application/json
{
  • "timeEntryIds": [
    ],
  • "startDate": "2019-08-24T14:15:22Z",
  • "endDate": "2019-08-24T14:15:22Z",
  • "employeeId": "string",
  • "approved": true
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Get one time entry

Authorizations:
ApiKeyAuth
path Parameters
timeEntryId
required
string
query Parameters
includeLocation
string
Default: "false"
Enum: "true" "false"

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Edit a time entry

Corrects clock times and/or notes. Changing a time follows the app's rules: the entry is marked edited, the first edit snapshots original, duration and date are recomputed, and approval is RESET (re-approve via /time-entries/approve). Setting clockOutAt on an open entry clocks the employee out. A notes-only change keeps the approval state.

Authorizations:
ApiKeyAuth
path Parameters
timeEntryId
required
string
Request Body schema: application/json
required
clockInAt
string <date-time>
clockOutAt
string <date-time>

Cannot be cleared

notes
string or null

Responses

Request samples

Content type
application/json
{
  • "clockInAt": "2019-08-24T14:15:22Z",
  • "clockOutAt": "2019-08-24T14:15:22Z",
  • "notes": "string"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Delete a time entry (soft)

Soft-deletes the entry. Entries still clocked in must be closed first (PUT clockOutAt).

Authorizations:
ApiKeyAuth
path Parameters
timeEntryId
required
string

Responses

Response samples

Content type
application/json
{
  • "error": "API key missing"
}