Skip to content

Customers API

Enterprise feature

The REST API is available on Enterprise plans. Compare plans to find the right fit for your team.

The Customers API lets you create, retrieve, and update customer records and their service locations programmatically. Use it to sync your CRM, import customer data, or build custom dashboards.


Endpoints summary

Method Path Scope Description
GET /api/v1/customers customers:read List customers
GET /api/v1/customers?id={id} customers:read Get a single customer
POST /api/v1/customers customers:write Create a customer
PUT /api/v1/customers?id={id} customers:write Update a customer
GET /api/v1/customers?id={id}&locations=1 customers:read List customer locations
POST /api/v1/customers?id={id}&locations=1 customers:write Create a location
PUT /api/v1/customers?id={id}&locations=1&location_id={loc_id} customers:write Update a location

Customer object

Every customer returned by the API contains these fields:

Field Type Description
customer_id integer Unique customer identifier
customer_name string Customer or company name
customer_email string Primary contact email
customer_phone string Primary contact phone (E.164 format)
default_sla_hours integer Default SLA response time in hours
tax_exempt boolean Whether the customer is tax exempt
tax_exemption_reason string / null Reason for tax exemption (max 255 characters)
created_at string When the customer was created (ISO 8601)
updated_at string When the customer was last updated (ISO 8601)

List customers

GET /api/v1/customers

Returns a paginated list of customers.

Query parameters

Parameter Type Description
search string Search by customer name, email, or phone
created_after string Filter customers created after this date (ISO 8601 format, e.g., 2026-01-15T00:00:00Z)
created_before string Filter customers created before this date (ISO 8601 format)
has_locations string Filter by location status: 1 to return only customers with locations, 0 for customers without
page integer Page number (default: 1)
per_page integer Results per page (default: 50, max: 100)

Example request

curl -X GET "https://fsmnavigator.com/api/v1/customers?search=Acme" \
  -H "X-API-Key: YOUR_API_KEY"

Example response

{
  "data": [
    {
      "customer_id": 201,
      "customer_name": "Acme Corporation",
      "customer_email": "[email protected]",
      "customer_phone": "+15551234567",
      "default_sla_hours": 24,
      "tax_exempt": false,
      "tax_exemption_reason": null,
      "created_at": "2026-01-15T10:00:00Z",
      "updated_at": "2026-02-20T08:30:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 50,
    "total": 1,
    "total_pages": 1
  },
  "request_id": "a1b2c3d4e5f6"
}

Get a single customer

GET /api/v1/customers?id={id}

Retrieves full details for one customer. Add &include=locations to embed service locations in the response.

Example request

curl -X GET "https://fsmnavigator.com/api/v1/customers?id=201&include=locations" \
  -H "X-API-Key: YOUR_API_KEY"

Example response

{
  "data": {
    "customer_id": 201,
    "customer_name": "Acme Corporation",
    "customer_email": "[email protected]",
    "customer_phone": "+15551234567",
    "default_sla_hours": 24,
    "tax_exempt": false,
    "tax_exemption_reason": null,
    "created_at": "2026-01-15T10:00:00Z",
    "updated_at": "2026-02-20T08:30:00Z"
  },
  "request_id": "a1b2c3d4e5f6"
}

Create a customer

POST /api/v1/customers

Creates a new customer record. Returns 201 Created on success. Locations are managed separately — see Customer locations below.

Request body

Field Type Required Description
customer_name string Yes Customer or company name
customer_email string Yes Primary contact email
customer_phone string Yes Primary contact phone (E.164 format recommended)
default_sla_hours integer Yes Default SLA response time in hours
tax_exempt boolean No Whether the customer is tax exempt (default: false)
tax_exemption_reason string No Reason for tax exemption (max 255 characters)

Example request

curl -X POST "https://fsmnavigator.com/api/v1/customers" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_name": "Riverside Medical Center",
    "customer_email": "[email protected]",
    "customer_phone": "+15559876543",
    "default_sla_hours": 24,
    "tax_exempt": false,
    "tax_exemption_reason": null
  }'

Example response

{
  "success": true,
  "message": "Customer created successfully",
  "data": {
    "customer_id": 202,
    "customer_name": "Riverside Medical Center"
  },
  "request_id": "a1b2c3d4e5f6"
}

Update a customer

PUT /api/v1/customers?id={id}

Updates one or more fields on an existing customer record.

Example request

curl -X PUT "https://fsmnavigator.com/api/v1/customers?id=201" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_email": "[email protected]"
  }'

Example response

{
  "success": true,
  "message": "Customer updated successfully",
  "data": {
    "customer_id": 201,
    "customer_name": "Acme Corporation"
  },
  "request_id": "a1b2c3d4e5f6"
}

Customer locations

Locations are managed as a sub-resource of a customer. Each customer can have multiple service locations, and each location is automatically geocoded when created or updated.

v1 API change (2026-05-27): Location response now includes contact_email, contact_phone, and notes. Fields default to null when not populated server-side.

Initial-create mirror (2026-05-27): When a customer is created with an inline location object (POST /v1/customers with location in the request body), the first location row now automatically mirrors the customer-level contact_email and contact_phone into the location's per-location contact fields. This ensures default-location billing and service notifications route through the customer's primary contact without a follow-up PATCH. Locations created via the separate POST /v1/customers/{customer_id}/locations endpoint (additional locations) do NOT auto-mirror — pass contact_email / contact_phone explicitly if you want a per-location override.

Location object

Field Type Description
location_id integer Unique location identifier
location_name string Name for this location
address_street string Street address
address_city string City
address_state string Two-letter state code
address_zip string ZIP code (5 digits)
latitude number Latitude (auto-geocoded)
longitude number Longitude (auto-geocoded)
is_primary boolean Whether this is the primary location
created_at string When the location was created (ISO 8601)
updated_at string When the location was last updated (ISO 8601)
contact_email string Email for location-specific contact (optional, nullable)
contact_phone string Phone for location-specific contact (optional, E.164 format recommended)
notes string Internal notes about this location (optional, max ~2KB)

List locations

GET /api/v1/customers?id={id}&locations=1

Returns a paginated list of locations for the specified customer.

Example request

curl -X GET "https://fsmnavigator.com/api/v1/customers?id=201&locations=1" \
  -H "X-API-Key: YOUR_API_KEY"

Example response

{
  "data": [
    {
      "location_id": 87,
      "location_name": "Main Office",
      "address_street": "123 Commerce Blvd",
      "address_city": "Austin",
      "address_state": "TX",
      "address_zip": "78701",
      "latitude": 30.2672,
      "longitude": -97.7431,
      "is_primary": true,
      "created_at": "2026-01-15T10:00:00Z",
      "updated_at": "2026-01-15T10:00:00Z",
      "contact_email": "[email protected]",
      "contact_phone": "+15558901234",
      "notes": "Main office with 2 conference rooms"
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 50,
    "total": 1,
    "total_pages": 1
  },
  "request_id": "a1b2c3d4e5f6"
}

Create a location

POST /api/v1/customers?id={id}&locations=1

Creates a new service location for the specified customer. The address is automatically geocoded. Returns 201 Created on success.

Request body

Field Type Required Description
location_name string Yes Name for this location
address_street string Yes Street address
address_city string Yes City
address_state string Yes Two-letter state code (e.g., TX)
address_zip string Yes ZIP code (5 digits)
contact_email string No Email for location-specific contact
contact_phone string No Phone for location-specific contact (E.164 format recommended)
notes string No Internal notes about this location (max ~2KB)

Example request

curl -X POST "https://fsmnavigator.com/api/v1/customers?id=201&locations=1" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "location_name": "East Wing",
    "address_street": "456 Health Park Dr",
    "address_city": "Dallas",
    "address_state": "TX",
    "address_zip": "75201"
  }'

Example response

{
  "success": true,
  "message": "Location created successfully",
  "data": {
    "location_id": 88,
    "location_name": "East Wing",
    "address_street": "456 Health Park Dr",
    "address_city": "Dallas",
    "address_state": "TX",
    "address_zip": "75201",
    "latitude": 32.7767,
    "longitude": -96.7970,
    "contact_email": "[email protected]",
    "contact_phone": "+15559876500",
    "notes": "Dedicated HVAC maintenance area"
  },
  "request_id": "a1b2c3d4e5f6"
}

Update a location

PUT /api/v1/customers?id={id}&locations=1&location_id={loc_id}

Updates one or more fields on an existing service location. If the address changes, it is automatically re-geocoded.

Example request

curl -X PUT "https://fsmnavigator.com/api/v1/customers?id=201&locations=1&location_id=87" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "location_name": "Main Office - Renovated",
    "address_street": "125 Commerce Blvd"
  }'

Example response

{
  "success": true,
  "message": "Location updated successfully",
  "data": {
    "location_id": 87,
    "location_name": "Main Office - Renovated",
    "address_street": "125 Commerce Blvd",
    "address_city": "Austin",
    "address_state": "TX",
    "address_zip": "78701",
    "latitude": 30.2675,
    "longitude": -97.7428,
    "contact_email": "[email protected]",
    "contact_phone": "+15558901234",
    "notes": "Recently renovated reception area"
  },
  "request_id": "a1b2c3d4e5f6"
}

Error responses

See Error codes for the full reference. Common customer-specific errors:

HTTP code Error Description
400 validation_failed Missing required fields or invalid data
404 not_found Customer or location ID does not exist
400 duplicate_customer A customer with this email already exists