# Customers ## Create or update a customer `client.customers.createOrUpdate(CustomerCreateOrUpdateParamsparams, RequestOptionsoptions?): CustomerCreateOrUpdateResponse` **post** `/customers` Creates a new customer or updates an existing one based on the provided information. **Upsert Logic:** 1. If `id` is provided, updates the customer with that ID 1. If no `id` but phone/email provided, searches for existing customer by phone first, then email 1. If no existing customer found, creates a new customer Tags are merged (not replaced) when updating. ### Parameters - `params: CustomerCreateOrUpdateParams` - `rotorAPIVersion: "1.1.0"` Header param: Required OpenAPI version header. - `"1.1.0"` - `id?: string` Body param: Optional — provide to update an existing customer - `billing_city?: string` Body param - `billing_country?: string` Body param - `billing_same_as_property?: boolean` Body param - `billing_state?: string` Body param - `billing_street1?: string` Body param - `billing_street2?: string` Body param - `billing_zip?: string` Body param - `company_name?: string` Body param - `email?: string` Body param - `first_name?: string` Body param - `last_name?: string` Body param - `notes?: string` Body param - `phone?: string` Body param - `property_city?: string` Body param - `property_country?: string` Body param - `property_state?: string` Body param - `property_street1?: string` Body param - `property_street2?: string` Body param - `property_zip?: string` Body param - `service_frequency?: string` Body param - `service_type?: string` Body param - `source?: string` Body param - `status?: "active" | "inactive"` Body param - `"active"` - `"inactive"` - `tags?: Array` Body param ### Returns - `CustomerCreateOrUpdateResponse` - `id?: string` - `billing_city?: string | null` - `billing_country?: string | null` - `billing_same_as_property?: boolean` - `billing_state?: string | null` - `billing_street1?: string | null` - `billing_street2?: string | null` - `billing_zip?: string | null` - `company_name?: string | null` - `created_at?: string` - `email?: string | null` - `first_name?: string | null` - `last_name?: string | null` - `message?: string` - `notes?: string | null` - `phone?: string | null` - `property_city?: string | null` - `property_country?: string | null` - `property_state?: string | null` - `property_street1?: string | null` - `property_street2?: string | null` - `property_zip?: string | null` - `service_frequency?: string | null` - `service_type?: string | null` - `source?: string | null` - `status?: "active" | "inactive"` - `"active"` - `"inactive"` - `tags?: Array | null` ### Example ```typescript import Rotor from 'getrotor'; const client = new Rotor({ rotorAPIVersion: '1.1.0', apiKey: process.env['ROTOR_API_KEY'], // This is the default and can be omitted }); const response = await client.customers.createOrUpdate({ 'rotor-api-version': '1.1.0' }); console.log(response.id); ``` #### Response ```json { "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "billing_city": "billing_city", "billing_country": "billing_country", "billing_same_as_property": true, "billing_state": "billing_state", "billing_street1": "billing_street1", "billing_street2": "billing_street2", "billing_zip": "billing_zip", "company_name": "company_name", "created_at": "2019-12-27T18:11:19.117Z", "email": "dev@stainless.com", "first_name": "first_name", "last_name": "last_name", "message": "Customer created successfully", "notes": "notes", "phone": "phone", "property_city": "property_city", "property_country": "property_country", "property_state": "property_state", "property_street1": "property_street1", "property_street2": "property_street2", "property_zip": "property_zip", "service_frequency": "service_frequency", "service_type": "service_type", "source": "source", "status": "active", "tags": [ "string" ] } ``` ## List customers `client.customers.list(CustomerListParamsparams, RequestOptionsoptions?): CustomerListResponse` **get** `/customers` Returns a paginated list of customers for the authenticated company. ### Parameters - `params: CustomerListParams` - `rotorAPIVersion: "1.1.0"` Header param: Required OpenAPI version header. - `"1.1.0"` - `archived?: boolean` Query param: Include archived customers (default false) - `limit?: number` Query param: Number of results per page (max 1000) - `page?: number` Query param: Page number (1-based) - `search?: string` Query param: Search by first name, last name, company name, email, or phone - `status?: "active" | "inactive"` Query param: Filter by customer status - `"active"` - `"inactive"` - `tags?: string` Query param: Filter by tags (comma-separated) ### Returns - `CustomerListResponse` - `data?: Array` - `id?: string` - `address?: Address` - `city: string` - `country: string` - `state: string` - `street1: string` - `zip: string` - `street2?: string | null` - `company_name?: string` - `created_at?: string` - `email?: string` - `first_name?: string` - `has_payment_method?: boolean` Whether the customer has at least one saved payment method on file - `last_name?: string` - `location?: Array | null` - `notes?: string | null` - `phone?: string` - `source?: string` - `status?: "active" | "inactive"` - `"active"` - `"inactive"` - `tags?: Array | null` - `pagination?: Pagination` - `has_more?: boolean` Whether more pages are available - `limit?: number` - `page?: number` - `total?: number` Total number of matching records - `status?: string` ### Example ```typescript import Rotor from 'getrotor'; const client = new Rotor({ rotorAPIVersion: '1.1.0', apiKey: process.env['ROTOR_API_KEY'], // This is the default and can be omitted }); const customers = await client.customers.list({ 'rotor-api-version': '1.1.0' }); console.log(customers.data); ``` #### Response ```json { "data": [ { "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "address": { "city": "city", "country": "country", "state": "state", "street1": "street1", "zip": "zip", "street2": "street2" }, "company_name": "company_name", "created_at": "2019-12-27T18:11:19.117Z", "email": "dev@stainless.com", "first_name": "first_name", "has_payment_method": true, "last_name": "last_name", "location": [ 0 ], "notes": "notes", "phone": "phone", "source": "source", "status": "active", "tags": [ "string" ] } ], "pagination": { "has_more": true, "limit": 50, "page": 1, "total": 142 }, "status": "success" } ``` ## Get a customer by ID `client.customers.retrieve(stringid, CustomerRetrieveParamsparams, RequestOptionsoptions?): CustomerRetrieveResponse` **get** `/customers/{id}` Get a customer by ID ### Parameters - `id: string` - `params: CustomerRetrieveParams` - `rotorAPIVersion: "1.1.0"` Required OpenAPI version header. - `"1.1.0"` ### Returns - `CustomerRetrieveResponse` - `data?: Data` - `id?: string` - `address?: Address` - `city: string` - `country: string` - `state: string` - `street1: string` - `zip: string` - `street2?: string | null` - `company_name?: string` - `created_at?: string` - `email?: string` - `first_name?: string` - `has_payment_method?: boolean` Whether the customer has at least one saved payment method on file - `last_name?: string` - `location?: Array | null` - `notes?: string | null` - `phone?: string` - `source?: string` - `status?: "active" | "inactive"` - `"active"` - `"inactive"` - `tags?: Array | null` - `status?: string` ### Example ```typescript import Rotor from 'getrotor'; const client = new Rotor({ rotorAPIVersion: '1.1.0', apiKey: process.env['ROTOR_API_KEY'], // This is the default and can be omitted }); const customer = await client.customers.retrieve('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e', { 'rotor-api-version': '1.1.0', }); console.log(customer.data); ``` #### Response ```json { "data": { "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "address": { "city": "city", "country": "country", "state": "state", "street1": "street1", "zip": "zip", "street2": "street2" }, "company_name": "company_name", "created_at": "2019-12-27T18:11:19.117Z", "email": "dev@stainless.com", "first_name": "first_name", "has_payment_method": true, "last_name": "last_name", "location": [ 0 ], "notes": "notes", "phone": "phone", "source": "source", "status": "active", "tags": [ "string" ] }, "status": "success" } ```