ServiceKeel.Developers
All 9 chapters · Code and API details

CHAPTER 02 OF 8

Find the customer and service address

Resolve the caller to the right customer and property before checking coverage or scheduling work.

1. Match an existing customer, or create one

Ask for the caller’s name and contact information. Search using a confirmed email, then verify the returned match. A search result is not identity verification: resolve ambiguous matches with the caller before reading private job details or changing records. The demo uses a unique synthetic email.

List results are paginated. Follow has_more with the documented limit and offset before concluding a customer does not exist. Persist the resulting ID in your call workflow so a reconnect does not create the customer again.

GET/field_service/customers

List customers

Parameters from the API specification
NameLocationType / schema
searchquerystring
statusquerystring
customer_idquerystring
property_idquerystring
job_idquerystring
limitqueryinteger
offsetqueryinteger
created_afterquerystring
created_beforequerystring

Documented responses: 200 401 403

Open full API reference
POST/field_service/customers

Create customer

Parameters from the API specification
NameLocationType / schema
recordrequiredbodymodels.FieldServiceRecord

Documented responses: 201 400 409

Open full API reference
Resolve the caller
const email = 'alex@example.com'; // Confirmed with the caller.
let customer;
for (let offset = 0; ; offset += 100) {
  const query = new URLSearchParams({ search: email, limit: '100', offset: String(offset) });
  const result = await api('GET', '/customers?' + query);
  customer = result.items.find(item => item.email === email);
  if (customer || !result.has_more) break;
}
if (!customer) {
  customer = await api('POST', '/customers', {
    name: 'Alex Morgan', email, phone: '+12025550142', status: 'active',
  });
}
JavaScript · server side

2. Save only the confirmed changes

A customer record carries a version. Send the current version when patching it and replace your saved copy with the response. A stale update returns a conflict; reload, reconcile the change, and ask again if the caller’s intended outcome has changed.

Use a separate call note for new instructions when you should preserve existing notes. This example updates the synthetic customer’s note field deliberately.

PATCH/field_service/customers/{id}

Update customer (PATCH)

Parameters from the API specification
NameLocationType / schema
idrequiredpathstring
recordrequiredbodymodels.FieldServiceRecord

Documented responses: 200 400 409

Open full API reference
Update the customer with optimistic concurrency
customer = await api('PATCH', '/customers/' + customer.id, {
  version: customer.version,
  notes: 'Caller confirmed the best callback time is after 3 pm.',
});
JavaScript · server side

3. Confirm the service location

List the customer’s locations and confirm which property needs service. Do not assume the first address is the right one. If the address is new, create it under that customer. The returned location’s id becomes property_id in downstream requests.

The caller can now hear an address confirmation before you check whether the business serves the property.

GET/field_service/locations

List tenant service locations

Parameters from the API specification
NameLocationType / schema
customer_idquerystring
property_idquerystring
location_idquerystring
addressquerystring
postal_codequerystring
limitqueryinteger
offsetqueryinteger

Documented responses: 200 400 401 403 500

Open full API reference
POST/field_service/locations

Create a customer service location

Parameters from the API specification
NameLocationType / schema
locationrequiredbodymodels.FieldServiceLocation

Documented responses: 201 400 401 403 404 409 500

Open full API reference
Create a caller-confirmed new location
const locations = await api('GET', '/locations?' + new URLSearchParams({
  customer_id: customer.id,
}));
// Review existing locations with the caller first. If this is a new address:
const location = await api('POST', '/locations', {
  customer_id: customer.id,
  name: 'Home', address: '123 Demo Lane', city: 'Madison',
  region: 'WI', postal_code: '53703', country: 'US',
});
JavaScript · server side