Repository: moov-io/customers
Pull request #269 (2020-10-29 15:02:47)

business customer profiles
Some of this is duplicated work from #266 which was opened primarily to demonstrate API model changes, and will be closed in lieu of this PR

codecov-io: # [Codecov](https://codecov.io/gh/moov-io/customers/pull/269?src=pr&el=h1) Report
> Merging [#269](https://codecov.io/gh/moov-io/customers/pull/269?src=pr&el=desc) into [master](https://codecov.io/gh/moov-io/customers/commit/a910ae4cad36a6dd0c58344d9c4ba1115ca5a245?el=desc) will **decrease** coverage by `2.48%`.
> The diff coverage is `60.94%`.


```diff
@@            Coverage Diff             @@
##           master     #269      +/-   ##
==========================================
- Coverage   61.43%   58.95%   -2.49%     
==========================================
  Files          51       54       +3     
  Lines        2956     3340     +384     
==========================================
+ Hits         1816     1969     +153     
- Misses        820     1016     +196     
- Partials      320      355      +35     
```


Patch:
diff --git a/api/client.yaml b/api/client.yaml
index e456994..c05b3d7 100644
--- a/api/client.yaml
+++ b/api/client.yaml
@@ -404,7 +404,7 @@ paths:
       tags: [Customers]
       summary: Add Customer Address
       description: Add an Address onto an existing Customer record
-      operationId: addCustomerAddress
+      operationId: addAddress
       parameters:
         - name: X-Request-ID
           in: header
@@ -430,7 +430,7 @@ paths:
         content:
           application/json:
             schema:
-              $ref: '#/components/schemas/CreateCustomerAddress'
+              $ref: '#/components/schemas/CreateAddress'
       responses:
         '200':
           description: A customer object
@@ -449,7 +449,7 @@ paths:
       tags: [Customers]
       summary: Update Customer Address
       description: Updates the specified customer address
-      operationId: updateCustomerAddress
+      operationId: updateAddress
       parameters:
         - name: customerID
           in: path
@@ -470,7 +470,7 @@ paths:
         content:
           application/json:
             schema:
-              $ref: '#/components/schemas/UpdateCustomerAddress'
+              $ref: '#/components/schemas/UpdateAddress'
       responses:
         '200':
           description: Updated Customer address
@@ -484,7 +484,7 @@ paths:
       tags: [Customers]
       summary: Delete Customer Address
       description: Deletes a customer's address
-      operationId: deleteCustomerAddress
+      operationId: deleteAddress
       parameters:
         - name: customerID
           in: path
@@ -1530,6 +1530,251 @@ paths:
             application/json:
               schema:
                 $ref: 'https://raw.githubusercontent.com/moov-io/base/master/api/common.yaml#/components/schemas/Error'
+  /customers/{customerID}/representatives:
+    post:
+      tags: [Representatives]
+      summary: Add Customer Representative
+      description: Add a Customer Representative
+      operationId: addRepresentative
+      parameters:
+        - name: X-Request-ID
+          in: header
+          description: Optional requestID allows application developer to trace requests through the systems logs
+          example: rs4f9915
+          required: true
+          schema:
+            type: string
+        - name: X-Organization
+          in: header
+          description: Value used to separate and identify models
+          required: true
+          example: org342
+          schema:
+            type: string
+        - name: customerID
+          in: path
+          description: customerID of the Customer for whom to add the representative
+          required: true
+          schema:
+            type: string
+            example: e210a9d6-d755-4455-9bd2-9577ea7e1081
+      requestBody:
+        required: true
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/CreateRepresentative'
+      responses:
+        '200':
+          description: A customer object
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Customer'
+        '400':
+          description: Customer representative was not added, see error(s)
+          content:
+            application/json:
+              schema:
+                $ref: 'https://raw.githubusercontent.com/moov-io/base/master/api/common.yaml#/components/schemas/Error'
+  /customers/{customerID}/representatives/{representativeID}:
+    put:
+      tags: [Representatives]
+      summary: Update Customer Representative
+      description: Updates the specified Customer Representative
+      operationId: updateRepresentative
+      parameters:
+        - name: customerID
+          in: path
+          description: Customer ID
+          required: true
+          schema:
+            type: string
+            example: e210a9d6-d755-4455-9bd2-9577ea7e1081
+        - name: representativeID
+          in: path
+          description: Representative ID
+          required: true
+          schema:
+            type: string
+            example: 1d62e297-9727-4084-a902-1031da932c9e
+      requestBody:
+        required: true
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/CreateRepresentative'
+      responses:
+        '200':
+          description: Updated Customer Representative
+        '400':
+          description: See error message
+          content:
+            application/json:
+              schema:
+                $ref: 'https://raw.githubusercontent.com/moov-io/base/master/api/common.yaml#/components/schemas/Error'
+    delete:
+      tags: [Representatives]
+      summary: Delete Customer Representative
+      description: Deletes a Customer Representative
+      operationId: deleteRepresentative
+      parameters:
+        - name: customerID
+          in: path
+          description: Customer ID
+          required: true
+          schema:
+            type: string
+            example: e210a9d6-d755-4455-9bd2-9577ea7e1081
+        - name: representativeID
+          in: path
+          description: Representative ID
+          required: true
+          schema:
+            type: string
+            example: 1d62e297-9727-4084-a902-1031da932c9e
+      responses:
+        '204':
+          description: Successfully deleted the customer representative
+        '400':
+          description: See error message
+          content:
+            application/json:
+              schema:
+                $ref: 'https://raw.githubusercontent.com/moov-io/base/master/api/common.yaml#/components/schemas/Error'
+  /customers/{customerID}/representatives/{representativeID}/address:
+    post:
+      tags: [Representatives]
+      summary: Add Customer Representative Address
+      description: Add an address to an existing customer representative record
+      operationId: addRepresentativeAddress
+      parameters:
+        - name: X-Request-ID
+          in: header
+          description: Optional requestID allows application developer to trace requests through the systems logs
+          example: rs4f9915
+          schema:
+            type: string
+        - name: X-Organization
+          in: header
+          description: Value used to separate and identify models
+          required: true
+          example: org342
+          schema:
+            type: string
+        - name: customerID
+          in: path
+          description: customerID of the Customer to add the address onto
+          required: true
+          schema:
+            type: string
+            example: e210a9d6-d755-4455-9bd2-9577ea7e1081
+        - name: representativeID
+          in: path
+          description: representativeID of the Customer representative for whom to add the address
+          required: true
+          schema:
+            type: string
+            example: b210a9d6-d755-4455-9bd2-9577ea7e7643
+      requestBody:
+        required: true
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/CreateAddress'
+      responses:
+        '200':
+          description: A customer representative object
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Representative'
+        '400':
+          description: Customer representative address was not added, see error(s)
+          content:
+            application/json:
+              schema:
+                $ref: 'https://raw.githubusercontent.com/moov-io/base/master/api/common.yaml#/components/schemas/Error'
+  /customers/{customerID}/representatives/{representativeID}/addresses/{addressID}:
+    put:
+      tags: [Representatives]
+      summary: Update Customer Representative Address
+      description: Updates the specified customer representative address
+      operationId: updateRepresentativeAddress
+      parameters:
+        - name: customerID
+          in: path
+          description: Customer ID
+          required: true
+          schema:
+            type: string
+            example: e210a9d6-d755-4455-9bd2-9577ea7e1081
+        - name: representativeID
+          in: path
+          description: Customer Representative ID
+          required: true
+          schema:
+            type: string
+            example: b946a9d6-d755-4455-9bd2-9577ea7f0623
+        - name: addressID
+          in: path
+          description: Address ID
+          required: true
+          schema:
+            type: string
+            example: 1d62e297-9727-4084-a902-1031da932c9e
+      requestBody:
+        required: true
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/UpdateAddress'
+      responses:
+        '200':
+          description: Updated Customer representative address
+        '400':
+          description: See error message
+          content:
+            application/json:
+              schema:
+                $ref: 'https://raw.githubusercontent.com/moov-io/base/master/api/common.yaml#/components/schemas/Error'
+    delete:
+      tags: [Representatives]
+      summary: Delete a Customer Representative Address
+      description: Deletes a customer representative's address
+      operationId: deleteRepresentativeAddress
+      parameters:
+        - name: customerID
+          in: path
+          description: Customer ID
+          required: true
+          schema:
+            type: string
+            example: e210a9d6-d755-4455-9bd2-9577ea7e1081
+        - name: representativeID
+          in: path
+          description: Customer Representative ID
+          required: true
+          schema:
+            type: string
+            example: b946a9d6-d755-4455-9bd2-9577ea7f0623
+        - name: addressID
+          in: path
+          description: Address ID
+          required: true
+          schema:
+            type: string
+            example: 1d62e297-9727-4084-a902-1031da932c9e
+      responses:
+        '204':
+          description: Successfully deleted the customer representative's address
+        '400':
+          description: See error message
+          content:
+            application/json:
+              schema:
+                $ref: 'https://raw.githubusercontent.com/moov-io/base/master/api/common.yaml#/components/schemas/Error'
+
   /reports/accounts:
     get:
       tags: [Reports]
@@ -1610,6 +1855,28 @@ components:
           description: Customers name suffix. "Jr", "PH.D."
         type:
           $ref: '#/components/schemas/CustomerType'
+        businessName:
+          type: string
+          description: Business Name for business type customers
+          example: Alphabet Inc.
+        doingBusinessAs:
+          type: string
+          description: Doing Business As (DBA) name for business type customers
+          example: Google
+        businessType:
+          $ref: '#/components/schemas/BusinessType'
+        EIN:
+          type: string
+          description: Employer Identification Number (EIN) for business type customers
+          example: 77-0493581
+        DUNS:
+          type: string
+          description: Dun & Bradstreet D-U-N-S Number (D-U-N-S) for business type customers
+          example: 15-048-3782
+        SICCode:
+          $ref: '#/components/schemas/SICCode'
+        NAICSCode:
+          $ref: '#/components/schemas/NAICSCode'
         birthDate:
           type: string
           description: Legal date of birth
@@ -1622,6 +1889,14 @@ components:
           type: string
           description: Customer Social Security Number (SSN)
           example: 111-11-1111
+        website:
+          type: string
+          description: Company Website for business type customers
+          example: http://google.com
+        dateBusinessEstablished:
+          type: string
+          description: Date business was established for business type customers
+          example: '2016-08-29'
         phones:
           type: array
           items:
@@ -1630,7 +1905,11 @@ components:
           type: array
           minimum: 1
           items:
-            $ref: '#/components/schemas/CreateCustomerAddress'
+            $ref: '#/components/schemas/CreateAddress'
+        representatives:
+          type: array
+          items:
+            $ref: '#/components/schemas/CreateRepresentative'
         metadata:
           type: object
           description: Map of unique keys associated to values to act as foreign key relationships or arbitrary data associated to a Customer.
@@ -1673,6 +1952,28 @@ components:
           description: Customers name suffix. "Jr", "PH.D."
         type:
           $ref: '#/components/schemas/CustomerType'
+        businessName:
+          type: string
+          description: Business Name for business type customers
+          example: Alphabet Inc.
+        doingBusinessAs:
+          type: string
+          description: Doing Business As (DBA) name for business type customers
+          example: Google
+        businessType:
+          $ref: '#/components/schemas/BusinessType'
+        EIN:
+          type: string
+          description: Employer Identification Number (EIN) for business type customers
+          example: 77-0493581
+        DUNS:
+          type: string
+          description: Dun & Bradstreet D-U-N-S Number (D-U-N-S) for business type customers
+          example: 15-048-3782
+        SICCode:
+          $ref: '#/components/schemas/SICCode'
+        NAICSCode:
+          $ref: '#/components/schemas/NAICSCode'
         birthDate:
           type: string
           description: Legal date of birth
@@ -1683,6 +1984,14 @@ components:
           type: string
           maximum: 500
           description: Primary email address of customer name@domain.com
+        website:
+          type: string
+          description: Company Website for business type customers
+          example: http://google.com
+        dateBusinessEstablished:
+          type: string
+          description: Date business was established for business type customers
+          example: '2016-08-29'
         phones:
           type: array
           items:
@@ -1690,7 +1999,11 @@ components:
         addresses:
           type: array
           items:
-            $ref: '#/components/schemas/CustomerAddress'
+            $ref: '#/components/schemas/Address'
+        representatives:
+          type: array
+          items:
+            $ref: '#/components/schemas/Representative'
         metadata:
           type: object
           description: Map of unique keys associated to values to act as foreign key relationships or arbitrary data associated to a Customer.
@@ -1726,6 +2039,21 @@ components:
       enum:
         - individual
         - business
+    BusinessType:
+      type: string
+      description: The type of business for business customers
+      enum:
+        - individual, sole proprietor, or single-member LLC
+        - corporation
+        - non-profit organization
+        - partnership
+        - limited liability company
+    OwnerType:
+      type: string
+      description: The type of individual owner of a resource, such as SSN, phone, or address
+      enum:
+        - customer
+        - representative
     CustomerStatus:
       type: string
       description: State of the customer
@@ -1736,6 +2064,234 @@ components:
         - ReceiveOnly
         - Verified
         - Frozen
+    SICCode:
+      type: string
+      description: SIC Code (https://docs.google.com/spreadsheets/d/1erIdqoy60JwLAnpb91EfoJV5YrXDnbwSaA-aqcBlw48/edit#gid=1627409140)
+      enum:
+        - 01
+        - 02
+        - 07
+        - 08
+        - 09
+        - 10
+        - 12
+        - 13
+        - 14
+        - 15
+        - 16
+        - 17
+        - 20
+        - 21
+        - 22
+        - 23
+        - 24
+        - 25
+        - 26
+        - 27
+        - 28
+        - 29
+        - 30
+        - 31
+        - 32
+        - 33
+        - 34
+        - 35
+        - 36
+        - 37
+        - 38
+        - 39
+        - 40
+        - 41
+        - 42
+        - 43
+        - 44
+        - 45
+        - 46
+        - 47
+        - 48
+        - 49
+        - 50
+        - 51
+        - 52
+        - 53
+        - 54
+        - 55
+        - 56
+        - 57
+        - 58
+        - 59
+        - 60
+        - 61
+        - 62
+        - 63
+        - 64
+        - 65
+        - 67
+        - 70
+        - 72
+        - 73
+        - 75
+        - 76
+        - 78
+        - 79
+        - 80
+        - 81
+        - 82
+        - 83
+        - 84
+        - 86
+        - 87
+        - 88
+        - 89
+        - 91
+        - 92
+        - 93
+        - 94
+        - 95
+        - 96
+        - 97
+        - 98
+        - 99
+      x-enum-values:
+        - Agricultural Production – Crops
+        - Agricultural Production – Livestock
+        - Agricultural Services
+        - Forestry
+        - Fishing, Hunting, & Trapping
+        - Metal, Mining
+        - Coal Mining
+        - Oil & Gas Extraction
+        - Nonmetallic Minerals, Except Fuels
+        - General Building Contractors
+        - Heavy Construction, Except Building
+        - Special Trade Contractors
+        - Food & Kindred Products
+        - Tobacco Products
+        - Textile Mill Products
+        - Apparel & Other Textile Products
+        - Lumber & Wood Products
+        - Furniture & Fixtures
+        - Paper & Allied Products
+        - Printing & Publishing
+        - Chemical & Allied Products
+        - Petroleum & Coal Products
+        - Rubber & Miscellaneous Plastics Products
+        - Leather & Leather Products
+        - Stone, Clay, & Glass Products
+        - Primary Metal Industries
+        - Fabricated Metal Products
+        - Industrial Machinery & Equipment
+        - Electronic & Other Electric Equipment
+        - Transportation Equipment
+        - Instruments & Related Products
+        - Miscellaneous Manufacturing Industries
+        - Railroad Transportation
+        - Local & Interurban Passenger Transit
+        - Trucking & Warehousing
+        - U.S. Postal Service
+        - Water Transportation
+        - Transportation by Air
+        - Pipelines, Except Natural Gas
+        - Transportation Services
+        - Communications
+        - Electric, Gas, & Sanitary Services
+        - Wholesale Trade – Durable Goods
+        - Wholesale Trade – Nondurable Goods
+        - Building Materials & Gardening Supplies
+        - General Merchandise Stores
+        - Food Stores
+        - Automative Dealers & Service Stations
+        - Apparel & Accessory Stores
+        - Furniture & Homefurnishings Stores
+        - Eating & Drinking Places
+        - Miscellaneous Retail
+        - Depository Institutions
+        - Nondepository Institutions
+        - Security & Commodity Brokers
+        - Insurance Carriers
+        - Insurance Agents, Brokers, & Service
+        - Real Estate
+        - Holding & Other Investment Offices
+        - Hotels & Other Lodging Places
+        - Personal Services
+        - Business Services
+        - Auto Repair, Services, & Parking
+        - Miscellaneous Repair Services
+        - Motion Pictures
+        - Amusement & Recreation Services
+        - Health Services
+        - Legal Services
+        - Educational Services
+        - Social Services
+        - Museums, Botanical, Zoological Gardens
+        - Membership Organizations
+        - Engineering & Management Services
+        - Private Households
+        - Services, Not Elsewhere Classified
+        - Executive, Legislative, & General
+        - Justice, Public Order, & Safety
+        - Finance, Taxation, & Monetary Policy
+        - Administration of Human Resources
+        - Environmental Quality & Housing
+        - Administration of Economic Programs
+        - National Security & International Affairs
+        - Zoological Gardens
+        - Non-Classifiable Establishments
+    NAICSCode:
+      type: string
+      description: NAICS Code (https://docs.google.com/spreadsheets/d/1erIdqoy60JwLAnpb91EfoJV5YrXDnbwSaA-aqcBlw48/edit#gid=1627409140)
+      enum:
+        - 11
+        - 21
+        - 22
+        - 23
+        - 31
+        - 32
+        - 33
+        - 42
+        - 44
+        - 45
+        - 48
+        - 49
+        - 51
+        - 52
+        - 53
+        - 54
+        - 55
+        - 56
+        - 61
+        - 62
+        - 71
+        - 72
+        - 81
+        - 92
+        - 99
+      x-enum-values:
+        - Agriculture, forestry, fishing and hunting
+        - Mining
+        - Utilities
+        - Construction
+        - Manufacturing
+        - Manufacturing
+        - Manufacturing
+        - Wholesale trade
+        - Retail trade
+        - Retail trade
+        - Transportation and warehousing
+        - Transportation and warehousing
+        - Information
+        - Finance and insurance
+        - Real estate and rental and leasing
+        - Professional, scientific, and technical services
+        - Management of companies and enterprises
+        - Administrative and support and waste management and remediation services
+        - Education services
+        - Health care and social assistance
+        - Arts, entertainment, and recreation
+        - Accommodation and food services
+        - Other services, except public administration
+        - Public administration
+        - Unclassified
     CustomerMetadata:
       properties:
         metadata:
@@ -1757,7 +2313,7 @@ components:
           $ref: '#/components/schemas/CustomerStatus'
       required:
         - status
-    UpdateCustomerAddress:
+    UpdateAddress:
       properties:
         type:
           type: string
@@ -1812,6 +2368,8 @@ components:
           type: string
           description: phone number
           example: "+1.818.555.1212"
+        ownerType:
+          $ref: '#/components/schemas/OwnerType'
         valid:
           type: boolean
           description: phone number has been validated to connect with customer
@@ -1828,7 +2386,7 @@ components:
         - home
         - mobile
         - work
-    CreateCustomerAddress:
+    CreateAddress:
       type: object
       properties:
         type:
@@ -1864,7 +2422,7 @@ components:
         - state
         - postalCode
         - country
-    CustomerAddress:
+    Address:
       type: object
       properties:
         addressID:
@@ -1873,6 +2431,8 @@ components:
           example: 851233a1
         type:
           $ref: '#/components/schemas/AddressType'
+        ownerType:
+          $ref: '#/components/schemas/OwnerType'
         address1:
           type: string
           description: First line of the address
@@ -1909,6 +2469,94 @@ components:
       enum:
         - primary
         - secondary
+    CreateRepresentative:
+      properties:
+        firstName:
+          type: string
+          description: Given Name or First Name
+          example: Mary
+        lastName:
+          type: string
+          description: Surname or Last Name
+          example: Smith
+        jobTitle:
+          type: string
+          description: Job title of this representative
+          example: Chief Executive Officer
+        birthDate:
+          type: string
+          description: Legal date of birth
+          example: '2016-08-29'
+        SSN:
+          type: string
+          description: Customer Representative's Social Security Number (SSN)
+          example: 111-11-1111
+        phones:
+          type: array
+          items:
+            $ref: '#/components/schemas/CreatePhone'
+        addresses:
+          type: array
+          items:
+            $ref: '#/components/schemas/CreateAddress'
+      required:
+        - firstName
+        - lastName
+    Representative:
+      properties:
+        representativeID:
+          type: string
+          description: Unique identifier for this Representative
+          example: b280b9d9
+        customerID:
+          type: string
+          description: The unique identifier for the customer the representative belongs to
+          example: e210a9d6
+        firstName:
+          type: string
+          description: Given Name or First Name
+          example: Mary
+        lastName:
+          type: string
+          description: Surname or Last Name
+          example: Smith
+        jobTitle:
+          type: string
+          description: Job title of this representative
+          example: Chief Executive Officer
+        birthDate:
+          type: string
+          description: Legal date of birth
+          example: '2016-08-29'
+        createdAt:
+          type: string
+          format: date-time
+          example: '2016-08-29T09:12:33.001Z'
+        lastModified:
+          type: string
+          format: date-time
+          description: Last time the object was modified
+          example: '2016-08-29T09:12:33.001Z'
+        SSN:
+          type: string
+          description: Customer Representative's Social Security Number (SSN)
+          example: 111-11-1111
+        phones:
+          type: array
+          items:
+            $ref: '#/components/schemas/Phone'
+        addresses:
+          type: array
+          minimum: 1
+          items:
+            $ref: '#/components/schemas/Address'
+      required:
+        - representativeID
+        - customerID
+        - firstName
+        - lastName
+        - createdAt
+        - lastModified
     AccountStatus:
       type: string
       description: Enumeration if this account has been validated through micro-deposits or another available strategy.
diff --git a/cmd/server/main.go b/cmd/server/main.go
index a6e3589..ae25c13 100644
--- a/cmd/server/main.go
+++ b/cmd/server/main.go
@@ -184,6 +184,7 @@ func main() {
 	accounts.RegisterRoutes(logger, router, accountsRepo, validationsRepo, fedClient, stringKeeper, transitStringKeeper, validationStrategies, &accountOfacSeacher, appSalt)
 	customers.AddCustomerRoutes(logger, router, customerRepo, customerSSNStorage, ofac)
 	customers.AddCustomerAddressRoutes(logger, router, customerRepo)
+	customers.AddRepresentativeRoutes(logger, router, customerRepo, customerSSNStorage)
 	documents.AddDisclaimerRoutes(logger, router, disclaimerRepo)
 
 	docsStorageProvider := util.Or(os.Getenv("DOCUMENTS_STORAGE_PROVIDER"), "file")
diff --git a/migrations/016_add_business_name_to_customers.up.sql b/migrations/016_add_business_name_to_customers.up.sql
new file mode 100644
index 0000000..5daac9c
--- /dev/null
+++ b/migrations/016_add_business_name_to_customers.up.sql
@@ -0,0 +1,1 @@
+ALTER TABLE customers ADD COLUMN business_name varchar(255) default null;
diff --git a/migrations/017_add_doing_business_as_to_customers.up.sql b/migrations/017_add_doing_business_as_to_customers.up.sql
new file mode 100644
index 0000000..ee993de
--- /dev/null
+++ b/migrations/017_add_doing_business_as_to_customers.up.sql
@@ -0,0 +1,1 @@
+ALTER TABLE customers ADD COLUMN doing_business_as varchar(255) default null;
diff --git a/migrations/018_add_business_type_to_customers.up.sql b/migrations/018_add_business_type_to_customers.up.sql
new file mode 100644
index 0000000..ebbd62f
--- /dev/null
+++ b/migrations/018_add_business_type_to_customers.up.sql
@@ -0,0 +1,1 @@
+ALTER TABLE customers ADD COLUMN business_type varchar(50) default null;
diff --git a/migrations/019_add_ein_to_customers.up.sql b/migrations/019_add_ein_to_customers.up.sql
new file mode 100644
index 0000000..b7c70f7
--- /dev/null
+++ b/migrations/019_add_ein_to_customers.up.sql
@@ -0,0 +1,1 @@
+ALTER TABLE customers ADD COLUMN ein varchar(40) default null;
diff --git a/migrations/020_add_duns_to_customers.up.sql b/migrations/020_add_duns_to_customers.up.sql
new file mode 100644
index 0000000..64a2510
--- /dev/null
+++ b/migrations/020_add_duns_to_customers.up.sql
@@ -0,0 +1,1 @@
+ALTER TABLE customers ADD COLUMN duns varchar(40) default null;
diff --git a/migrations/021_add_sic_code_to_customers.up.sql b/migrations/021_add_sic_code_to_customers.up.sql
new file mode 100644
index 0000000..6247021
--- /dev/null
+++ b/migrations/021_add_sic_code_to_customers.up.sql
@@ -0,0 +1,1 @@
+ALTER TABLE customers ADD COLUMN sic_code varchar(5) default null;
diff --git a/migrations/022_add_naics_code_to_customers.up.sql b/migrations/022_add_naics_code_to_customers.up.sql
new file mode 100644
index 0000000..aa9a1e6
--- /dev/null
+++ b/migrations/022_add_naics_code_to_customers.up.sql
@@ -0,0 +1,1 @@
+ALTER TABLE customers ADD COLUMN naics_code varchar(5) default null;
diff --git a/migrations/023_add_website_to_customers.up.sql b/migrations/023_add_website_to_customers.up.sql
new file mode 100644
index 0000000..ad6bef2
--- /dev/null
+++ b/migrations/023_add_website_to_customers.up.sql
@@ -0,0 +1,1 @@
+ALTER TABLE customers ADD COLUMN website varchar(255) default null;
diff --git a/migrations/024_add_date_business_established_to_customers.up.sql b/migrations/024_add_date_business_established_to_customers.up.sql
new file mode 100644
index 0000000..610594c
--- /dev/null
+++ b/migrations/024_add_date_business_established_to_customers.up.sql
@@ -0,0 +1,1 @@
+ALTER TABLE customers ADD COLUMN date_business_established varchar(40) default null;
diff --git a/migrations/025_create_representatives.up.sql b/migrations/025_create_representatives.up.sql
new file mode 100644
index 0000000..a5b9d68
--- /dev/null
+++ b/migrations/025_create_representatives.up.sql
@@ -0,0 +1,11 @@
+CREATE TABLE if not exists representatives (
+    representative_id varchar(40) primary key,
+    customer_id varchar(40),
+    first_name varchar(40),
+    last_name varchar(40),
+    job_title varchar(50),
+    birth_date datetime,
+    created_at datetime,
+    last_modified datetime,
+    deleted_at datetime
+);
diff --git a/migrations/026_alter_customer_ssn_customer_id_to_owner_id.up.sql b/migrations/026_alter_customer_ssn_customer_id_to_owner_id.up.sql
new file mode 100644
index 0000000..5e836cd
--- /dev/null
+++ b/migrations/026_alter_customer_ssn_customer_id_to_owner_id.up.sql
@@ -0,0 +1,1 @@
+ALTER TABLE customer_ssn RENAME COLUMN customer_id TO owner_id;
diff --git a/migrations/027_add_owner_type_to_customer_ssn.up.sql b/migrations/027_add_owner_type_to_customer_ssn.up.sql
new file mode 100644
index 0000000..780c364
--- /dev/null
+++ b/migrations/027_add_owner_type_to_customer_ssn.up.sql
@@ -0,0 +1,1 @@
+ALTER TABLE customer_ssn ADD COLUMN owner_type varchar(25) NOT NULL default 'customer';
diff --git a/migrations/028_alter_rename_customer_ssn_to_ssn.up.sql b/migrations/028_alter_rename_customer_ssn_to_ssn.up.sql
new file mode 100644
index 0000000..bf83cde
--- /dev/null
+++ b/migrations/028_alter_rename_customer_ssn_to_ssn.up.sql
@@ -0,0 +1,1 @@
+ALTER TABLE customer_ssn RENAME TO ssn;
diff --git a/migrations/029_alter_customers_addresses_customer_id_to_owner_id.up.sql b/migrations/029_alter_customers_addresses_customer_id_to_owner_id.up.sql
new file mode 100644
index 0000000..d624f03
--- /dev/null
+++ b/migrations/029_alter_customers_addresses_customer_id_to_owner_id.up.sql
@@ -0,0 +1,1 @@
+ALTER TABLE customers_addresses RENAME COLUMN customer_id TO owner_id;
diff --git a/migrations/030_add_owner_type_to_customers_addresses.up.sql b/migrations/030_add_owner_type_to_customers_addresses.up.sql
new file mode 100644
index 0000000..4750785
--- /dev/null
+++ b/migrations/030_add_owner_type_to_customers_addresses.up.sql
@@ -0,0 +1,1 @@
+ALTER TABLE customers_addresses ADD COLUMN owner_type varchar(25) NOT NULL default 'customer';
diff --git a/migrations/031_alter_rename_customers_addresses_to_addresses.up.sql b/migrations/031_alter_rename_customers_addresses_to_addresses.up.sql
new file mode 100644
index 0000000..c4b12b4
--- /dev/null
+++ b/migrations/031_alter_rename_customers_addresses_to_addresses.up.sql
@@ -0,0 +1,1 @@
+ALTER TABLE customers_addresses RENAME TO addresses;
diff --git a/migrations/032_alter_customers_phones_customer_id_to_owner_id.up.sql b/migrations/032_alter_customers_phones_customer_id_to_owner_id.up.sql
new file mode 100644
index 0000000..6e206da
--- /dev/null
+++ b/migrations/032_alter_customers_phones_customer_id_to_owner_id.up.sql
@@ -0,0 +1,1 @@
+ALTER TABLE customers_phones RENAME COLUMN customer_id TO owner_id;
diff --git a/migrations/033_add_owner_type_to_customers_phones.up.sql b/migrations/033_add_owner_type_to_customers_phones.up.sql
new file mode 100644
index 0000000..eb2350e
--- /dev/null
+++ b/migrations/033_add_owner_type_to_customers_phones.up.sql
@@ -0,0 +1,1 @@
+ALTER TABLE customers_phones ADD COLUMN owner_type varchar(25) NOT NULL default 'customer';
diff --git a/migrations/034_alter_rename_customers_phones_to_phones.up.sql b/migrations/034_alter_rename_customers_phones_to_phones.up.sql
new file mode 100644
index 0000000..189ad2e
--- /dev/null
+++ b/migrations/034_alter_rename_customers_phones_to_phones.up.sql
@@ -0,0 +1,1 @@
+ALTER TABLE customers_phones RENAME TO phones;
diff --git a/pkg/client/README.md b/pkg/client/README.md
index 139d66b..9714dc5 100644
--- a/pkg/client/README.md
+++ b/pkg/client/README.md
@@ -53,18 +53,18 @@ Class | Method | HTTP request | Description
 *ConfigurationApi* | [**GetOrganizationLogo**](docs/ConfigurationApi.md#getorganizationlogo) | **Get** /configuration/logo | Get Organization Logo
 *ConfigurationApi* | [**UpdateOrganizationConfiguration**](docs/ConfigurationApi.md#updateorganizationconfiguration) | **Put** /configuration/customers | Update Organization Configuration
 *ConfigurationApi* | [**UploadOrganizationLogo**](docs/ConfigurationApi.md#uploadorganizationlogo) | **Put** /configuration/logo | Update Organization Logo
-*CustomersApi* | [**AddCustomerAddress**](docs/CustomersApi.md#addcustomeraddress) | **Post** /customers/{customerID}/address | Add Customer Address
+*CustomersApi* | [**AddAddress**](docs/CustomersApi.md#addaddress) | **Post** /customers/{customerID}/address | Add Customer Address
 *CustomersApi* | [**CreateCustomer**](docs/CustomersApi.md#createcustomer) | **Post** /customers | Create Customer
+*CustomersApi* | [**DeleteAddress**](docs/CustomersApi.md#deleteaddress) | **Delete** /customers/{customerID}/addresses/{addressID} | Delete Customer Address
 *CustomersApi* | [**DeleteCustomer**](docs/CustomersApi.md#deletecustomer) | **Delete** /customers/{customerID} | Delete Customer
-*CustomersApi* | [**DeleteCustomerAddress**](docs/CustomersApi.md#deletecustomeraddress) | **Delete** /customers/{customerID}/addresses/{addressID} | Delete Customer Address
 *CustomersApi* | [**GetCustomer**](docs/CustomersApi.md#getcustomer) | **Get** /customers/{customerID} | Get Customer
 *CustomersApi* | [**GetLatestOFACSearch**](docs/CustomersApi.md#getlatestofacsearch) | **Get** /customers/{customerID}/ofac | Latest Customer OFAC search
 *CustomersApi* | [**Ping**](docs/CustomersApi.md#ping) | **Get** /ping | Ping Customers Service
 *CustomersApi* | [**RefreshOFACSearch**](docs/CustomersApi.md#refreshofacsearch) | **Put** /customers/{customerID}/refresh/ofac | Refresh Customer OFAC search
 *CustomersApi* | [**ReplaceCustomerMetadata**](docs/CustomersApi.md#replacecustomermetadata) | **Put** /customers/{customerID}/metadata | Update Customer Metadata
 *CustomersApi* | [**SearchCustomers**](docs/CustomersApi.md#searchcustomers) | **Get** /customers | Search Customers
+*CustomersApi* | [**UpdateAddress**](docs/CustomersApi.md#updateaddress) | **Put** /customers/{customerID}/addresses/{addressID} | Update Customer Address
 *CustomersApi* | [**UpdateCustomer**](docs/CustomersApi.md#updatecustomer) | **Put** /customers/{customerID} | Update Customer
-*CustomersApi* | [**UpdateCustomerAddress**](docs/CustomersApi.md#updatecustomeraddress) | **Put** /customers/{customerID}/addresses/{addressID} | Update Customer Address
 *CustomersApi* | [**UpdateCustomerStatus**](docs/CustomersApi.md#updatecustomerstatus) | **Put** /customers/{customerID}/status | Update Customer Status
 *DisclaimersApi* | [**AcceptDisclaimer**](docs/DisclaimersApi.md#acceptdisclaimer) | **Post** /customers/{customerID}/disclaimers/{disclaimerID} | Accept Customer Disclaimer
 *DisclaimersApi* | [**GetCustomerDisclaimers**](docs/DisclaimersApi.md#getcustomerdisclaimers) | **Get** /customers/{customerID}/disclaimers | Get Customer Disclaimers
@@ -73,6 +73,12 @@ Class | Method | HTTP request | Description
 *DocumentsApi* | [**GetCustomerDocuments**](docs/DocumentsApi.md#getcustomerdocuments) | **Get** /customers/{customerID}/documents | Get Customer Documents
 *DocumentsApi* | [**UploadCustomerDocument**](docs/DocumentsApi.md#uploadcustomerdocument) | **Post** /customers/{customerID}/documents | Upload Customer Document
 *ReportsApi* | [**GetReportOfCustomerAccounts**](docs/ReportsApi.md#getreportofcustomeraccounts) | **Get** /reports/accounts | Create Report of Accounts
+*RepresentativesApi* | [**AddRepresentative**](docs/RepresentativesApi.md#addrepresentative) | **Post** /customers/{customerID}/representatives | Add Customer Representative
+*RepresentativesApi* | [**AddRepresentativeAddress**](docs/RepresentativesApi.md#addrepresentativeaddress) | **Post** /customers/{customerID}/representatives/{representativeID}/address | Add Customer Representative Address
+*RepresentativesApi* | [**DeleteRepresentative**](docs/RepresentativesApi.md#deleterepresentative) | **Delete** /customers/{customerID}/representatives/{representativeID} | Delete Customer Representative
+*RepresentativesApi* | [**DeleteRepresentativeAddress**](docs/RepresentativesApi.md#deleterepresentativeaddress) | **Delete** /customers/{customerID}/representatives/{representativeID}/addresses/{addressID} | Delete a Customer Representative Address
+*RepresentativesApi* | [**UpdateRepresentative**](docs/RepresentativesApi.md#updaterepresentative) | **Put** /customers/{customerID}/representatives/{representativeID} | Update Customer Representative
+*RepresentativesApi* | [**UpdateRepresentativeAddress**](docs/RepresentativesApi.md#updaterepresentativeaddress) | **Put** /customers/{customerID}/representatives/{representativeID}/addresses/{addressID} | Update Customer Representative Address
 
 
 ## Documentation For Models
@@ -81,16 +87,18 @@ Class | Method | HTTP request | Description
  - [AccountStatus](docs/AccountStatus.md)
  - [AccountType](docs/AccountType.md)
  - [AccountValidationResponse](docs/AccountValidationResponse.md)
+ - [Address](docs/Address.md)
  - [AddressType](docs/AddressType.md)
  - [Amount](docs/Amount.md)
+ - [BusinessType](docs/BusinessType.md)
  - [CompleteAccountValidationRequest](docs/CompleteAccountValidationRequest.md)
  - [CompleteAccountValidationResponse](docs/CompleteAccountValidationResponse.md)
  - [CreateAccount](docs/CreateAccount.md)
+ - [CreateAddress](docs/CreateAddress.md)
  - [CreateCustomer](docs/CreateCustomer.md)
- - [CreateCustomerAddress](docs/CreateCustomerAddress.md)
  - [CreatePhone](docs/CreatePhone.md)
+ - [CreateRepresentative](docs/CreateRepresentative.md)
  - [Customer](docs/Customer.md)
- - [CustomerAddress](docs/CustomerAddress.md)
  - [CustomerMetadata](docs/CustomerMetadata.md)
  - [CustomerStatus](docs/CustomerStatus.md)
  - [CustomerType](docs/CustomerType.md)
@@ -101,14 +109,18 @@ Class | Method | HTTP request | Description
  - [InitAccountValidationResponse](docs/InitAccountValidationResponse.md)
  - [InstitutionAddress](docs/InstitutionAddress.md)
  - [InstitutionDetails](docs/InstitutionDetails.md)
+ - [NaicsCode](docs/NaicsCode.md)
  - [OfacSearch](docs/OfacSearch.md)
  - [OrganizationConfiguration](docs/OrganizationConfiguration.md)
+ - [OwnerType](docs/OwnerType.md)
  - [Phone](docs/Phone.md)
  - [PhoneType](docs/PhoneType.md)
  - [ReportAccountResponse](docs/ReportAccountResponse.md)
+ - [Representative](docs/Representative.md)
+ - [SicCode](docs/SicCode.md)
  - [TransitAccountNumber](docs/TransitAccountNumber.md)
  - [UpdateAccountStatus](docs/UpdateAccountStatus.md)
- - [UpdateCustomerAddress](docs/UpdateCustomerAddress.md)
+ - [UpdateAddress](docs/UpdateAddress.md)
  - [UpdateCustomerStatus](docs/UpdateCustomerStatus.md)
  - [UpdateValidation](docs/UpdateValidation.md)
 
diff --git a/pkg/client/api/openapi.yaml b/pkg/client/api/openapi.yaml
index 35f4a28..5e7671b 100644
--- a/pkg/client/api/openapi.yaml
+++ b/pkg/client/api/openapi.yaml
@@ -474,7 +474,7 @@ paths:
   /customers/{customerID}/address:
     post:
       description: Add an Address onto an existing Customer record
-      operationId: addCustomerAddress
+      operationId: addAddress
       parameters:
       - description: Optional requestID allows application developer to trace requests
           through the systems logs
@@ -508,7 +508,7 @@ paths:
         content:
           application/json:
             schema:
-              $ref: '#/components/schemas/CreateCustomerAddress'
+              $ref: '#/components/schemas/CreateAddress'
         required: true
       responses:
         "200":
@@ -529,7 +529,7 @@ paths:
   /customers/{customerID}/addresses/{addressID}:
     delete:
       description: Deletes a customer's address
-      operationId: deleteCustomerAddress
+      operationId: deleteAddress
       parameters:
       - description: Customer ID
         explode: false
@@ -563,7 +563,7 @@ paths:
       - Customers
     put:
       description: Updates the specified customer address
-      operationId: updateCustomerAddress
+      operationId: updateAddress
       parameters:
       - description: Customer ID
         explode: false
@@ -587,7 +587,7 @@ paths:
         content:
           application/json:
             schema:
-              $ref: '#/components/schemas/UpdateCustomerAddress'
+              $ref: '#/components/schemas/UpdateAddress'
         required: true
       responses:
         "200":
@@ -1848,6 +1848,294 @@ paths:
       summary: Refresh Customer OFAC search
       tags:
       - Customers
+  /customers/{customerID}/representatives:
+    post:
+      description: Add a Customer Representative
+      operationId: addRepresentative
+      parameters:
+      - description: Optional requestID allows application developer to trace requests
+          through the systems logs
+        example: rs4f9915
+        explode: false
+        in: header
+        name: X-Request-ID
+        required: true
+        schema:
+          type: string
+        style: simple
+      - description: Value used to separate and identify models
+        example: org342
+        explode: false
+        in: header
+        name: X-Organization
+        required: true
+        schema:
+          type: string
+        style: simple
+      - description: customerID of the Customer for whom to add the representative
+        explode: false
+        in: path
+        name: customerID
+        required: true
+        schema:
+          example: e210a9d6-d755-4455-9bd2-9577ea7e1081
+          type: string
+        style: simple
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/CreateRepresentative'
+        required: true
+      responses:
+        "200":
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Customer'
+          description: A customer object
+        "400":
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Error'
+          description: Customer representative was not added, see error(s)
+      summary: Add Customer Representative
+      tags:
+      - Representatives
+  /customers/{customerID}/representatives/{representativeID}:
+    delete:
+      description: Deletes a Customer Representative
+      operationId: deleteRepresentative
+      parameters:
+      - description: Customer ID
+        explode: false
+        in: path
+        name: customerID
+        required: true
+        schema:
+          example: e210a9d6-d755-4455-9bd2-9577ea7e1081
+          type: string
+        style: simple
+      - description: Representative ID
+        explode: false
+        in: path
+        name: representativeID
+        required: true
+        schema:
+          example: 1d62e297-9727-4084-a902-1031da932c9e
+          type: string
+        style: simple
+      responses:
+        "204":
+          description: Successfully deleted the customer representative
+        "400":
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Error'
+          description: See error message
+      summary: Delete Customer Representative
+      tags:
+      - Representatives
+    put:
+      description: Updates the specified Customer Representative
+      operationId: updateRepresentative
+      parameters:
+      - description: Customer ID
+        explode: false
+        in: path
+        name: customerID
+        required: true
+        schema:
+          example: e210a9d6-d755-4455-9bd2-9577ea7e1081
+          type: string
+        style: simple
+      - description: Representative ID
+        explode: false
+        in: path
+        name: representativeID
+        required: true
+        schema:
+          example: 1d62e297-9727-4084-a902-1031da932c9e
+          type: string
+        style: simple
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/CreateRepresentative'
+        required: true
+      responses:
+        "200":
+          description: Updated Customer Representative
+        "400":
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Error'
+          description: See error message
+      summary: Update Customer Representative
+      tags:
+      - Representatives
+  /customers/{customerID}/representatives/{representativeID}/address:
+    post:
+      description: Add an address to an existing customer representative record
+      operationId: addRepresentativeAddress
+      parameters:
+      - description: Optional requestID allows application developer to trace requests
+          through the systems logs
+        example: rs4f9915
+        explode: false
+        in: header
+        name: X-Request-ID
+        required: false
+        schema:
+          type: string
+        style: simple
+      - description: Value used to separate and identify models
+        example: org342
+        explode: false
+        in: header
+        name: X-Organization
+        required: true
+        schema:
+          type: string
+        style: simple
+      - description: customerID of the Customer to add the address onto
+        explode: false
+        in: path
+        name: customerID
+        required: true
+        schema:
+          example: e210a9d6-d755-4455-9bd2-9577ea7e1081
+          type: string
+        style: simple
+      - description: representativeID of the Customer representative for whom to add
+          the address
+        explode: false
+        in: path
+        name: representativeID
+        required: true
+        schema:
+          example: b210a9d6-d755-4455-9bd2-9577ea7e7643
+          type: string
+        style: simple
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/CreateAddress'
+        required: true
+      responses:
+        "200":
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Representative'
+          description: A customer representative object
+        "400":
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Error'
+          description: Customer representative address was not added, see error(s)
+      summary: Add Customer Representative Address
+      tags:
+      - Representatives
+  /customers/{customerID}/representatives/{representativeID}/addresses/{addressID}:
+    delete:
+      description: Deletes a customer representative's address
+      operationId: deleteRepresentativeAddress
+      parameters:
+      - description: Customer ID
+        explode: false
+        in: path
+        name: customerID
+        required: true
+        schema:
+          example: e210a9d6-d755-4455-9bd2-9577ea7e1081
+          type: string
+        style: simple
+      - description: Customer Representative ID
+        explode: false
+        in: path
+        name: representativeID
+        required: true
+        schema:
+          example: b946a9d6-d755-4455-9bd2-9577ea7f0623
+          type: string
+        style: simple
+      - description: Address ID
+        explode: false
+        in: path
+        name: addressID
+        required: true
+        schema:
+          example: 1d62e297-9727-4084-a902-1031da932c9e
+          type: string
+        style: simple
+      responses:
+        "204":
+          description: Successfully deleted the customer representative's address
+        "400":
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Error'
+          description: See error message
+      summary: Delete a Customer Representative Address
+      tags:
+      - Representatives
+    put:
+      description: Updates the specified customer representative address
+      operationId: updateRepresentativeAddress
+      parameters:
+      - description: Customer ID
+        explode: false
+        in: path
+        name: customerID
+        required: true
+        schema:
+          example: e210a9d6-d755-4455-9bd2-9577ea7e1081
+          type: string
+        style: simple
+      - description: Customer Representative ID
+        explode: false
+        in: path
+        name: representativeID
+        required: true
+        schema:
+          example: b946a9d6-d755-4455-9bd2-9577ea7f0623
+          type: string
+        style: simple
+      - description: Address ID
+        explode: false
+        in: path
+        name: addressID
+        required: true
+        schema:
+          example: 1d62e297-9727-4084-a902-1031da932c9e
+          type: string
+        style: simple
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/UpdateAddress'
+        required: true
+      responses:
+        "200":
+          description: Updated Customer representative address
+        "400":
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Error'
+          description: See error message
+      summary: Update Customer Representative Address
+      tags:
+      - Representatives
   /reports/accounts:
     get:
       description: Retrieves a list of customer and account information.
@@ -1917,8 +2205,8 @@ components:
       - primaryAccount
     CreateCustomer:
       example:
-        firstName: Robert
         lastName: Smith
+        website: http://google.com
         addresses:
         - country: US
           address2: address2
@@ -1937,14 +2225,67 @@ components:
         metadata:
           paygateID: 23beb5fd
         nickName: Bob
+        businessName: Alphabet Inc.
+        dateBusinessEstablished: 2016-08-29
         phones:
         - number: +1.818.555.1212
         - number: +1.818.555.1212
-        middleName: Flex
+        EIN: 77-0493581
         suffix: suffix
         birthDate: 2016-08-29
-        email: email
         SSN: 111-11-1111
+        firstName: Robert
+        doingBusinessAs: Google
+        DUNS: 15-048-3782
+        middleName: Flex
+        representatives:
+        - firstName: Mary
+          lastName: Smith
+          addresses:
+          - country: US
+            address2: address2
+            city: Denver
+            address1: address1
+            postalCode: postalCode
+            state: CO
+            type: Primary
+          - country: US
+            address2: address2
+            city: Denver
+            address1: address1
+            postalCode: postalCode
+            state: CO
+            type: Primary
+          jobTitle: Chief Executive Officer
+          phones:
+          - number: +1.818.555.1212
+          - number: +1.818.555.1212
+          birthDate: 2016-08-29
+          SSN: 111-11-1111
+        - firstName: Mary
+          lastName: Smith
+          addresses:
+          - country: US
+            address2: address2
+            city: Denver
+            address1: address1
+            postalCode: postalCode
+            state: CO
+            type: Primary
+          - country: US
+            address2: address2
+            city: Denver
+            address1: address1
+            postalCode: postalCode
+            state: CO
+            type: Primary
+          jobTitle: Chief Executive Officer
+          phones:
+          - number: +1.818.555.1212
+          - number: +1.818.555.1212
+          birthDate: 2016-08-29
+          SSN: 111-11-1111
+        email: email
       properties:
         firstName:
           description: Given Name or First Name
@@ -1969,6 +2310,29 @@ components:
           type: string
         type:
           $ref: '#/components/schemas/CustomerType'
+        businessName:
+          description: Business Name for business type customers
+          example: Alphabet Inc.
+          type: string
+        doingBusinessAs:
+          description: Doing Business As (DBA) name for business type customers
+          example: Google
+          type: string
+        businessType:
+          $ref: '#/components/schemas/BusinessType'
+        EIN:
+          description: Employer Identification Number (EIN) for business type customers
+          example: 77-0493581
+          type: string
+        DUNS:
+          description: Dun & Bradstreet D-U-N-S Number (D-U-N-S) for business type
+            customers
+          example: 15-048-3782
+          type: string
+        SICCode:
+          $ref: '#/components/schemas/SICCode'
+        NAICSCode:
+          $ref: '#/components/schemas/NAICSCode'
         birthDate:
           description: Legal date of birth
           example: 2016-08-29
@@ -1981,15 +2345,27 @@ components:
           description: Customer Social Security Number (SSN)
           example: 111-11-1111
           type: string
+        website:
+          description: Company Website for business type customers
+          example: http://google.com
+          type: string
+        dateBusinessEstablished:
+          description: Date business was established for business type customers
+          example: 2016-08-29
+          type: string
         phones:
           items:
             $ref: '#/components/schemas/CreatePhone'
           type: array
         addresses:
           items:
-            $ref: '#/components/schemas/CreateCustomerAddress'
+            $ref: '#/components/schemas/CreateAddress'
           minimum: 1
           type: array
+        representatives:
+          items:
+            $ref: '#/components/schemas/CreateRepresentative'
+          type: array
         metadata:
           additionalProperties:
             type: string
@@ -2026,20 +2402,89 @@ components:
           addressID: 851233a1
         metadata:
           paygateID: 23beb5fd
-        nickName: Bob
+        businessName: Alphabet Inc.
         phones:
         - valid: true
           number: +1.818.555.1212
         - valid: true
           number: +1.818.555.1212
         suffix: suffix
+        createdAt: 2016-08-29T09:12:33.001Z
+        doingBusinessAs: Google
+        email: email
+        website: http://google.com
+        nickName: Bob
+        dateBusinessEstablished: 2016-08-29
+        EIN: 77-0493581
         birthDate: 2016-08-29
         firstName: Robert
-        createdAt: 2016-08-29T09:12:33.001Z
+        DUNS: 15-048-3782
         customerID: e210a9d6
         middleName: Flex
         lastModified: 2016-08-29T09:12:33.001Z
-        email: email
+        representatives:
+        - firstName: Mary
+          lastName: Smith
+          createdAt: 2016-08-29T09:12:33.001Z
+          addresses:
+          - country: US
+            validated: true
+            address2: address2
+            city: city
+            address1: address1
+            postalCode: postalCode
+            state: state
+            addressID: 851233a1
+          - country: US
+            validated: true
+            address2: address2
+            city: city
+            address1: address1
+            postalCode: postalCode
+            state: state
+            addressID: 851233a1
+          jobTitle: Chief Executive Officer
+          representativeID: b280b9d9
+          customerID: e210a9d6
+          phones:
+          - valid: true
+            number: +1.818.555.1212
+          - valid: true
+            number: +1.818.555.1212
+          lastModified: 2016-08-29T09:12:33.001Z
+          birthDate: 2016-08-29
+          SSN: 111-11-1111
+        - firstName: Mary
+          lastName: Smith
+          createdAt: 2016-08-29T09:12:33.001Z
+          addresses:
+          - country: US
+            validated: true
+            address2: address2
+            city: city
+            address1: address1
+            postalCode: postalCode
+            state: state
+            addressID: 851233a1
+          - country: US
+            validated: true
+            address2: address2
+            city: city
+            address1: address1
+            postalCode: postalCode
+            state: state
+            addressID: 851233a1
+          jobTitle: Chief Executive Officer
+          representativeID: b280b9d9
+          customerID: e210a9d6
+          phones:
+          - valid: true
+            number: +1.818.555.1212
+          - valid: true
+            number: +1.818.555.1212
+          lastModified: 2016-08-29T09:12:33.001Z
+          birthDate: 2016-08-29
+          SSN: 111-11-1111
       properties:
         customerID:
           description: The unique identifier for the customer who owns the account
@@ -2068,6 +2513,29 @@ components:
           type: string
         type:
           $ref: '#/components/schemas/CustomerType'
+        businessName:
+          description: Business Name for business type customers
+          example: Alphabet Inc.
+          type: string
+        doingBusinessAs:
+          description: Doing Business As (DBA) name for business type customers
+          example: Google
+          type: string
+        businessType:
+          $ref: '#/components/schemas/BusinessType'
+        EIN:
+          description: Employer Identification Number (EIN) for business type customers
+          example: 77-0493581
+          type: string
+        DUNS:
+          description: Dun & Bradstreet D-U-N-S Number (D-U-N-S) for business type
+            customers
+          example: 15-048-3782
+          type: string
+        SICCode:
+          $ref: '#/components/schemas/SICCode'
+        NAICSCode:
+          $ref: '#/components/schemas/NAICSCode'
         birthDate:
           description: Legal date of birth
           example: 2016-08-29
@@ -2078,13 +2546,25 @@ components:
           description: Primary email address of customer name@domain.com
           maximum: 500
           type: string
+        website:
+          description: Company Website for business type customers
+          example: http://google.com
+          type: string
+        dateBusinessEstablished:
+          description: Date business was established for business type customers
+          example: 2016-08-29
+          type: string
         phones:
           items:
             $ref: '#/components/schemas/Phone'
           type: array
         addresses:
           items:
-            $ref: '#/components/schemas/CustomerAddress'
+            $ref: '#/components/schemas/Address'
+          type: array
+        representatives:
+          items:
+            $ref: '#/components/schemas/Representative'
           type: array
         metadata:
           additionalProperties:
@@ -2123,6 +2603,22 @@ components:
       - individual
       - business
       type: string
+    BusinessType:
+      description: The type of business for business customers
+      enum:
+      - individual, sole proprietor, or single-member LLC
+      - corporation
+      - non-profit organization
+      - partnership
+      - limited liability company
+      type: string
+    OwnerType:
+      description: The type of individual owner of a resource, such as SSN, phone,
+        or address
+      enum:
+      - customer
+      - representative
+      type: string
     CustomerStatus:
       description: State of the customer
       enum:
@@ -2133,6 +2629,234 @@ components:
       - Verified
       - Frozen
       type: string
+    SICCode:
+      description: SIC Code (https://docs.google.com/spreadsheets/d/1erIdqoy60JwLAnpb91EfoJV5YrXDnbwSaA-aqcBlw48/edit#gid=1627409140)
+      enum:
+      - "1"
+      - "2"
+      - "7"
+      - "8.0"
+      - "9.0"
+      - "10"
+      - "12"
+      - "13"
+      - "14"
+      - "15"
+      - "16"
+      - "17"
+      - "20"
+      - "21"
+      - "22"
+      - "23"
+      - "24"
+      - "25"
+      - "26"
+      - "27"
+      - "28"
+      - "29"
+      - "30"
+      - "31"
+      - "32"
+      - "33"
+      - "34"
+      - "35"
+      - "36"
+      - "37"
+      - "38"
+      - "39"
+      - "40"
+      - "41"
+      - "42"
+      - "43"
+      - "44"
+      - "45"
+      - "46"
+      - "47"
+      - "48"
+      - "49"
+      - "50"
+      - "51"
+      - "52"
+      - "53"
+      - "54"
+      - "55"
+      - "56"
+      - "57"
+      - "58"
+      - "59"
+      - "60"
+      - "61"
+      - "62"
+      - "63"
+      - "64"
+      - "65"
+      - "67"
+      - "70"
+      - "72"
+      - "73"
+      - "75"
+      - "76"
+      - "78"
+      - "79"
+      - "80"
+      - "81"
+      - "82"
+      - "83"
+      - "84"
+      - "86"
+      - "87"
+      - "88"
+      - "89"
+      - "91"
+      - "92"
+      - "93"
+      - "94"
+      - "95"
+      - "96"
+      - "97"
+      - "98"
+      - "99"
+      type: string
+      x-enum-values:
+      - Agricultural Production – Crops
+      - Agricultural Production – Livestock
+      - Agricultural Services
+      - Forestry
+      - Fishing, Hunting, & Trapping
+      - Metal, Mining
+      - Coal Mining
+      - Oil & Gas Extraction
+      - Nonmetallic Minerals, Except Fuels
+      - General Building Contractors
+      - Heavy Construction, Except Building
+      - Special Trade Contractors
+      - Food & Kindred Products
+      - Tobacco Products
+      - Textile Mill Products
+      - Apparel & Other Textile Products
+      - Lumber & Wood Products
+      - Furniture & Fixtures
+      - Paper & Allied Products
+      - Printing & Publishing
+      - Chemical & Allied Products
+      - Petroleum & Coal Products
+      - Rubber & Miscellaneous Plastics Products
+      - Leather & Leather Products
+      - Stone, Clay, & Glass Products
+      - Primary Metal Industries
+      - Fabricated Metal Products
+      - Industrial Machinery & Equipment
+      - Electronic & Other Electric Equipment
+      - Transportation Equipment
+      - Instruments & Related Products
+      - Miscellaneous Manufacturing Industries
+      - Railroad Transportation
+      - Local & Interurban Passenger Transit
+      - Trucking & Warehousing
+      - U.S. Postal Service
+      - Water Transportation
+      - Transportation by Air
+      - Pipelines, Except Natural Gas
+      - Transportation Services
+      - Communications
+      - Electric, Gas, & Sanitary Services
+      - Wholesale Trade – Durable Goods
+      - Wholesale Trade – Nondurable Goods
+      - Building Materials & Gardening Supplies
+      - General Merchandise Stores
+      - Food Stores
+      - Automative Dealers & Service Stations
+      - Apparel & Accessory Stores
+      - Furniture & Homefurnishings Stores
+      - Eating & Drinking Places
+      - Miscellaneous Retail
+      - Depository Institutions
+      - Nondepository Institutions
+      - Security & Commodity Brokers
+      - Insurance Carriers
+      - Insurance Agents, Brokers, & Service
+      - Real Estate
+      - Holding & Other Investment Offices
+      - Hotels & Other Lodging Places
+      - Personal Services
+      - Business Services
+      - Auto Repair, Services, & Parking
+      - Miscellaneous Repair Services
+      - Motion Pictures
+      - Amusement & Recreation Services
+      - Health Services
+      - Legal Services
+      - Educational Services
+      - Social Services
+      - Museums, Botanical, Zoological Gardens
+      - Membership Organizations
+      - Engineering & Management Services
+      - Private Households
+      - Services, Not Elsewhere Classified
+      - Executive, Legislative, & General
+      - Justice, Public Order, & Safety
+      - Finance, Taxation, & Monetary Policy
+      - Administration of Human Resources
+      - Environmental Quality & Housing
+      - Administration of Economic Programs
+      - National Security & International Affairs
+      - Zoological Gardens
+      - Non-Classifiable Establishments
+    NAICSCode:
+      description: NAICS Code (https://docs.google.com/spreadsheets/d/1erIdqoy60JwLAnpb91EfoJV5YrXDnbwSaA-aqcBlw48/edit#gid=1627409140)
+      enum:
+      - "11"
+      - "21"
+      - "22"
+      - "23"
+      - "31"
+      - "32"
+      - "33"
+      - "42"
+      - "44"
+      - "45"
+      - "48"
+      - "49"
+      - "51"
+      - "52"
+      - "53"
+      - "54"
+      - "55"
+      - "56"
+      - "61"
+      - "62"
+      - "71"
+      - "72"
+      - "81"
+      - "92"
+      - "99"
+      type: string
+      x-enum-values:
+      - Agriculture, forestry, fishing and hunting
+      - Mining
+      - Utilities
+      - Construction
+      - Manufacturing
+      - Manufacturing
+      - Manufacturing
+      - Wholesale trade
+      - Retail trade
+      - Retail trade
+      - Transportation and warehousing
+      - Transportation and warehousing
+      - Information
+      - Finance and insurance
+      - Real estate and rental and leasing
+      - Professional, scientific, and technical services
+      - Management of companies and enterprises
+      - Administrative and support and waste management and remediation services
+      - Education services
+      - Health care and social assistance
+      - Arts, entertainment, and recreation
+      - Accommodation and food services
+      - Other services, except public administration
+      - Public administration
+      - Unclassified
     CustomerMetadata:
       example:
         metadata:
@@ -2160,7 +2884,7 @@ components:
           $ref: '#/components/schemas/CustomerStatus'
       required:
       - status
-    UpdateCustomerAddress:
+    UpdateAddress:
       example:
         country: US
         validated: false
@@ -2229,6 +2953,8 @@ components:
           description: phone number
           example: +1.818.555.1212
           type: string
+        ownerType:
+          $ref: '#/components/schemas/OwnerType'
         valid:
           description: phone number has been validated to connect with customer
           type: boolean
@@ -2245,7 +2971,7 @@ components:
       - mobile
       - work
       type: string
-    CreateCustomerAddress:
+    CreateAddress:
       example:
         country: US
         address2: address2
@@ -2289,7 +3015,7 @@ components:
       - state
       - type
       type: object
-    CustomerAddress:
+    Address:
       example:
         country: US
         validated: true
@@ -2306,6 +3032,8 @@ components:
           type: string
         type:
           $ref: '#/components/schemas/AddressType'
+        ownerType:
+          $ref: '#/components/schemas/OwnerType'
         address1:
           description: First line of the address
           type: string
@@ -2343,6 +3071,151 @@ components:
       - primary
       - secondary
       type: string
+    CreateRepresentative:
+      example:
+        firstName: Mary
+        lastName: Smith
+        addresses:
+        - country: US
+          address2: address2
+          city: Denver
+          address1: address1
+          postalCode: postalCode
+          state: CO
+          type: Primary
+        - country: US
+          address2: address2
+          city: Denver
+          address1: address1
+          postalCode: postalCode
+          state: CO
+          type: Primary
+        jobTitle: Chief Executive Officer
+        phones:
+        - number: +1.818.555.1212
+        - number: +1.818.555.1212
+        birthDate: 2016-08-29
+        SSN: 111-11-1111
+      properties:
+        firstName:
+          description: Given Name or First Name
+          example: Mary
+          type: string
+        lastName:
+          description: Surname or Last Name
+          example: Smith
+          type: string
+        jobTitle:
+          description: Job title of this representative
+          example: Chief Executive Officer
+          type: string
+        birthDate:
+          description: Legal date of birth
+          example: 2016-08-29
+          type: string
+        SSN:
+          description: Customer Representative's Social Security Number (SSN)
+          example: 111-11-1111
+          type: string
+        phones:
+          items:
+            $ref: '#/components/schemas/CreatePhone'
+          type: array
+        addresses:
+          items:
+            $ref: '#/components/schemas/CreateAddress'
+          type: array
+      required:
+      - firstName
+      - lastName
+    Representative:
+      example:
+        firstName: Mary
+        lastName: Smith
+        createdAt: 2016-08-29T09:12:33.001Z
+        addresses:
+        - country: US
+          validated: true
+          address2: address2
+          city: city
+          address1: address1
+          postalCode: postalCode
+          state: state
+          addressID: 851233a1
+        - country: US
+          validated: true
+          address2: address2
+          city: city
+          address1: address1
+          postalCode: postalCode
+          state: state
+          addressID: 851233a1
+        jobTitle: Chief Executive Officer
+        representativeID: b280b9d9
+        customerID: e210a9d6
+        phones:
+        - valid: true
+          number: +1.818.555.1212
+        - valid: true
+          number: +1.818.555.1212
+        lastModified: 2016-08-29T09:12:33.001Z
+        birthDate: 2016-08-29
+        SSN: 111-11-1111
+      properties:
+        representativeID:
+          description: Unique identifier for this Representative
+          example: b280b9d9
+          type: string
+        customerID:
+          description: The unique identifier for the customer the representative belongs
+            to
+          example: e210a9d6
+          type: string
+        firstName:
+          description: Given Name or First Name
+          example: Mary
+          type: string
+        lastName:
+          description: Surname or Last Name
+          example: Smith
+          type: string
+        jobTitle:
+          description: Job title of this representative
+          example: Chief Executive Officer
+          type: string
+        birthDate:
+          description: Legal date of birth
+          example: 2016-08-29
+          type: string
+        createdAt:
+          example: 2016-08-29T09:12:33.001Z
+          format: date-time
+          type: string
+        lastModified:
+          description: Last time the object was modified
+          example: 2016-08-29T09:12:33.001Z
+          format: date-time
+          type: string
+        SSN:
+          description: Customer Representative's Social Security Number (SSN)
+          example: 111-11-1111
+          type: string
+        phones:
+          items:
+            $ref: '#/components/schemas/Phone'
+          type: array
+        addresses:
+          items:
+            $ref: '#/components/schemas/Address'
+          minimum: 1
+          type: array
+      required:
+      - createdAt
+      - customerID
+      - firstName
+      - lastModified
+      - lastName
+      - representativeID
     AccountStatus:
       description: Enumeration if this account has been validated through micro-deposits
         or another available strategy.
@@ -2842,20 +3715,89 @@ components:
             addressID: 851233a1
           metadata:
             paygateID: 23beb5fd
-          nickName: Bob
+          businessName: Alphabet Inc.
           phones:
           - valid: true
             number: +1.818.555.1212
           - valid: true
             number: +1.818.555.1212
           suffix: suffix
+          createdAt: 2016-08-29T09:12:33.001Z
+          doingBusinessAs: Google
+          email: email
+          website: http://google.com
+          nickName: Bob
+          dateBusinessEstablished: 2016-08-29
+          EIN: 77-0493581
           birthDate: 2016-08-29
           firstName: Robert
-          createdAt: 2016-08-29T09:12:33.001Z
+          DUNS: 15-048-3782
           customerID: e210a9d6
           middleName: Flex
           lastModified: 2016-08-29T09:12:33.001Z
-          email: email
+          representatives:
+          - firstName: Mary
+            lastName: Smith
+            createdAt: 2016-08-29T09:12:33.001Z
+            addresses:
+            - country: US
+              validated: true
+              address2: address2
+              city: city
+              address1: address1
+              postalCode: postalCode
+              state: state
+              addressID: 851233a1
+            - country: US
+              validated: true
+              address2: address2
+              city: city
+              address1: address1
+              postalCode: postalCode
+              state: state
+              addressID: 851233a1
+            jobTitle: Chief Executive Officer
+            representativeID: b280b9d9
+            customerID: e210a9d6
+            phones:
+            - valid: true
+              number: +1.818.555.1212
+            - valid: true
+              number: +1.818.555.1212
+            lastModified: 2016-08-29T09:12:33.001Z
+            birthDate: 2016-08-29
+            SSN: 111-11-1111
+          - firstName: Mary
+            lastName: Smith
+            createdAt: 2016-08-29T09:12:33.001Z
+            addresses:
+            - country: US
+              validated: true
+              address2: address2
+              city: city
+              address1: address1
+              postalCode: postalCode
+              state: state
+              addressID: 851233a1
+            - country: US
+              validated: true
+              address2: address2
+              city: city
+              address1: address1
+              postalCode: postalCode
+              state: state
+              addressID: 851233a1
+            jobTitle: Chief Executive Officer
+            representativeID: b280b9d9
+            customerID: e210a9d6
+            phones:
+            - valid: true
+              number: +1.818.555.1212
+            - valid: true
+              number: +1.818.555.1212
+            lastModified: 2016-08-29T09:12:33.001Z
+            birthDate: 2016-08-29
+            SSN: 111-11-1111
       properties:
         Customer:
           $ref: '#/components/schemas/Customer'
diff --git a/pkg/client/api_customers.go b/pkg/client/api_customers.go
index d5f76c9..b924453 100644
--- a/pkg/client/api_customers.go
+++ b/pkg/client/api_customers.go
@@ -26,24 +26,24 @@ var (
 // CustomersApiService CustomersApi service
 type CustomersApiService service
 
-// AddCustomerAddressOpts Optional parameters for the method 'AddCustomerAddress'
-type AddCustomerAddressOpts struct {
+// AddAddressOpts Optional parameters for the method 'AddAddress'
+type AddAddressOpts struct {
 	XRequestID    optional.String
 	XOrganization optional.String
 }
 
 /*
-AddCustomerAddress Add Customer Address
+AddAddress Add Customer Address
 Add an Address onto an existing Customer record
  * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
  * @param customerID customerID of the Customer to add the address onto
- * @param createCustomerAddress
- * @param optional nil or *AddCustomerAddressOpts - Optional Parameters:
+ * @param createAddress
+ * @param optional nil or *AddAddressOpts - Optional Parameters:
  * @param "XRequestID" (optional.String) -  Optional requestID allows application developer to trace requests through the systems logs
  * @param "XOrganization" (optional.String) -  Value used to separate and identify models
 @return Customer
 */
-func (a *CustomersApiService) AddCustomerAddress(ctx _context.Context, customerID string, createCustomerAddress CreateCustomerAddress, localVarOptionals *AddCustomerAddressOpts) (Customer, *_nethttp.Response, error) {
+func (a *CustomersApiService) AddAddress(ctx _context.Context, customerID string, createAddress CreateAddress, localVarOptionals *AddAddressOpts) (Customer, *_nethttp.Response, error) {
 	var (
 		localVarHTTPMethod   = _nethttp.MethodPost
 		localVarPostBody     interface{}
@@ -85,7 +85,7 @@ func (a *CustomersApiService) AddCustomerAddress(ctx _context.Context, customerI
 		localVarHeaderParams["X-Organization"] = parameterToString(localVarOptionals.XOrganization.Value(), "")
 	}
 	// body params
-	localVarPostBody = &createCustomerAddress
+	localVarPostBody = &createAddress
 	r, err := a.client.prepareRequest(ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes)
 	if err != nil {
 		return localVarReturnValue, nil, err
@@ -233,22 +233,14 @@ func (a *CustomersApiService) CreateCustomer(ctx _context.Context, createCustome
 	return localVarReturnValue, localVarHTTPResponse, nil
 }
 
-// DeleteCustomerOpts Optional parameters for the method 'DeleteCustomer'
-type DeleteCustomerOpts struct {
-	XRequestID    optional.String
-	XOrganization optional.String
-}
-
 /*
-DeleteCustomer Delete Customer
-Remove a given Customer
+DeleteAddress Delete Customer Address
+Deletes a customer&#39;s address
  * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
- * @param customerID customerID of the Customer to be deleted
- * @param optional nil or *DeleteCustomerOpts - Optional Parameters:
- * @param "XRequestID" (optional.String) -  Optional requestID allows application developer to trace requests through the systems logs
- * @param "XOrganization" (optional.String) -  Value used to separate and identify models
+ * @param customerID Customer ID
+ * @param addressID Address ID
 */
-func (a *CustomersApiService) DeleteCustomer(ctx _context.Context, customerID string, localVarOptionals *DeleteCustomerOpts) (*_nethttp.Response, error) {
+func (a *CustomersApiService) DeleteAddress(ctx _context.Context, customerID string, addressID string) (*_nethttp.Response, error) {
 	var (
 		localVarHTTPMethod   = _nethttp.MethodDelete
 		localVarPostBody     interface{}
@@ -258,9 +250,11 @@ func (a *CustomersApiService) DeleteCustomer(ctx _context.Context, customerID st
 	)
 
 	// create path and map variables
-	localVarPath := a.client.cfg.BasePath + "/customers/{customerID}"
+	localVarPath := a.client.cfg.BasePath + "/customers/{customerID}/addresses/{addressID}"
 	localVarPath = strings.Replace(localVarPath, "{"+"customerID"+"}", _neturl.QueryEscape(parameterToString(customerID, "")), -1)
 
+	localVarPath = strings.Replace(localVarPath, "{"+"addressID"+"}", _neturl.QueryEscape(parameterToString(addressID, "")), -1)
+
 	localVarHeaderParams := make(map[string]string)
 	localVarQueryParams := _neturl.Values{}
 	localVarFormParams := _neturl.Values{}
@@ -275,19 +269,13 @@ func (a *CustomersApiService) DeleteCustomer(ctx _context.Context, customerID st
 	}
 
 	// to determine the Accept header
-	localVarHTTPHeaderAccepts := []string{}
+	localVarHTTPHeaderAccepts := []string{"application/json"}
 
 	// set Accept header
 	localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
 	if localVarHTTPHeaderAccept != "" {
 		localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
 	}
-	if localVarOptionals != nil && localVarOptionals.XRequestID.IsSet() {
-		localVarHeaderParams["X-Request-ID"] = parameterToString(localVarOptionals.XRequestID.Value(), "")
-	}
-	if localVarOptionals != nil && localVarOptionals.XOrganization.IsSet() {
-		localVarHeaderParams["X-Organization"] = parameterToString(localVarOptionals.XOrganization.Value(), "")
-	}
 	r, err := a.client.prepareRequest(ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes)
 	if err != nil {
 		return nil, err
@@ -309,20 +297,37 @@ func (a *CustomersApiService) DeleteCustomer(ctx _context.Context, customerID st
 			body:  localVarBody,
 			error: localVarHTTPResponse.Status,
 		}
+		if localVarHTTPResponse.StatusCode == 400 {
+			var v Error
+			err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
+			if err != nil {
+				newErr.error = err.Error()
+				return localVarHTTPResponse, newErr
+			}
+			newErr.model = v
+		}
 		return localVarHTTPResponse, newErr
 	}
 
 	return localVarHTTPResponse, nil
 }
 
+// DeleteCustomerOpts Optional parameters for the method 'DeleteCustomer'
+type DeleteCustomerOpts struct {
+	XRequestID    optional.String
+	XOrganization optional.String
+}
+
 /*
-DeleteCustomerAddress Delete Customer Address
-Deletes a customer&#39;s address
+DeleteCustomer Delete Customer
+Remove a given Customer
  * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
- * @param customerID Customer ID
- * @param addressID Address ID
+ * @param customerID customerID of the Customer to be deleted
+ * @param optional nil or *DeleteCustomerOpts - Optional Parameters:
+ * @param "XRequestID" (optional.String) -  Optional requestID allows application developer to trace requests through the systems logs
+ * @param "XOrganization" (optional.String) -  Value used to separate and identify models
 */
-func (a *CustomersApiService) DeleteCustomerAddress(ctx _context.Context, customerID string, addressID string) (*_nethttp.Response, error) {
+func (a *CustomersApiService) DeleteCustomer(ctx _context.Context, customerID string, localVarOptionals *DeleteCustomerOpts) (*_nethttp.Response, error) {
 	var (
 		localVarHTTPMethod   = _nethttp.MethodDelete
 		localVarPostBody     interface{}
@@ -332,11 +337,9 @@ func (a *CustomersApiService) DeleteCustomerAddress(ctx _context.Context, custom
 	)
 
 	// create path and map variables
-	localVarPath := a.client.cfg.BasePath + "/customers/{customerID}/addresses/{addressID}"
+	localVarPath := a.client.cfg.BasePath + "/customers/{customerID}"
 	localVarPath = strings.Replace(localVarPath, "{"+"customerID"+"}", _neturl.QueryEscape(parameterToString(customerID, "")), -1)
 
-	localVarPath = strings.Replace(localVarPath, "{"+"addressID"+"}", _neturl.QueryEscape(parameterToString(addressID, "")), -1)
-
 	localVarHeaderParams := make(map[string]string)
 	localVarQueryParams := _neturl.Values{}
 	localVarFormParams := _neturl.Values{}
@@ -351,13 +354,19 @@ func (a *CustomersApiService) DeleteCustomerAddress(ctx _context.Context, custom
 	}
 
 	// to determine the Accept header
-	localVarHTTPHeaderAccepts := []string{"application/json"}
+	localVarHTTPHeaderAccepts := []string{}
 
 	// set Accept header
 	localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
 	if localVarHTTPHeaderAccept != "" {
 		localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
 	}
+	if localVarOptionals != nil && localVarOptionals.XRequestID.IsSet() {
+		localVarHeaderParams["X-Request-ID"] = parameterToString(localVarOptionals.XRequestID.Value(), "")
+	}
+	if localVarOptionals != nil && localVarOptionals.XOrganization.IsSet() {
+		localVarHeaderParams["X-Organization"] = parameterToString(localVarOptionals.XOrganization.Value(), "")
+	}
 	r, err := a.client.prepareRequest(ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes)
 	if err != nil {
 		return nil, err
@@ -379,15 +388,6 @@ func (a *CustomersApiService) DeleteCustomerAddress(ctx _context.Context, custom
 			body:  localVarBody,
 			error: localVarHTTPResponse.Status,
 		}
-		if localVarHTTPResponse.StatusCode == 400 {
-			var v Error
-			err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
-			if err != nil {
-				newErr.error = err.Error()
-				return localVarHTTPResponse, newErr
-			}
-			newErr.model = v
-		}
 		return localVarHTTPResponse, newErr
 	}
 
@@ -994,37 +994,29 @@ func (a *CustomersApiService) SearchCustomers(ctx _context.Context, localVarOpti
 	return localVarReturnValue, localVarHTTPResponse, nil
 }
 
-// UpdateCustomerOpts Optional parameters for the method 'UpdateCustomer'
-type UpdateCustomerOpts struct {
-	XRequestID    optional.String
-	XOrganization optional.String
-}
-
 /*
-UpdateCustomer Update Customer
-Update a Customer object
+UpdateAddress Update Customer Address
+Updates the specified customer address
  * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
- * @param customerID customerID that identifies this Customer
- * @param createCustomer
- * @param optional nil or *UpdateCustomerOpts - Optional Parameters:
- * @param "XRequestID" (optional.String) -  Optional requestID allows application developer to trace requests through the systems logs
- * @param "XOrganization" (optional.String) -  Value used to separate and identify models
-@return Customer
+ * @param customerID Customer ID
+ * @param addressID Address ID
+ * @param updateAddress
 */
-func (a *CustomersApiService) UpdateCustomer(ctx _context.Context, customerID string, createCustomer CreateCustomer, localVarOptionals *UpdateCustomerOpts) (Customer, *_nethttp.Response, error) {
+func (a *CustomersApiService) UpdateAddress(ctx _context.Context, customerID string, addressID string, updateAddress UpdateAddress) (*_nethttp.Response, error) {
 	var (
 		localVarHTTPMethod   = _nethttp.MethodPut
 		localVarPostBody     interface{}
 		localVarFormFileName string
 		localVarFileName     string
 		localVarFileBytes    []byte
-		localVarReturnValue  Customer
 	)
 
 	// create path and map variables
-	localVarPath := a.client.cfg.BasePath + "/customers/{customerID}"
+	localVarPath := a.client.cfg.BasePath + "/customers/{customerID}/addresses/{addressID}"
 	localVarPath = strings.Replace(localVarPath, "{"+"customerID"+"}", _neturl.QueryEscape(parameterToString(customerID, "")), -1)
 
+	localVarPath = strings.Replace(localVarPath, "{"+"addressID"+"}", _neturl.QueryEscape(parameterToString(addressID, "")), -1)
+
 	localVarHeaderParams := make(map[string]string)
 	localVarQueryParams := _neturl.Values{}
 	localVarFormParams := _neturl.Values{}
@@ -1046,28 +1038,22 @@ func (a *CustomersApiService) UpdateCustomer(ctx _context.Context, customerID st
 	if localVarHTTPHeaderAccept != "" {
 		localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
 	}
-	if localVarOptionals != nil && localVarOptionals.XRequestID.IsSet() {
-		localVarHeaderParams["X-Request-ID"] = parameterToString(localVarOptionals.XRequestID.Value(), "")
-	}
-	if localVarOptionals != nil && localVarOptionals.XOrganization.IsSet() {
-		localVarHeaderParams["X-Organization"] = parameterToString(localVarOptionals.XOrganization.Value(), "")
-	}
 	// body params
-	localVarPostBody = &createCustomer
+	localVarPostBody = &updateAddress
 	r, err := a.client.prepareRequest(ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes)
 	if err != nil {
-		return localVarReturnValue, nil, err
+		return nil, err
 	}
 
 	localVarHTTPResponse, err := a.client.callAPI(r)
 	if err != nil || localVarHTTPResponse == nil {
-		return localVarReturnValue, localVarHTTPResponse, err
+		return localVarHTTPResponse, err
 	}
 
 	localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
 	localVarHTTPResponse.Body.Close()
 	if err != nil {
-		return localVarReturnValue, localVarHTTPResponse, err
+		return localVarHTTPResponse, err
 	}
 
 	if localVarHTTPResponse.StatusCode >= 300 {
@@ -1080,48 +1066,47 @@ func (a *CustomersApiService) UpdateCustomer(ctx _context.Context, customerID st
 			err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
 			if err != nil {
 				newErr.error = err.Error()
-				return localVarReturnValue, localVarHTTPResponse, newErr
+				return localVarHTTPResponse, newErr
 			}
 			newErr.model = v
 		}
-		return localVarReturnValue, localVarHTTPResponse, newErr
+		return localVarHTTPResponse, newErr
 	}
 
-	err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
-	if err != nil {
-		newErr := GenericOpenAPIError{
-			body:  localVarBody,
-			error: err.Error(),
-		}
-		return localVarReturnValue, localVarHTTPResponse, newErr
-	}
+	return localVarHTTPResponse, nil
+}
 
-	return localVarReturnValue, localVarHTTPResponse, nil
+// UpdateCustomerOpts Optional parameters for the method 'UpdateCustomer'
+type UpdateCustomerOpts struct {
+	XRequestID    optional.String
+	XOrganization optional.String
 }
 
 /*
-UpdateCustomerAddress Update Customer Address
-Updates the specified customer address
+UpdateCustomer Update Customer
+Update a Customer object
  * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
- * @param customerID Customer ID
- * @param addressID Address ID
- * @param updateCustomerAddress
+ * @param customerID customerID that identifies this Customer
+ * @param createCustomer
+ * @param optional nil or *UpdateCustomerOpts - Optional Parameters:
+ * @param "XRequestID" (optional.String) -  Optional requestID allows application developer to trace requests through the systems logs
+ * @param "XOrganization" (optional.String) -  Value used to separate and identify models
+@return Customer
 */
-func (a *CustomersApiService) UpdateCustomerAddress(ctx _context.Context, customerID string, addressID string, updateCustomerAddress UpdateCustomerAddress) (*_nethttp.Response, error) {
+func (a *CustomersApiService) UpdateCustomer(ctx _context.Context, customerID string, createCustomer CreateCustomer, localVarOptionals *UpdateCustomerOpts) (Customer, *_nethttp.Response, error) {
 	var (
 		localVarHTTPMethod   = _nethttp.MethodPut
 		localVarPostBody     interface{}
 		localVarFormFileName string
 		localVarFileName     string
 		localVarFileBytes    []byte
+		localVarReturnValue  Customer
 	)
 
 	// create path and map variables
-	localVarPath := a.client.cfg.BasePath + "/customers/{customerID}/addresses/{addressID}"
+	localVarPath := a.client.cfg.BasePath + "/customers/{customerID}"
 	localVarPath = strings.Replace(localVarPath, "{"+"customerID"+"}", _neturl.QueryEscape(parameterToString(customerID, "")), -1)
 
-	localVarPath = strings.Replace(localVarPath, "{"+"addressID"+"}", _neturl.QueryEscape(parameterToString(addressID, "")), -1)
-
 	localVarHeaderParams := make(map[string]string)
 	localVarQueryParams := _neturl.Values{}
 	localVarFormParams := _neturl.Values{}
@@ -1143,22 +1128,28 @@ func (a *CustomersApiService) UpdateCustomerAddress(ctx _context.Context, custom
 	if localVarHTTPHeaderAccept != "" {
 		localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
 	}
+	if localVarOptionals != nil && localVarOptionals.XRequestID.IsSet() {
+		localVarHeaderParams["X-Request-ID"] = parameterToString(localVarOptionals.XRequestID.Value(), "")
+	}
+	if localVarOptionals != nil && localVarOptionals.XOrganization.IsSet() {
+		localVarHeaderParams["X-Organization"] = parameterToString(localVarOptionals.XOrganization.Value(), "")
+	}
 	// body params
-	localVarPostBody = &updateCustomerAddress
+	localVarPostBody = &createCustomer
 	r, err := a.client.prepareRequest(ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes)
 	if err != nil {
-		return nil, err
+		return localVarReturnValue, nil, err
 	}
 
 	localVarHTTPResponse, err := a.client.callAPI(r)
 	if err != nil || localVarHTTPResponse == nil {
-		return localVarHTTPResponse, err
+		return localVarReturnValue, localVarHTTPResponse, err
 	}
 
 	localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
 	localVarHTTPResponse.Body.Close()
 	if err != nil {
-		return localVarHTTPResponse, err
+		return localVarReturnValue, localVarHTTPResponse, err
 	}
 
 	if localVarHTTPResponse.StatusCode >= 300 {
@@ -1171,14 +1162,23 @@ func (a *CustomersApiService) UpdateCustomerAddress(ctx _context.Context, custom
 			err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
 			if err != nil {
 				newErr.error = err.Error()
-				return localVarHTTPResponse, newErr
+				return localVarReturnValue, localVarHTTPResponse, newErr
 			}
 			newErr.model = v
 		}
-		return localVarHTTPResponse, newErr
+		return localVarReturnValue, localVarHTTPResponse, newErr
 	}
 
-	return localVarHTTPResponse, nil
+	err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
+	if err != nil {
+		newErr := GenericOpenAPIError{
+			body:  localVarBody,
+			error: err.Error(),
+		}
+		return localVarReturnValue, localVarHTTPResponse, newErr
+	}
+
+	return localVarReturnValue, localVarHTTPResponse, nil
 }
 
 // UpdateCustomerStatusOpts Optional parameters for the method 'UpdateCustomerStatus'
diff --git a/pkg/client/api_representatives.go b/pkg/client/api_representatives.go
new file mode 100644
index 0000000..5f6948d
--- /dev/null
+++ b/pkg/client/api_representatives.go
@@ -0,0 +1,554 @@
+/*
+ * Customers API
+ *
+ * Customers focuses on solving authentic identification of humans who are legally able to hold and transfer currency within the US. Primarily this project solves [Know Your Customer](https://en.wikipedia.org/wiki/Know_your_customer) (KYC), [Customer Identification Program](https://en.wikipedia.org/wiki/Customer_Identification_Program) (CIP), [Office of Foreign Asset Control](https://www.treasury.gov/about/organizational-structure/offices/Pages/Office-of-Foreign-Assets-Control.aspx) (OFAC) checks and verification workflows to comply with United States federal law and ensure authentic transfers. Customers has an objective to be a service for detailed due diligence on individuals and companies for Financial Institutions and services in a modernized and extensible way.  Customer phone numbers and addresses are stored and partially used in KYC/OFAC validation. Arbitrary key/value pairs can be stored for a Customer. Documents and Disclaimers, and their acknowledgment are also stored under a Customer as they're accepted. Bank Accounts, which can be validated with micro-deposits currently, are stored under each Customer.  ![](https://raw.githubusercontent.com/adamdecaf/customers/create-accounts/docs/images/customer.png)
+ *
+ * API version: v1
+ * Generated by: OpenAPI Generator (https://openapi-generator.tech)
+ */
+
+package client
+
+import (
+	_context "context"
+	"github.com/antihax/optional"
+	_ioutil "io/ioutil"
+	_nethttp "net/http"
+	_neturl "net/url"
+	"strings"
+)
+
+// Linger please
+var (
+	_ _context.Context
+)
+
+// RepresentativesApiService RepresentativesApi service
+type RepresentativesApiService service
+
+/*
+AddRepresentative Add Customer Representative
+Add a Customer Representative
+ * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param xRequestID Optional requestID allows application developer to trace requests through the systems logs
+ * @param xOrganization Value used to separate and identify models
+ * @param customerID customerID of the Customer for whom to add the representative
+ * @param createRepresentative
+@return Customer
+*/
+func (a *RepresentativesApiService) AddRepresentative(ctx _context.Context, xRequestID string, xOrganization string, customerID string, createRepresentative CreateRepresentative) (Customer, *_nethttp.Response, error) {
+	var (
+		localVarHTTPMethod   = _nethttp.MethodPost
+		localVarPostBody     interface{}
+		localVarFormFileName string
+		localVarFileName     string
+		localVarFileBytes    []byte
+		localVarReturnValue  Customer
+	)
+
+	// create path and map variables
+	localVarPath := a.client.cfg.BasePath + "/customers/{customerID}/representatives"
+	localVarPath = strings.Replace(localVarPath, "{"+"customerID"+"}", _neturl.QueryEscape(parameterToString(customerID, "")), -1)
+
+	localVarHeaderParams := make(map[string]string)
+	localVarQueryParams := _neturl.Values{}
+	localVarFormParams := _neturl.Values{}
+
+	// to determine the Content-Type header
+	localVarHTTPContentTypes := []string{"application/json"}
+
+	// set Content-Type header
+	localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
+	if localVarHTTPContentType != "" {
+		localVarHeaderParams["Content-Type"] = localVarHTTPContentType
+	}
+
+	// to determine the Accept header
+	localVarHTTPHeaderAccepts := []string{"application/json"}
+
+	// set Accept header
+	localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
+	if localVarHTTPHeaderAccept != "" {
+		localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
+	}
+	localVarHeaderParams["X-Request-ID"] = parameterToString(xRequestID, "")
+	localVarHeaderParams["X-Organization"] = parameterToString(xOrganization, "")
+	// body params
+	localVarPostBody = &createRepresentative
+	r, err := a.client.prepareRequest(ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes)
+	if err != nil {
+		return localVarReturnValue, nil, err
+	}
+
+	localVarHTTPResponse, err := a.client.callAPI(r)
+	if err != nil || localVarHTTPResponse == nil {
+		return localVarReturnValue, localVarHTTPResponse, err
+	}
+
+	localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
+	localVarHTTPResponse.Body.Close()
+	if err != nil {
+		return localVarReturnValue, localVarHTTPResponse, err
+	}
+
+	if localVarHTTPResponse.StatusCode >= 300 {
+		newErr := GenericOpenAPIError{
+			body:  localVarBody,
+			error: localVarHTTPResponse.Status,
+		}
+		if localVarHTTPResponse.StatusCode == 400 {
+			var v Error
+			err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
+			if err != nil {
+				newErr.error = err.Error()
+				return localVarReturnValue, localVarHTTPResponse, newErr
+			}
+			newErr.model = v
+		}
+		return localVarReturnValue, localVarHTTPResponse, newErr
+	}
+
+	err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
+	if err != nil {
+		newErr := GenericOpenAPIError{
+			body:  localVarBody,
+			error: err.Error(),
+		}
+		return localVarReturnValue, localVarHTTPResponse, newErr
+	}
+
+	return localVarReturnValue, localVarHTTPResponse, nil
+}
+
+// AddRepresentativeAddressOpts Optional parameters for the method 'AddRepresentativeAddress'
+type AddRepresentativeAddressOpts struct {
+	XRequestID optional.String
+}
+
+/*
+AddRepresentativeAddress Add Customer Representative Address
+Add an address to an existing customer representative record
+ * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param xOrganization Value used to separate and identify models
+ * @param customerID customerID of the Customer to add the address onto
+ * @param representativeID representativeID of the Customer representative for whom to add the address
+ * @param createAddress
+ * @param optional nil or *AddRepresentativeAddressOpts - Optional Parameters:
+ * @param "XRequestID" (optional.String) -  Optional requestID allows application developer to trace requests through the systems logs
+@return Representative
+*/
+func (a *RepresentativesApiService) AddRepresentativeAddress(ctx _context.Context, xOrganization string, customerID string, representativeID string, createAddress CreateAddress, localVarOptionals *AddRepresentativeAddressOpts) (Representative, *_nethttp.Response, error) {
+	var (
+		localVarHTTPMethod   = _nethttp.MethodPost
+		localVarPostBody     interface{}
+		localVarFormFileName string
+		localVarFileName     string
+		localVarFileBytes    []byte
+		localVarReturnValue  Representative
+	)
+
+	// create path and map variables
+	localVarPath := a.client.cfg.BasePath + "/customers/{customerID}/representatives/{representativeID}/address"
+	localVarPath = strings.Replace(localVarPath, "{"+"customerID"+"}", _neturl.QueryEscape(parameterToString(customerID, "")), -1)
+
+	localVarPath = strings.Replace(localVarPath, "{"+"representativeID"+"}", _neturl.QueryEscape(parameterToString(representativeID, "")), -1)
+
+	localVarHeaderParams := make(map[string]string)
+	localVarQueryParams := _neturl.Values{}
+	localVarFormParams := _neturl.Values{}
+
+	// to determine the Content-Type header
+	localVarHTTPContentTypes := []string{"application/json"}
+
+	// set Content-Type header
+	localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
+	if localVarHTTPContentType != "" {
+		localVarHeaderParams["Content-Type"] = localVarHTTPContentType
+	}
+
+	// to determine the Accept header
+	localVarHTTPHeaderAccepts := []string{"application/json"}
+
+	// set Accept header
+	localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
+	if localVarHTTPHeaderAccept != "" {
+		localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
+	}
+	if localVarOptionals != nil && localVarOptionals.XRequestID.IsSet() {
+		localVarHeaderParams["X-Request-ID"] = parameterToString(localVarOptionals.XRequestID.Value(), "")
+	}
+	localVarHeaderParams["X-Organization"] = parameterToString(xOrganization, "")
+	// body params
+	localVarPostBody = &createAddress
+	r, err := a.client.prepareRequest(ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes)
+	if err != nil {
+		return localVarReturnValue, nil, err
+	}
+
+	localVarHTTPResponse, err := a.client.callAPI(r)
+	if err != nil || localVarHTTPResponse == nil {
+		return localVarReturnValue, localVarHTTPResponse, err
+	}
+
+	localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
+	localVarHTTPResponse.Body.Close()
+	if err != nil {
+		return localVarReturnValue, localVarHTTPResponse, err
+	}
+
+	if localVarHTTPResponse.StatusCode >= 300 {
+		newErr := GenericOpenAPIError{
+			body:  localVarBody,
+			error: localVarHTTPResponse.Status,
+		}
+		if localVarHTTPResponse.StatusCode == 400 {
+			var v Error
+			err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
+			if err != nil {
+				newErr.error = err.Error()
+				return localVarReturnValue, localVarHTTPResponse, newErr
+			}
+			newErr.model = v
+		}
+		return localVarReturnValue, localVarHTTPResponse, newErr
+	}
+
+	err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
+	if err != nil {
+		newErr := GenericOpenAPIError{
+			body:  localVarBody,
+			error: err.Error(),
+		}
+		return localVarReturnValue, localVarHTTPResponse, newErr
+	}
+
+	return localVarReturnValue, localVarHTTPResponse, nil
+}
+
+/*
+DeleteRepresentative Delete Customer Representative
+Deletes a Customer Representative
+ * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param customerID Customer ID
+ * @param representativeID Representative ID
+*/
+func (a *RepresentativesApiService) DeleteRepresentative(ctx _context.Context, customerID string, representativeID string) (*_nethttp.Response, error) {
+	var (
+		localVarHTTPMethod   = _nethttp.MethodDelete
+		localVarPostBody     interface{}
+		localVarFormFileName string
+		localVarFileName     string
+		localVarFileBytes    []byte
+	)
+
+	// create path and map variables
+	localVarPath := a.client.cfg.BasePath + "/customers/{customerID}/representatives/{representativeID}"
+	localVarPath = strings.Replace(localVarPath, "{"+"customerID"+"}", _neturl.QueryEscape(parameterToString(customerID, "")), -1)
+
+	localVarPath = strings.Replace(localVarPath, "{"+"representativeID"+"}", _neturl.QueryEscape(parameterToString(representativeID, "")), -1)
+
+	localVarHeaderParams := make(map[string]string)
+	localVarQueryParams := _neturl.Values{}
+	localVarFormParams := _neturl.Values{}
+
+	// to determine the Content-Type header
+	localVarHTTPContentTypes := []string{}
+
+	// set Content-Type header
+	localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
+	if localVarHTTPContentType != "" {
+		localVarHeaderParams["Content-Type"] = localVarHTTPContentType
+	}
+
+	// to determine the Accept header
+	localVarHTTPHeaderAccepts := []string{"application/json"}
+
+	// set Accept header
+	localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
+	if localVarHTTPHeaderAccept != "" {
+		localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
+	}
+	r, err := a.client.prepareRequest(ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes)
+	if err != nil {
+		return nil, err
+	}
+
+	localVarHTTPResponse, err := a.client.callAPI(r)
+	if err != nil || localVarHTTPResponse == nil {
+		return localVarHTTPResponse, err
+	}
+
+	localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
+	localVarHTTPResponse.Body.Close()
+	if err != nil {
+		return localVarHTTPResponse, err
+	}
+
+	if localVarHTTPResponse.StatusCode >= 300 {
+		newErr := GenericOpenAPIError{
+			body:  localVarBody,
+			error: localVarHTTPResponse.Status,
+		}
+		if localVarHTTPResponse.StatusCode == 400 {
+			var v Error
+			err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
+			if err != nil {
+				newErr.error = err.Error()
+				return localVarHTTPResponse, newErr
+			}
+			newErr.model = v
+		}
+		return localVarHTTPResponse, newErr
+	}
+
+	return localVarHTTPResponse, nil
+}
+
+/*
+DeleteRepresentativeAddress Delete a Customer Representative Address
+Deletes a customer representative&#39;s address
+ * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param customerID Customer ID
+ * @param representativeID Customer Representative ID
+ * @param addressID Address ID
+*/
+func (a *RepresentativesApiService) DeleteRepresentativeAddress(ctx _context.Context, customerID string, representativeID string, addressID string) (*_nethttp.Response, error) {
+	var (
+		localVarHTTPMethod   = _nethttp.MethodDelete
+		localVarPostBody     interface{}
+		localVarFormFileName string
+		localVarFileName     string
+		localVarFileBytes    []byte
+	)
+
+	// create path and map variables
+	localVarPath := a.client.cfg.BasePath + "/customers/{customerID}/representatives/{representativeID}/addresses/{addressID}"
+	localVarPath = strings.Replace(localVarPath, "{"+"customerID"+"}", _neturl.QueryEscape(parameterToString(customerID, "")), -1)
+
+	localVarPath = strings.Replace(localVarPath, "{"+"representativeID"+"}", _neturl.QueryEscape(parameterToString(representativeID, "")), -1)
+
+	localVarPath = strings.Replace(localVarPath, "{"+"addressID"+"}", _neturl.QueryEscape(parameterToString(addressID, "")), -1)
+
+	localVarHeaderParams := make(map[string]string)
+	localVarQueryParams := _neturl.Values{}
+	localVarFormParams := _neturl.Values{}
+
+	// to determine the Content-Type header
+	localVarHTTPContentTypes := []string{}
+
+	// set Content-Type header
+	localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
+	if localVarHTTPContentType != "" {
+		localVarHeaderParams["Content-Type"] = localVarHTTPContentType
+	}
+
+	// to determine the Accept header
+	localVarHTTPHeaderAccepts := []string{"application/json"}
+
+	// set Accept header
+	localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
+	if localVarHTTPHeaderAccept != "" {
+		localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
+	}
+	r, err := a.client.prepareRequest(ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes)
+	if err != nil {
+		return nil, err
+	}
+
+	localVarHTTPResponse, err := a.client.callAPI(r)
+	if err != nil || localVarHTTPResponse == nil {
+		return localVarHTTPResponse, err
+	}
+
+	localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
+	localVarHTTPResponse.Body.Close()
+	if err != nil {
+		return localVarHTTPResponse, err
+	}
+
+	if localVarHTTPResponse.StatusCode >= 300 {
+		newErr := GenericOpenAPIError{
+			body:  localVarBody,
+			error: localVarHTTPResponse.Status,
+		}
+		if localVarHTTPResponse.StatusCode == 400 {
+			var v Error
+			err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
+			if err != nil {
+				newErr.error = err.Error()
+				return localVarHTTPResponse, newErr
+			}
+			newErr.model = v
+		}
+		return localVarHTTPResponse, newErr
+	}
+
+	return localVarHTTPResponse, nil
+}
+
+/*
+UpdateRepresentative Update Customer Representative
+Updates the specified Customer Representative
+ * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param customerID Customer ID
+ * @param representativeID Representative ID
+ * @param createRepresentative
+*/
+func (a *RepresentativesApiService) UpdateRepresentative(ctx _context.Context, customerID string, representativeID string, createRepresentative CreateRepresentative) (*_nethttp.Response, error) {
+	var (
+		localVarHTTPMethod   = _nethttp.MethodPut
+		localVarPostBody     interface{}
+		localVarFormFileName string
+		localVarFileName     string
+		localVarFileBytes    []byte
+	)
+
+	// create path and map variables
+	localVarPath := a.client.cfg.BasePath + "/customers/{customerID}/representatives/{representativeID}"
+	localVarPath = strings.Replace(localVarPath, "{"+"customerID"+"}", _neturl.QueryEscape(parameterToString(customerID, "")), -1)
+
+	localVarPath = strings.Replace(localVarPath, "{"+"representativeID"+"}", _neturl.QueryEscape(parameterToString(representativeID, "")), -1)
+
+	localVarHeaderParams := make(map[string]string)
+	localVarQueryParams := _neturl.Values{}
+	localVarFormParams := _neturl.Values{}
+
+	// to determine the Content-Type header
+	localVarHTTPContentTypes := []string{"application/json"}
+
+	// set Content-Type header
+	localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
+	if localVarHTTPContentType != "" {
+		localVarHeaderParams["Content-Type"] = localVarHTTPContentType
+	}
+
+	// to determine the Accept header
+	localVarHTTPHeaderAccepts := []string{"application/json"}
+
+	// set Accept header
+	localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
+	if localVarHTTPHeaderAccept != "" {
+		localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
+	}
+	// body params
+	localVarPostBody = &createRepresentative
+	r, err := a.client.prepareRequest(ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes)
+	if err != nil {
+		return nil, err
+	}
+
+	localVarHTTPResponse, err := a.client.callAPI(r)
+	if err != nil || localVarHTTPResponse == nil {
+		return localVarHTTPResponse, err
+	}
+
+	localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
+	localVarHTTPResponse.Body.Close()
+	if err != nil {
+		return localVarHTTPResponse, err
+	}
+
+	if localVarHTTPResponse.StatusCode >= 300 {
+		newErr := GenericOpenAPIError{
+			body:  localVarBody,
+			error: localVarHTTPResponse.Status,
+		}
+		if localVarHTTPResponse.StatusCode == 400 {
+			var v Error
+			err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
+			if err != nil {
+				newErr.error = err.Error()
+				return localVarHTTPResponse, newErr
+			}
+			newErr.model = v
+		}
+		return localVarHTTPResponse, newErr
+	}
+
+	return localVarHTTPResponse, nil
+}
+
+/*
+UpdateRepresentativeAddress Update Customer Representative Address
+Updates the specified customer representative address
+ * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param customerID Customer ID
+ * @param representativeID Customer Representative ID
+ * @param addressID Address ID
+ * @param updateAddress
+*/
+func (a *RepresentativesApiService) UpdateRepresentativeAddress(ctx _context.Context, customerID string, representativeID string, addressID string, updateAddress UpdateAddress) (*_nethttp.Response, error) {
+	var (
+		localVarHTTPMethod   = _nethttp.MethodPut
+		localVarPostBody     interface{}
+		localVarFormFileName string
+		localVarFileName     string
+		localVarFileBytes    []byte
+	)
+
+	// create path and map variables
+	localVarPath := a.client.cfg.BasePath + "/customers/{customerID}/representatives/{representativeID}/addresses/{addressID}"
+	localVarPath = strings.Replace(localVarPath, "{"+"customerID"+"}", _neturl.QueryEscape(parameterToString(customerID, "")), -1)
+
+	localVarPath = strings.Replace(localVarPath, "{"+"representativeID"+"}", _neturl.QueryEscape(parameterToString(representativeID, "")), -1)
+
+	localVarPath = strings.Replace(localVarPath, "{"+"addressID"+"}", _neturl.QueryEscape(parameterToString(addressID, "")), -1)
+
+	localVarHeaderParams := make(map[string]string)
+	localVarQueryParams := _neturl.Values{}
+	localVarFormParams := _neturl.Values{}
+
+	// to determine the Content-Type header
+	localVarHTTPContentTypes := []string{"application/json"}
+
+	// set Content-Type header
+	localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
+	if localVarHTTPContentType != "" {
+		localVarHeaderParams["Content-Type"] = localVarHTTPContentType
+	}
+
+	// to determine the Accept header
+	localVarHTTPHeaderAccepts := []string{"application/json"}
+
+	// set Accept header
+	localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
+	if localVarHTTPHeaderAccept != "" {
+		localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
+	}
+	// body params
+	localVarPostBody = &updateAddress
+	r, err := a.client.prepareRequest(ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes)
+	if err != nil {
+		return nil, err
+	}
+
+	localVarHTTPResponse, err := a.client.callAPI(r)
+	if err != nil || localVarHTTPResponse == nil {
+		return localVarHTTPResponse, err
+	}
+
+	localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
+	localVarHTTPResponse.Body.Close()
+	if err != nil {
+		return localVarHTTPResponse, err
+	}
+
+	if localVarHTTPResponse.StatusCode >= 300 {
+		newErr := GenericOpenAPIError{
+			body:  localVarBody,
+			error: localVarHTTPResponse.Status,
+		}
+		if localVarHTTPResponse.StatusCode == 400 {
+			var v Error
+			err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
+			if err != nil {
+				newErr.error = err.Error()
+				return localVarHTTPResponse, newErr
+			}
+			newErr.model = v
+		}
+		return localVarHTTPResponse, newErr
+	}
+
+	return localVarHTTPResponse, nil
+}
diff --git a/pkg/client/client.go b/pkg/client/client.go
index f5b87fa..03f45c6 100644
--- a/pkg/client/client.go
+++ b/pkg/client/client.go
@@ -61,6 +61,8 @@ type APIClient struct {
 	DocumentsApi *DocumentsApiService
 
 	ReportsApi *ReportsApiService
+
+	RepresentativesApi *RepresentativesApiService
 }
 
 type service struct {
@@ -86,6 +88,7 @@ func NewAPIClient(cfg *Configuration) *APIClient {
 	c.DisclaimersApi = (*DisclaimersApiService)(&c.common)
 	c.DocumentsApi = (*DocumentsApiService)(&c.common)
 	c.ReportsApi = (*ReportsApiService)(&c.common)
+	c.RepresentativesApi = (*RepresentativesApiService)(&c.common)
 
 	return c
 }
diff --git a/pkg/client/docs/CustomerAddress.md b/pkg/client/docs/Address.md
similarity index 91%
rename from pkg/client/docs/CustomerAddress.md
rename to pkg/client/docs/Address.md
index c732f10..27a4b87 100644
--- a/pkg/client/docs/CustomerAddress.md
+++ b/pkg/client/docs/Address.md
@@ -1,4 +1,4 @@
-# CustomerAddress
+# Address
 
 ## Properties
 
@@ -6,6 +6,7 @@ Name | Type | Description | Notes
 ------------ | ------------- | ------------- | -------------
 **AddressID** | **string** | Unique identifier for this Address | 
 **Type** | [**AddressType**](AddressType.md) |  | 
+**OwnerType** | [**OwnerType**](OwnerType.md) |  | [optional] 
 **Address1** | **string** | First line of the address | 
 **Address2** | **string** | Second line of the address | [optional] 
 **City** | **string** |  | 
diff --git a/pkg/client/docs/BusinessType.md b/pkg/client/docs/BusinessType.md
new file mode 100644
index 0000000..7cedd26
--- /dev/null
+++ b/pkg/client/docs/BusinessType.md
@@ -0,0 +1,10 @@
+# BusinessType
+
+## Properties
+
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/pkg/client/docs/CreateCustomerAddress.md b/pkg/client/docs/CreateAddress.md
similarity index 96%
rename from pkg/client/docs/CreateCustomerAddress.md
rename to pkg/client/docs/CreateAddress.md
index 5811100..eff195b 100644
--- a/pkg/client/docs/CreateCustomerAddress.md
+++ b/pkg/client/docs/CreateAddress.md
@@ -1,4 +1,4 @@
-# CreateCustomerAddress
+# CreateAddress
 
 ## Properties
 
diff --git a/pkg/client/docs/CreateCustomer.md b/pkg/client/docs/CreateCustomer.md
index 026d4cd..8594ae7 100644
--- a/pkg/client/docs/CreateCustomer.md
+++ b/pkg/client/docs/CreateCustomer.md
@@ -10,11 +10,21 @@ Name | Type | Description | Notes
 **NickName** | **string** | Name Customer is preferred to be called | [optional] 
 **Suffix** | **string** | Customers name suffix. \&quot;Jr\&quot;, \&quot;PH.D.\&quot; | [optional] 
 **Type** | [**CustomerType**](CustomerType.md) |  | 
+**BusinessName** | **string** | Business Name for business type customers | [optional] 
+**DoingBusinessAs** | **string** | Doing Business As (DBA) name for business type customers | [optional] 
+**BusinessType** | [**BusinessType**](BusinessType.md) |  | [optional] 
+**EIN** | **string** | Employer Identification Number (EIN) for business type customers | [optional] 
+**DUNS** | **string** | Dun &amp; Bradstreet D-U-N-S Number (D-U-N-S) for business type customers | [optional] 
+**SICCode** | [**SicCode**](SICCode.md) |  | [optional] 
+**NAICSCode** | [**NaicsCode**](NAICSCode.md) |  | [optional] 
 **BirthDate** | **string** | Legal date of birth | [optional] 
 **Email** | **string** | Primary email address of customer name@domain.com | 
 **SSN** | **string** | Customer Social Security Number (SSN) | [optional] 
+**Website** | **string** | Company Website for business type customers | [optional] 
+**DateBusinessEstablished** | **string** | Date business was established for business type customers | [optional] 
 **Phones** | [**[]CreatePhone**](CreatePhone.md) |  | [optional] 
-**Addresses** | [**[]CreateCustomerAddress**](CreateCustomerAddress.md) |  | [optional] 
+**Addresses** | [**[]CreateAddress**](CreateAddress.md) |  | [optional] 
+**Representatives** | [**[]CreateRepresentative**](CreateRepresentative.md) |  | [optional] 
 **Metadata** | **map[string]string** | Map of unique keys associated to values to act as foreign key relationships or arbitrary data associated to a Customer. | [optional] 
 
 [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
diff --git a/pkg/client/docs/CreateRepresentative.md b/pkg/client/docs/CreateRepresentative.md
new file mode 100644
index 0000000..ae46d8f
--- /dev/null
+++ b/pkg/client/docs/CreateRepresentative.md
@@ -0,0 +1,17 @@
+# CreateRepresentative
+
+## Properties
+
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**FirstName** | **string** | Given Name or First Name | 
+**LastName** | **string** | Surname or Last Name | 
+**JobTitle** | **string** | Job title of this representative | [optional] 
+**BirthDate** | **string** | Legal date of birth | [optional] 
+**SSN** | **string** | Customer Representative&#39;s Social Security Number (SSN) | [optional] 
+**Phones** | [**[]CreatePhone**](CreatePhone.md) |  | [optional] 
+**Addresses** | [**[]CreateAddress**](CreateAddress.md) |  | [optional] 
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/pkg/client/docs/Customer.md b/pkg/client/docs/Customer.md
index 2ffb0d2..c81406a 100644
--- a/pkg/client/docs/Customer.md
+++ b/pkg/client/docs/Customer.md
@@ -11,11 +11,21 @@ Name | Type | Description | Notes
 **NickName** | **string** | Name Customer is preferred to be called | [optional] 
 **Suffix** | **string** | Customers name suffix. \&quot;Jr\&quot;, \&quot;PH.D.\&quot; | [optional] 
 **Type** | [**CustomerType**](CustomerType.md) |  | 
+**BusinessName** | **string** | Business Name for business type customers | [optional] 
+**DoingBusinessAs** | **string** | Doing Business As (DBA) name for business type customers | [optional] 
+**BusinessType** | [**BusinessType**](BusinessType.md) |  | [optional] 
+**EIN** | **string** | Employer Identification Number (EIN) for business type customers | [optional] 
+**DUNS** | **string** | Dun &amp; Bradstreet D-U-N-S Number (D-U-N-S) for business type customers | [optional] 
+**SICCode** | [**SicCode**](SICCode.md) |  | [optional] 
+**NAICSCode** | [**NaicsCode**](NAICSCode.md) |  | [optional] 
 **BirthDate** | **string** | Legal date of birth | [optional] 
 **Status** | [**CustomerStatus**](CustomerStatus.md) |  | 
 **Email** | **string** | Primary email address of customer name@domain.com | 
+**Website** | **string** | Company Website for business type customers | [optional] 
+**DateBusinessEstablished** | **string** | Date business was established for business type customers | [optional] 
 **Phones** | [**[]Phone**](Phone.md) |  | [optional] 
-**Addresses** | [**[]CustomerAddress**](CustomerAddress.md) |  | [optional] 
+**Addresses** | [**[]Address**](Address.md) |  | [optional] 
+**Representatives** | [**[]Representative**](Representative.md) |  | [optional] 
 **Metadata** | **map[string]string** | Map of unique keys associated to values to act as foreign key relationships or arbitrary data associated to a Customer. | [optional] 
 **CreatedAt** | [**time.Time**](time.Time.md) |  | 
 **LastModified** | [**time.Time**](time.Time.md) | Last time the object was modified | 
diff --git a/pkg/client/docs/CustomersApi.md b/pkg/client/docs/CustomersApi.md
index 6d36a8f..35ab55a 100644
--- a/pkg/client/docs/CustomersApi.md
+++ b/pkg/client/docs/CustomersApi.md
@@ -4,25 +4,25 @@ All URIs are relative to *http://localhost:8087*
 
 Method | HTTP request | Description
 ------------- | ------------- | -------------
-[**AddCustomerAddress**](CustomersApi.md#AddCustomerAddress) | **Post** /customers/{customerID}/address | Add Customer Address
+[**AddAddress**](CustomersApi.md#AddAddress) | **Post** /customers/{customerID}/address | Add Customer Address
 [**CreateCustomer**](CustomersApi.md#CreateCustomer) | **Post** /customers | Create Customer
+[**DeleteAddress**](CustomersApi.md#DeleteAddress) | **Delete** /customers/{customerID}/addresses/{addressID} | Delete Customer Address
 [**DeleteCustomer**](CustomersApi.md#DeleteCustomer) | **Delete** /customers/{customerID} | Delete Customer
-[**DeleteCustomerAddress**](CustomersApi.md#DeleteCustomerAddress) | **Delete** /customers/{customerID}/addresses/{addressID} | Delete Customer Address
 [**GetCustomer**](CustomersApi.md#GetCustomer) | **Get** /customers/{customerID} | Get Customer
 [**GetLatestOFACSearch**](CustomersApi.md#GetLatestOFACSearch) | **Get** /customers/{customerID}/ofac | Latest Customer OFAC search
 [**Ping**](CustomersApi.md#Ping) | **Get** /ping | Ping Customers Service
 [**RefreshOFACSearch**](CustomersApi.md#RefreshOFACSearch) | **Put** /customers/{customerID}/refresh/ofac | Refresh Customer OFAC search
 [**ReplaceCustomerMetadata**](CustomersApi.md#ReplaceCustomerMetadata) | **Put** /customers/{customerID}/metadata | Update Customer Metadata
 [**SearchCustomers**](CustomersApi.md#SearchCustomers) | **Get** /customers | Search Customers
+[**UpdateAddress**](CustomersApi.md#UpdateAddress) | **Put** /customers/{customerID}/addresses/{addressID} | Update Customer Address
 [**UpdateCustomer**](CustomersApi.md#UpdateCustomer) | **Put** /customers/{customerID} | Update Customer
-[**UpdateCustomerAddress**](CustomersApi.md#UpdateCustomerAddress) | **Put** /customers/{customerID}/addresses/{addressID} | Update Customer Address
 [**UpdateCustomerStatus**](CustomersApi.md#UpdateCustomerStatus) | **Put** /customers/{customerID}/status | Update Customer Status
 
 
 
-## AddCustomerAddress
+## AddAddress
 
-> Customer AddCustomerAddress(ctx, customerID, createCustomerAddress, optional)
+> Customer AddAddress(ctx, customerID, createAddress, optional)
 
 Add Customer Address
 
@@ -35,12 +35,12 @@ Name | Type | Description  | Notes
 ------------- | ------------- | ------------- | -------------
 **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc.
 **customerID** | **string**| customerID of the Customer to add the address onto | 
-**createCustomerAddress** | [**CreateCustomerAddress**](CreateCustomerAddress.md)|  | 
- **optional** | ***AddCustomerAddressOpts** | optional parameters | nil if no parameters
+**createAddress** | [**CreateAddress**](CreateAddress.md)|  | 
+ **optional** | ***AddAddressOpts** | optional parameters | nil if no parameters
 
 ### Optional Parameters
 
-Optional parameters are passed through a pointer to a AddCustomerAddressOpts struct
+Optional parameters are passed through a pointer to a AddAddressOpts struct
 
 
 Name | Type | Description  | Notes
@@ -114,13 +114,13 @@ No authorization required
 [[Back to README]](../README.md)
 
 
-## DeleteCustomer
+## DeleteAddress
 
-> DeleteCustomer(ctx, customerID, optional)
+> DeleteAddress(ctx, customerID, addressID)
 
-Delete Customer
+Delete Customer Address
 
-Remove a given Customer
+Deletes a customer's address
 
 ### Required Parameters
 
@@ -128,19 +128,8 @@ Remove a given Customer
 Name | Type | Description  | Notes
 ------------- | ------------- | ------------- | -------------
 **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc.
-**customerID** | **string**| customerID of the Customer to be deleted | 
- **optional** | ***DeleteCustomerOpts** | optional parameters | nil if no parameters
-
-### Optional Parameters
-
-Optional parameters are passed through a pointer to a DeleteCustomerOpts struct
-
-
-Name | Type | Description  | Notes
-------------- | ------------- | ------------- | -------------
-
- **xRequestID** | **optional.String**| Optional requestID allows application developer to trace requests through the systems logs | 
- **xOrganization** | **optional.String**| Value used to separate and identify models | 
+**customerID** | **string**| Customer ID | 
+**addressID** | **string**| Address ID | 
 
 ### Return type
 
@@ -153,20 +142,20 @@ No authorization required
 ### HTTP request headers
 
 - **Content-Type**: Not defined
-- **Accept**: Not defined
+- **Accept**: application/json
 
 [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints)
 [[Back to Model list]](../README.md#documentation-for-models)
 [[Back to README]](../README.md)
 
 
-## DeleteCustomerAddress
+## DeleteCustomer
 
-> DeleteCustomerAddress(ctx, customerID, addressID)
+> DeleteCustomer(ctx, customerID, optional)
 
-Delete Customer Address
+Delete Customer
 
-Deletes a customer's address
+Remove a given Customer
 
 ### Required Parameters
 
@@ -174,8 +163,19 @@ Deletes a customer's address
 Name | Type | Description  | Notes
 ------------- | ------------- | ------------- | -------------
 **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc.
-**customerID** | **string**| Customer ID | 
-**addressID** | **string**| Address ID | 
+**customerID** | **string**| customerID of the Customer to be deleted | 
+ **optional** | ***DeleteCustomerOpts** | optional parameters | nil if no parameters
+
+### Optional Parameters
+
+Optional parameters are passed through a pointer to a DeleteCustomerOpts struct
+
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+
+ **xRequestID** | **optional.String**| Optional requestID allows application developer to trace requests through the systems logs | 
+ **xOrganization** | **optional.String**| Value used to separate and identify models | 
 
 ### Return type
 
@@ -188,7 +188,7 @@ No authorization required
 ### HTTP request headers
 
 - **Content-Type**: Not defined
-- **Accept**: application/json
+- **Accept**: Not defined
 
 [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints)
 [[Back to Model list]](../README.md#documentation-for-models)
@@ -460,13 +460,13 @@ No authorization required
 [[Back to README]](../README.md)
 
 
-## UpdateCustomer
+## UpdateAddress
 
-> Customer UpdateCustomer(ctx, customerID, createCustomer, optional)
+> UpdateAddress(ctx, customerID, addressID, updateAddress)
 
-Update Customer
+Update Customer Address
 
-Update a Customer object
+Updates the specified customer address
 
 ### Required Parameters
 
@@ -474,25 +474,13 @@ Update a Customer object
 Name | Type | Description  | Notes
 ------------- | ------------- | ------------- | -------------
 **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc.
-**customerID** | **string**| customerID that identifies this Customer | 
-**createCustomer** | [**CreateCustomer**](CreateCustomer.md)|  | 
- **optional** | ***UpdateCustomerOpts** | optional parameters | nil if no parameters
-
-### Optional Parameters
-
-Optional parameters are passed through a pointer to a UpdateCustomerOpts struct
-
-
-Name | Type | Description  | Notes
-------------- | ------------- | ------------- | -------------
-
-
- **xRequestID** | **optional.String**| Optional requestID allows application developer to trace requests through the systems logs | 
- **xOrganization** | **optional.String**| Value used to separate and identify models | 
+**customerID** | **string**| Customer ID | 
+**addressID** | **string**| Address ID | 
+**updateAddress** | [**UpdateAddress**](UpdateAddress.md)|  | 
 
 ### Return type
 
-[**Customer**](Customer.md)
+ (empty response body)
 
 ### Authorization
 
@@ -508,13 +496,13 @@ No authorization required
 [[Back to README]](../README.md)
 
 
-## UpdateCustomerAddress
+## UpdateCustomer
 
-> UpdateCustomerAddress(ctx, customerID, addressID, updateCustomerAddress)
+> Customer UpdateCustomer(ctx, customerID, createCustomer, optional)
 
-Update Customer Address
+Update Customer
 
-Updates the specified customer address
+Update a Customer object
 
 ### Required Parameters
 
@@ -522,13 +510,25 @@ Updates the specified customer address
 Name | Type | Description  | Notes
 ------------- | ------------- | ------------- | -------------
 **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc.
-**customerID** | **string**| Customer ID | 
-**addressID** | **string**| Address ID | 
-**updateCustomerAddress** | [**UpdateCustomerAddress**](UpdateCustomerAddress.md)|  | 
+**customerID** | **string**| customerID that identifies this Customer | 
+**createCustomer** | [**CreateCustomer**](CreateCustomer.md)|  | 
+ **optional** | ***UpdateCustomerOpts** | optional parameters | nil if no parameters
+
+### Optional Parameters
+
+Optional parameters are passed through a pointer to a UpdateCustomerOpts struct
+
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+
+
+ **xRequestID** | **optional.String**| Optional requestID allows application developer to trace requests through the systems logs | 
+ **xOrganization** | **optional.String**| Value used to separate and identify models | 
 
 ### Return type
 
- (empty response body)
+[**Customer**](Customer.md)
 
 ### Authorization
 
diff --git a/pkg/client/docs/NaicsCode.md b/pkg/client/docs/NaicsCode.md
new file mode 100644
index 0000000..e269a6b
--- /dev/null
+++ b/pkg/client/docs/NaicsCode.md
@@ -0,0 +1,10 @@
+# NaicsCode
+
+## Properties
+
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/pkg/client/docs/OwnerType.md b/pkg/client/docs/OwnerType.md
new file mode 100644
index 0000000..7885d38
--- /dev/null
+++ b/pkg/client/docs/OwnerType.md
@@ -0,0 +1,10 @@
+# OwnerType
+
+## Properties
+
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/pkg/client/docs/Phone.md b/pkg/client/docs/Phone.md
index 3abfe0a..e52a42b 100644
--- a/pkg/client/docs/Phone.md
+++ b/pkg/client/docs/Phone.md
@@ -5,6 +5,7 @@
 Name | Type | Description | Notes
 ------------ | ------------- | ------------- | -------------
 **Number** | **string** | phone number | 
+**OwnerType** | [**OwnerType**](OwnerType.md) |  | [optional] 
 **Valid** | **bool** | phone number has been validated to connect with customer | 
 **Type** | [**PhoneType**](PhoneType.md) |  | 
 
diff --git a/pkg/client/docs/Representative.md b/pkg/client/docs/Representative.md
new file mode 100644
index 0000000..74007d6
--- /dev/null
+++ b/pkg/client/docs/Representative.md
@@ -0,0 +1,21 @@
+# Representative
+
+## Properties
+
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**RepresentativeID** | **string** | Unique identifier for this Representative | 
+**CustomerID** | **string** | The unique identifier for the customer the representative belongs to | 
+**FirstName** | **string** | Given Name or First Name | 
+**LastName** | **string** | Surname or Last Name | 
+**JobTitle** | **string** | Job title of this representative | [optional] 
+**BirthDate** | **string** | Legal date of birth | [optional] 
+**CreatedAt** | [**time.Time**](time.Time.md) |  | 
+**LastModified** | [**time.Time**](time.Time.md) | Last time the object was modified | 
+**SSN** | **string** | Customer Representative&#39;s Social Security Number (SSN) | [optional] 
+**Phones** | [**[]Phone**](Phone.md) |  | [optional] 
+**Addresses** | [**[]Address**](Address.md) |  | [optional] 
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/pkg/client/docs/RepresentativesApi.md b/pkg/client/docs/RepresentativesApi.md
new file mode 100644
index 0000000..820df1e
--- /dev/null
+++ b/pkg/client/docs/RepresentativesApi.md
@@ -0,0 +1,246 @@
+# \RepresentativesApi
+
+All URIs are relative to *http://localhost:8087*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**AddRepresentative**](RepresentativesApi.md#AddRepresentative) | **Post** /customers/{customerID}/representatives | Add Customer Representative
+[**AddRepresentativeAddress**](RepresentativesApi.md#AddRepresentativeAddress) | **Post** /customers/{customerID}/representatives/{representativeID}/address | Add Customer Representative Address
+[**DeleteRepresentative**](RepresentativesApi.md#DeleteRepresentative) | **Delete** /customers/{customerID}/representatives/{representativeID} | Delete Customer Representative
+[**DeleteRepresentativeAddress**](RepresentativesApi.md#DeleteRepresentativeAddress) | **Delete** /customers/{customerID}/representatives/{representativeID}/addresses/{addressID} | Delete a Customer Representative Address
+[**UpdateRepresentative**](RepresentativesApi.md#UpdateRepresentative) | **Put** /customers/{customerID}/representatives/{representativeID} | Update Customer Representative
+[**UpdateRepresentativeAddress**](RepresentativesApi.md#UpdateRepresentativeAddress) | **Put** /customers/{customerID}/representatives/{representativeID}/addresses/{addressID} | Update Customer Representative Address
+
+
+
+## AddRepresentative
+
+> Customer AddRepresentative(ctx, xRequestID, xOrganization, customerID, createRepresentative)
+
+Add Customer Representative
+
+Add a Customer Representative
+
+### Required Parameters
+
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc.
+**xRequestID** | **string**| Optional requestID allows application developer to trace requests through the systems logs | 
+**xOrganization** | **string**| Value used to separate and identify models | 
+**customerID** | **string**| customerID of the Customer for whom to add the representative | 
+**createRepresentative** | [**CreateRepresentative**](CreateRepresentative.md)|  | 
+
+### Return type
+
+[**Customer**](Customer.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: application/json
+- **Accept**: application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints)
+[[Back to Model list]](../README.md#documentation-for-models)
+[[Back to README]](../README.md)
+
+
+## AddRepresentativeAddress
+
+> Representative AddRepresentativeAddress(ctx, xOrganization, customerID, representativeID, createAddress, optional)
+
+Add Customer Representative Address
+
+Add an address to an existing customer representative record
+
+### Required Parameters
+
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc.
+**xOrganization** | **string**| Value used to separate and identify models | 
+**customerID** | **string**| customerID of the Customer to add the address onto | 
+**representativeID** | **string**| representativeID of the Customer representative for whom to add the address | 
+**createAddress** | [**CreateAddress**](CreateAddress.md)|  | 
+ **optional** | ***AddRepresentativeAddressOpts** | optional parameters | nil if no parameters
+
+### Optional Parameters
+
+Optional parameters are passed through a pointer to a AddRepresentativeAddressOpts struct
+
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+
+
+
+
+ **xRequestID** | **optional.String**| Optional requestID allows application developer to trace requests through the systems logs | 
+
+### Return type
+
+[**Representative**](Representative.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: application/json
+- **Accept**: application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints)
+[[Back to Model list]](../README.md#documentation-for-models)
+[[Back to README]](../README.md)
+
+
+## DeleteRepresentative
+
+> DeleteRepresentative(ctx, customerID, representativeID)
+
+Delete Customer Representative
+
+Deletes a Customer Representative
+
+### Required Parameters
+
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc.
+**customerID** | **string**| Customer ID | 
+**representativeID** | **string**| Representative ID | 
+
+### Return type
+
+ (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints)
+[[Back to Model list]](../README.md#documentation-for-models)
+[[Back to README]](../README.md)
+
+
+## DeleteRepresentativeAddress
+
+> DeleteRepresentativeAddress(ctx, customerID, representativeID, addressID)
+
+Delete a Customer Representative Address
+
+Deletes a customer representative's address
+
+### Required Parameters
+
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc.
+**customerID** | **string**| Customer ID | 
+**representativeID** | **string**| Customer Representative ID | 
+**addressID** | **string**| Address ID | 
+
+### Return type
+
+ (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints)
+[[Back to Model list]](../README.md#documentation-for-models)
+[[Back to README]](../README.md)
+
+
+## UpdateRepresentative
+
+> UpdateRepresentative(ctx, customerID, representativeID, createRepresentative)
+
+Update Customer Representative
+
+Updates the specified Customer Representative
+
+### Required Parameters
+
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc.
+**customerID** | **string**| Customer ID | 
+**representativeID** | **string**| Representative ID | 
+**createRepresentative** | [**CreateRepresentative**](CreateRepresentative.md)|  | 
+
+### Return type
+
+ (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: application/json
+- **Accept**: application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints)
+[[Back to Model list]](../README.md#documentation-for-models)
+[[Back to README]](../README.md)
+
+
+## UpdateRepresentativeAddress
+
+> UpdateRepresentativeAddress(ctx, customerID, representativeID, addressID, updateAddress)
+
+Update Customer Representative Address
+
+Updates the specified customer representative address
+
+### Required Parameters
+
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc.
+**customerID** | **string**| Customer ID | 
+**representativeID** | **string**| Customer Representative ID | 
+**addressID** | **string**| Address ID | 
+**updateAddress** | [**UpdateAddress**](UpdateAddress.md)|  | 
+
+### Return type
+
+ (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: application/json
+- **Accept**: application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints)
+[[Back to Model list]](../README.md#documentation-for-models)
+[[Back to README]](../README.md)
+
diff --git a/pkg/client/docs/SicCode.md b/pkg/client/docs/SicCode.md
new file mode 100644
index 0000000..a4040da
--- /dev/null
+++ b/pkg/client/docs/SicCode.md
@@ -0,0 +1,10 @@
+# SicCode
+
+## Properties
+
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/pkg/client/docs/UpdateCustomerAddress.md b/pkg/client/docs/UpdateAddress.md
similarity index 96%
rename from pkg/client/docs/UpdateCustomerAddress.md
rename to pkg/client/docs/UpdateAddress.md
index 0bdb082..ea3b68f 100644
--- a/pkg/client/docs/UpdateCustomerAddress.md
+++ b/pkg/client/docs/UpdateAddress.md
@@ -1,4 +1,4 @@
-# UpdateCustomerAddress
+# UpdateAddress
 
 ## Properties
 
diff --git a/pkg/client/model_customer_address.go b/pkg/client/model_address.go
similarity index 94%
rename from pkg/client/model_customer_address.go
rename to pkg/client/model_address.go
index f3e8a8d..8da0b26 100644
--- a/pkg/client/model_customer_address.go
+++ b/pkg/client/model_address.go
@@ -9,11 +9,12 @@
 
 package client
 
-// CustomerAddress struct for CustomerAddress
-type CustomerAddress struct {
+// Address struct for Address
+type Address struct {
 	// Unique identifier for this Address
 	AddressID string      `json:"addressID"`
 	Type      AddressType `json:"type"`
+	OwnerType OwnerType   `json:"ownerType,omitempty"`
 	// First line of the address
 	Address1 string `json:"address1"`
 	// Second line of the address
diff --git a/pkg/client/model_business_type.go b/pkg/client/model_business_type.go
new file mode 100644
index 0000000..d25921f
--- /dev/null
+++ b/pkg/client/model_business_type.go
@@ -0,0 +1,22 @@
+/*
+ * Customers API
+ *
+ * Customers focuses on solving authentic identification of humans who are legally able to hold and transfer currency within the US. Primarily this project solves [Know Your Customer](https://en.wikipedia.org/wiki/Know_your_customer) (KYC), [Customer Identification Program](https://en.wikipedia.org/wiki/Customer_Identification_Program) (CIP), [Office of Foreign Asset Control](https://www.treasury.gov/about/organizational-structure/offices/Pages/Office-of-Foreign-Assets-Control.aspx) (OFAC) checks and verification workflows to comply with United States federal law and ensure authentic transfers. Customers has an objective to be a service for detailed due diligence on individuals and companies for Financial Institutions and services in a modernized and extensible way.  Customer phone numbers and addresses are stored and partially used in KYC/OFAC validation. Arbitrary key/value pairs can be stored for a Customer. Documents and Disclaimers, and their acknowledgment are also stored under a Customer as they're accepted. Bank Accounts, which can be validated with micro-deposits currently, are stored under each Customer.  ![](https://raw.githubusercontent.com/adamdecaf/customers/create-accounts/docs/images/customer.png)
+ *
+ * API version: v1
+ * Generated by: OpenAPI Generator (https://openapi-generator.tech)
+ */
+
+package client
+
+// BusinessType The type of business for business customers
+type BusinessType string
+
+// List of BusinessType
+const (
+	BUSINESSTYPE_INDIVIDUAL_SOLE_PROPRIETOR_OR_SINGLE_MEMBER_LLC BusinessType = "individual, sole proprietor, or single-member LLC"
+	BUSINESSTYPE_CORPORATION                                     BusinessType = "corporation"
+	BUSINESSTYPE_NON_PROFIT_ORGANIZATION                         BusinessType = "non-profit organization"
+	BUSINESSTYPE_PARTNERSHIP                                     BusinessType = "partnership"
+	BUSINESSTYPE_LIMITED_LIABILITY_COMPANY                       BusinessType = "limited liability company"
+)
diff --git a/pkg/client/model_create_customer_address.go b/pkg/client/model_create_address.go
similarity index 94%
rename from pkg/client/model_create_customer_address.go
rename to pkg/client/model_create_address.go
index f82ecf9..297dd24 100644
--- a/pkg/client/model_create_customer_address.go
+++ b/pkg/client/model_create_address.go
@@ -9,8 +9,8 @@
 
 package client
 
-// CreateCustomerAddress struct for CreateCustomerAddress
-type CreateCustomerAddress struct {
+// CreateAddress struct for CreateAddress
+type CreateAddress struct {
 	Type string `json:"type"`
 	// First line of the address
 	Address1 string `json:"address1"`
diff --git a/pkg/client/model_create_customer.go b/pkg/client/model_create_customer.go
index c163f3f..695707c 100644
--- a/pkg/client/model_create_customer.go
+++ b/pkg/client/model_create_customer.go
@@ -22,14 +22,30 @@ type CreateCustomer struct {
 	// Customers name suffix. \"Jr\", \"PH.D.\"
 	Suffix string       `json:"suffix,omitempty"`
 	Type   CustomerType `json:"type"`
+	// Business Name for business type customers
+	BusinessName string `json:"businessName,omitempty"`
+	// Doing Business As (DBA) name for business type customers
+	DoingBusinessAs string       `json:"doingBusinessAs,omitempty"`
+	BusinessType    BusinessType `json:"businessType,omitempty"`
+	// Employer Identification Number (EIN) for business type customers
+	EIN string `json:"EIN,omitempty"`
+	// Dun & Bradstreet D-U-N-S Number (D-U-N-S) for business type customers
+	DUNS      string    `json:"DUNS,omitempty"`
+	SICCode   SicCode   `json:"SICCode,omitempty"`
+	NAICSCode NaicsCode `json:"NAICSCode,omitempty"`
 	// Legal date of birth
 	BirthDate string `json:"birthDate,omitempty"`
 	// Primary email address of customer name@domain.com
 	Email string `json:"email"`
 	// Customer Social Security Number (SSN)
-	SSN       string                  `json:"SSN,omitempty"`
-	Phones    []CreatePhone           `json:"phones,omitempty"`
-	Addresses []CreateCustomerAddress `json:"addresses,omitempty"`
+	SSN string `json:"SSN,omitempty"`
+	// Company Website for business type customers
+	Website string `json:"website,omitempty"`
+	// Date business was established for business type customers
+	DateBusinessEstablished string                 `json:"dateBusinessEstablished,omitempty"`
+	Phones                  []CreatePhone          `json:"phones,omitempty"`
+	Addresses               []CreateAddress        `json:"addresses,omitempty"`
+	Representatives         []CreateRepresentative `json:"representatives,omitempty"`
 	// Map of unique keys associated to values to act as foreign key relationships or arbitrary data associated to a Customer.
 	Metadata map[string]string `json:"metadata,omitempty"`
 }
diff --git a/pkg/client/model_create_representative.go b/pkg/client/model_create_representative.go
new file mode 100644
index 0000000..4154752
--- /dev/null
+++ b/pkg/client/model_create_representative.go
@@ -0,0 +1,26 @@
+/*
+ * Customers API
+ *
+ * Customers focuses on solving authentic identification of humans who are legally able to hold and transfer currency within the US. Primarily this project solves [Know Your Customer](https://en.wikipedia.org/wiki/Know_your_customer) (KYC), [Customer Identification Program](https://en.wikipedia.org/wiki/Customer_Identification_Program) (CIP), [Office of Foreign Asset Control](https://www.treasury.gov/about/organizational-structure/offices/Pages/Office-of-Foreign-Assets-Control.aspx) (OFAC) checks and verification workflows to comply with United States federal law and ensure authentic transfers. Customers has an objective to be a service for detailed due diligence on individuals and companies for Financial Institutions and services in a modernized and extensible way.  Customer phone numbers and addresses are stored and partially used in KYC/OFAC validation. Arbitrary key/value pairs can be stored for a Customer. Documents and Disclaimers, and their acknowledgment are also stored under a Customer as they're accepted. Bank Accounts, which can be validated with micro-deposits currently, are stored under each Customer.  ![](https://raw.githubusercontent.com/adamdecaf/customers/create-accounts/docs/images/customer.png)
+ *
+ * API version: v1
+ * Generated by: OpenAPI Generator (https://openapi-generator.tech)
+ */
+
+package client
+
+// CreateRepresentative struct for CreateRepresentative
+type CreateRepresentative struct {
+	// Given Name or First Name
+	FirstName string `json:"firstName"`
+	// Surname or Last Name
+	LastName string `json:"lastName"`
+	// Job title of this representative
+	JobTitle string `json:"jobTitle,omitempty"`
+	// Legal date of birth
+	BirthDate string `json:"birthDate,omitempty"`
+	// Customer Representative's Social Security Number (SSN)
+	SSN       string          `json:"SSN,omitempty"`
+	Phones    []CreatePhone   `json:"phones,omitempty"`
+	Addresses []CreateAddress `json:"addresses,omitempty"`
+}
diff --git a/pkg/client/model_customer.go b/pkg/client/model_customer.go
index 941cc8c..81255f8 100644
--- a/pkg/client/model_customer.go
+++ b/pkg/client/model_customer.go
@@ -28,13 +28,29 @@ type Customer struct {
 	// Customers name suffix. \"Jr\", \"PH.D.\"
 	Suffix string       `json:"suffix,omitempty"`
 	Type   CustomerType `json:"type"`
+	// Business Name for business type customers
+	BusinessName string `json:"businessName,omitempty"`
+	// Doing Business As (DBA) name for business type customers
+	DoingBusinessAs string       `json:"doingBusinessAs,omitempty"`
+	BusinessType    BusinessType `json:"businessType,omitempty"`
+	// Employer Identification Number (EIN) for business type customers
+	EIN string `json:"EIN,omitempty"`
+	// Dun & Bradstreet D-U-N-S Number (D-U-N-S) for business type customers
+	DUNS      string    `json:"DUNS,omitempty"`
+	SICCode   SicCode   `json:"SICCode,omitempty"`
+	NAICSCode NaicsCode `json:"NAICSCode,omitempty"`
 	// Legal date of birth
 	BirthDate string         `json:"birthDate,omitempty"`
 	Status    CustomerStatus `json:"status"`
 	// Primary email address of customer name@domain.com
-	Email     string            `json:"email"`
-	Phones    []Phone           `json:"phones,omitempty"`
-	Addresses []CustomerAddress `json:"addresses,omitempty"`
+	Email string `json:"email"`
+	// Company Website for business type customers
+	Website string `json:"website,omitempty"`
+	// Date business was established for business type customers
+	DateBusinessEstablished string           `json:"dateBusinessEstablished,omitempty"`
+	Phones                  []Phone          `json:"phones,omitempty"`
+	Addresses               []Address        `json:"addresses,omitempty"`
+	Representatives         []Representative `json:"representatives,omitempty"`
 	// Map of unique keys associated to values to act as foreign key relationships or arbitrary data associated to a Customer.
 	Metadata  map[string]string `json:"metadata,omitempty"`
 	CreatedAt time.Time         `json:"createdAt"`
diff --git a/pkg/client/model_naics_code.go b/pkg/client/model_naics_code.go
new file mode 100644
index 0000000..e8ecf72
--- /dev/null
+++ b/pkg/client/model_naics_code.go
@@ -0,0 +1,42 @@
+/*
+ * Customers API
+ *
+ * Customers focuses on solving authentic identification of humans who are legally able to hold and transfer currency within the US. Primarily this project solves [Know Your Customer](https://en.wikipedia.org/wiki/Know_your_customer) (KYC), [Customer Identification Program](https://en.wikipedia.org/wiki/Customer_Identification_Program) (CIP), [Office of Foreign Asset Control](https://www.treasury.gov/about/organizational-structure/offices/Pages/Office-of-Foreign-Assets-Control.aspx) (OFAC) checks and verification workflows to comply with United States federal law and ensure authentic transfers. Customers has an objective to be a service for detailed due diligence on individuals and companies for Financial Institutions and services in a modernized and extensible way.  Customer phone numbers and addresses are stored and partially used in KYC/OFAC validation. Arbitrary key/value pairs can be stored for a Customer. Documents and Disclaimers, and their acknowledgment are also stored under a Customer as they're accepted. Bank Accounts, which can be validated with micro-deposits currently, are stored under each Customer.  ![](https://raw.githubusercontent.com/adamdecaf/customers/create-accounts/docs/images/customer.png)
+ *
+ * API version: v1
+ * Generated by: OpenAPI Generator (https://openapi-generator.tech)
+ */
+
+package client
+
+// NaicsCode NAICS Code (https://docs.google.com/spreadsheets/d/1erIdqoy60JwLAnpb91EfoJV5YrXDnbwSaA-aqcBlw48/edit#gid=1627409140)
+type NaicsCode string
+
+// List of NAICSCode
+const (
+	NAICSCODE__11 NaicsCode = "11"
+	NAICSCODE__21 NaicsCode = "21"
+	NAICSCODE__22 NaicsCode = "22"
+	NAICSCODE__23 NaicsCode = "23"
+	NAICSCODE__31 NaicsCode = "31"
+	NAICSCODE__32 NaicsCode = "32"
+	NAICSCODE__33 NaicsCode = "33"
+	NAICSCODE__42 NaicsCode = "42"
+	NAICSCODE__44 NaicsCode = "44"
+	NAICSCODE__45 NaicsCode = "45"
+	NAICSCODE__48 NaicsCode = "48"
+	NAICSCODE__49 NaicsCode = "49"
+	NAICSCODE__51 NaicsCode = "51"
+	NAICSCODE__52 NaicsCode = "52"
+	NAICSCODE__53 NaicsCode = "53"
+	NAICSCODE__54 NaicsCode = "54"
+	NAICSCODE__55 NaicsCode = "55"
+	NAICSCODE__56 NaicsCode = "56"
+	NAICSCODE__61 NaicsCode = "61"
+	NAICSCODE__62 NaicsCode = "62"
+	NAICSCODE__71 NaicsCode = "71"
+	NAICSCODE__72 NaicsCode = "72"
+	NAICSCODE__81 NaicsCode = "81"
+	NAICSCODE__92 NaicsCode = "92"
+	NAICSCODE__99 NaicsCode = "99"
+)
diff --git a/pkg/client/model_owner_type.go b/pkg/client/model_owner_type.go
new file mode 100644
index 0000000..553e4d0
--- /dev/null
+++ b/pkg/client/model_owner_type.go
@@ -0,0 +1,19 @@
+/*
+ * Customers API
+ *
+ * Customers focuses on solving authentic identification of humans who are legally able to hold and transfer currency within the US. Primarily this project solves [Know Your Customer](https://en.wikipedia.org/wiki/Know_your_customer) (KYC), [Customer Identification Program](https://en.wikipedia.org/wiki/Customer_Identification_Program) (CIP), [Office of Foreign Asset Control](https://www.treasury.gov/about/organizational-structure/offices/Pages/Office-of-Foreign-Assets-Control.aspx) (OFAC) checks and verification workflows to comply with United States federal law and ensure authentic transfers. Customers has an objective to be a service for detailed due diligence on individuals and companies for Financial Institutions and services in a modernized and extensible way.  Customer phone numbers and addresses are stored and partially used in KYC/OFAC validation. Arbitrary key/value pairs can be stored for a Customer. Documents and Disclaimers, and their acknowledgment are also stored under a Customer as they're accepted. Bank Accounts, which can be validated with micro-deposits currently, are stored under each Customer.  ![](https://raw.githubusercontent.com/adamdecaf/customers/create-accounts/docs/images/customer.png)
+ *
+ * API version: v1
+ * Generated by: OpenAPI Generator (https://openapi-generator.tech)
+ */
+
+package client
+
+// OwnerType The type of individual owner of a resource, such as SSN, phone, or address
+type OwnerType string
+
+// List of OwnerType
+const (
+	OWNERTYPE_CUSTOMER       OwnerType = "customer"
+	OWNERTYPE_REPRESENTATIVE OwnerType = "representative"
+)
diff --git a/pkg/client/model_phone.go b/pkg/client/model_phone.go
index eda9889..5fa2397 100644
--- a/pkg/client/model_phone.go
+++ b/pkg/client/model_phone.go
@@ -12,7 +12,8 @@ package client
 // Phone struct for Phone
 type Phone struct {
 	// phone number
-	Number string `json:"number"`
+	Number    string    `json:"number"`
+	OwnerType OwnerType `json:"ownerType,omitempty"`
 	// phone number has been validated to connect with customer
 	Valid bool      `json:"valid"`
 	Type  PhoneType `json:"type"`
diff --git a/pkg/client/model_representative.go b/pkg/client/model_representative.go
new file mode 100644
index 0000000..3397f4b
--- /dev/null
+++ b/pkg/client/model_representative.go
@@ -0,0 +1,37 @@
+/*
+ * Customers API
+ *
+ * Customers focuses on solving authentic identification of humans who are legally able to hold and transfer currency within the US. Primarily this project solves [Know Your Customer](https://en.wikipedia.org/wiki/Know_your_customer) (KYC), [Customer Identification Program](https://en.wikipedia.org/wiki/Customer_Identification_Program) (CIP), [Office of Foreign Asset Control](https://www.treasury.gov/about/organizational-structure/offices/Pages/Office-of-Foreign-Assets-Control.aspx) (OFAC) checks and verification workflows to comply with United States federal law and ensure authentic transfers. Customers has an objective to be a service for detailed due diligence on individuals and companies for Financial Institutions and services in a modernized and extensible way.  Customer phone numbers and addresses are stored and partially used in KYC/OFAC validation. Arbitrary key/value pairs can be stored for a Customer. Documents and Disclaimers, and their acknowledgment are also stored under a Customer as they're accepted. Bank Accounts, which can be validated with micro-deposits currently, are stored under each Customer.  ![](https://raw.githubusercontent.com/adamdecaf/customers/create-accounts/docs/images/customer.png)
+ *
+ * API version: v1
+ * Generated by: OpenAPI Generator (https://openapi-generator.tech)
+ */
+
+package client
+
+import (
+	"time"
+)
+
+// Representative struct for Representative
+type Representative struct {
+	// Unique identifier for this Representative
+	RepresentativeID string `json:"representativeID"`
+	// The unique identifier for the customer the representative belongs to
+	CustomerID string `json:"customerID"`
+	// Given Name or First Name
+	FirstName string `json:"firstName"`
+	// Surname or Last Name
+	LastName string `json:"lastName"`
+	// Job title of this representative
+	JobTitle string `json:"jobTitle,omitempty"`
+	// Legal date of birth
+	BirthDate string    `json:"birthDate,omitempty"`
+	CreatedAt time.Time `json:"createdAt"`
+	// Last time the object was modified
+	LastModified time.Time `json:"lastModified"`
+	// Customer Representative's Social Security Number (SSN)
+	SSN       string    `json:"SSN,omitempty"`
+	Phones    []Phone   `json:"phones,omitempty"`
+	Addresses []Address `json:"addresses,omitempty"`
+}
diff --git a/pkg/client/model_sic_code.go b/pkg/client/model_sic_code.go
new file mode 100644
index 0000000..8904bca
--- /dev/null
+++ b/pkg/client/model_sic_code.go
@@ -0,0 +1,101 @@
+/*
+ * Customers API
+ *
+ * Customers focuses on solving authentic identification of humans who are legally able to hold and transfer currency within the US. Primarily this project solves [Know Your Customer](https://en.wikipedia.org/wiki/Know_your_customer) (KYC), [Customer Identification Program](https://en.wikipedia.org/wiki/Customer_Identification_Program) (CIP), [Office of Foreign Asset Control](https://www.treasury.gov/about/organizational-structure/offices/Pages/Office-of-Foreign-Assets-Control.aspx) (OFAC) checks and verification workflows to comply with United States federal law and ensure authentic transfers. Customers has an objective to be a service for detailed due diligence on individuals and companies for Financial Institutions and services in a modernized and extensible way.  Customer phone numbers and addresses are stored and partially used in KYC/OFAC validation. Arbitrary key/value pairs can be stored for a Customer. Documents and Disclaimers, and their acknowledgment are also stored under a Customer as they're accepted. Bank Accounts, which can be validated with micro-deposits currently, are stored under each Customer.  ![](https://raw.githubusercontent.com/adamdecaf/customers/create-accounts/docs/images/customer.png)
+ *
+ * API version: v1
+ * Generated by: OpenAPI Generator (https://openapi-generator.tech)
+ */
+
+package client
+
+// SicCode SIC Code (https://docs.google.com/spreadsheets/d/1erIdqoy60JwLAnpb91EfoJV5YrXDnbwSaA-aqcBlw48/edit#gid=1627409140)
+type SicCode string
+
+// List of SICCode
+const (
+	SICCODE__1   SicCode = "1"
+	SICCODE__2   SicCode = "2"
+	SICCODE__7   SicCode = "7"
+	SICCODE__8_0 SicCode = "8.0"
+	SICCODE__9_0 SicCode = "9.0"
+	SICCODE__10  SicCode = "10"
+	SICCODE__12  SicCode = "12"
+	SICCODE__13  SicCode = "13"
+	SICCODE__14  SicCode = "14"
+	SICCODE__15  SicCode = "15"
+	SICCODE__16  SicCode = "16"
+	SICCODE__17  SicCode = "17"
+	SICCODE__20  SicCode = "20"
+	SICCODE__21  SicCode = "21"
+	SICCODE__22  SicCode = "22"
+	SICCODE__23  SicCode = "23"
+	SICCODE__24  SicCode = "24"
+	SICCODE__25  SicCode = "25"
+	SICCODE__26  SicCode = "26"
+	SICCODE__27  SicCode = "27"
+	SICCODE__28  SicCode = "28"
+	SICCODE__29  SicCode = "29"
+	SICCODE__30  SicCode = "30"
+	SICCODE__31  SicCode = "31"
+	SICCODE__32  SicCode = "32"
+	SICCODE__33  SicCode = "33"
+	SICCODE__34  SicCode = "34"
+	SICCODE__35  SicCode = "35"
+	SICCODE__36  SicCode = "36"
+	SICCODE__37  SicCode = "37"
+	SICCODE__38  SicCode = "38"
+	SICCODE__39  SicCode = "39"
+	SICCODE__40  SicCode = "40"
+	SICCODE__41  SicCode = "41"
+	SICCODE__42  SicCode = "42"
+	SICCODE__43  SicCode = "43"
+	SICCODE__44  SicCode = "44"
+	SICCODE__45  SicCode = "45"
+	SICCODE__46  SicCode = "46"
+	SICCODE__47  SicCode = "47"
+	SICCODE__48  SicCode = "48"
+	SICCODE__49  SicCode = "49"
+	SICCODE__50  SicCode = "50"
+	SICCODE__51  SicCode = "51"
+	SICCODE__52  SicCode = "52"
+	SICCODE__53  SicCode = "53"
+	SICCODE__54  SicCode = "54"
+	SICCODE__55  SicCode = "55"
+	SICCODE__56  SicCode = "56"
+	SICCODE__57  SicCode = "57"
+	SICCODE__58  SicCode = "58"
+	SICCODE__59  SicCode = "59"
+	SICCODE__60  SicCode = "60"
+	SICCODE__61  SicCode = "61"
+	SICCODE__62  SicCode = "62"
+	SICCODE__63  SicCode = "63"
+	SICCODE__64  SicCode = "64"
+	SICCODE__65  SicCode = "65"
+	SICCODE__67  SicCode = "67"
+	SICCODE__70  SicCode = "70"
+	SICCODE__72  SicCode = "72"
+	SICCODE__73  SicCode = "73"
+	SICCODE__75  SicCode = "75"
+	SICCODE__76  SicCode = "76"
+	SICCODE__78  SicCode = "78"
+	SICCODE__79  SicCode = "79"
+	SICCODE__80  SicCode = "80"
+	SICCODE__81  SicCode = "81"
+	SICCODE__82  SicCode = "82"
+	SICCODE__83  SicCode = "83"
+	SICCODE__84  SicCode = "84"
+	SICCODE__86  SicCode = "86"
+	SICCODE__87  SicCode = "87"
+	SICCODE__88  SicCode = "88"
+	SICCODE__89  SicCode = "89"
+	SICCODE__91  SicCode = "91"
+	SICCODE__92  SicCode = "92"
+	SICCODE__93  SicCode = "93"
+	SICCODE__94  SicCode = "94"
+	SICCODE__95  SicCode = "95"
+	SICCODE__96  SicCode = "96"
+	SICCODE__97  SicCode = "97"
+	SICCODE__98  SicCode = "98"
+	SICCODE__99  SicCode = "99"
+)
diff --git a/pkg/client/model_update_customer_address.go b/pkg/client/model_update_address.go
similarity index 95%
rename from pkg/client/model_update_customer_address.go
rename to pkg/client/model_update_address.go
index 8b6e0a5..b67fff6 100644
--- a/pkg/client/model_update_customer_address.go
+++ b/pkg/client/model_update_address.go
@@ -9,8 +9,8 @@
 
 package client
 
-// UpdateCustomerAddress struct for UpdateCustomerAddress
-type UpdateCustomerAddress struct {
+// UpdateAddress struct for UpdateAddress
+type UpdateAddress struct {
 	// Attribute of address
 	Type string `json:"type"`
 	// If this address has been confirmed with the Customer
diff --git a/pkg/customers/address.go b/pkg/customers/address.go
index 56b8d9c..2264ca6 100644
--- a/pkg/customers/address.go
+++ b/pkg/customers/address.go
@@ -4,6 +4,7 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
+	"github.com/moov-io/customers/pkg/client"
 	"net/http"
 
 	"github.com/gorilla/mux"
@@ -20,12 +21,16 @@ var (
 func AddCustomerAddressRoutes(logger log.Logger, r *mux.Router, repo CustomerRepository) {
 	logger = logger.Set("package", "customers")
 
-	r.Methods("POST").Path("/customers/{customerID}/addresses").HandlerFunc(createCustomerAddress(logger, repo))
-	r.Methods("PUT").Path("/customers/{customerID}/addresses/{addressID}").HandlerFunc(updateCustomerAddress(logger, repo))
-	r.Methods("DELETE").Path("/customers/{customerID}/addresses/{addressID}").HandlerFunc(deleteCustomerAddress(logger, repo))
+	r.Methods("POST").Path("/customers/{customerID}/addresses").HandlerFunc(createAddress(logger, client.OWNERTYPE_CUSTOMER, repo))
+	r.Methods("PUT").Path("/customers/{customerID}/addresses/{addressID}").HandlerFunc(updateAddress(logger, client.OWNERTYPE_CUSTOMER, repo))
+	r.Methods("DELETE").Path("/customers/{customerID}/addresses/{addressID}").HandlerFunc(deleteAddress(logger, client.OWNERTYPE_CUSTOMER, repo))
+
+	r.Methods("POST").Path("/customers/{customerID}/representatives/{representativeID}/addresses").HandlerFunc(createAddress(logger, client.OWNERTYPE_REPRESENTATIVE, repo))
+	r.Methods("PUT").Path("/customers/{customerID}/representatives/{representativeID}/addresses/{addressID}").HandlerFunc(updateAddress(logger, client.OWNERTYPE_REPRESENTATIVE, repo))
+	r.Methods("DELETE").Path("/customers/{customerID}/representatives/{representativeID}/addresses/{addressID}").HandlerFunc(deleteAddress(logger, client.OWNERTYPE_REPRESENTATIVE, repo))
 }
 
-func createCustomerAddress(logger log.Logger, repo CustomerRepository) http.HandlerFunc {
+func createAddress(logger log.Logger, ownerType client.OwnerType, repo CustomerRepository) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
 		customerID, requestID := route.GetCustomerID(w, r), moovhttp.GetRequestID(r)
 		if customerID == "" {
@@ -37,27 +42,51 @@ func createCustomerAddress(logger log.Logger, repo CustomerRepository) http.Hand
 			return
 		}
 
-		var reqAddr address
-		if err := json.NewDecoder(r.Body).Decode(&reqAddr); err != nil {
-			moovhttp.Problem(w, err)
-			return
+		var ownerID string
+		var addresses []client.Address
+		if ownerType == client.OWNERTYPE_CUSTOMER {
+			ownerID = customerID
+			cust, err := repo.GetCustomer(customerID, organization)
+			if err != nil {
+				moovhttp.Problem(w, err)
+				return
+			}
+			if cust == nil {
+				w.WriteHeader(http.StatusNotFound)
+				return
+			}
+			addresses = cust.Addresses
+		} else {
+			representativeID := route.GetRepresentativeID(w, r)
+			if representativeID == "" {
+				return
+			}
+			rep, err := repo.GetRepresentative(representativeID)
+			if err != nil {
+				moovhttp.Problem(w, err)
+				return
+			}
+			if rep == nil {
+				http.NotFound(w, r)
+				return
+			}
+			addresses = rep.Addresses
 		}
 
-		cust, err := repo.GetCustomer(customerID, organization)
-		if err != nil {
+		//ownerID, owner, ownerType, err := getOwnerIDAndType(w, customerID, representativeID, organization, repo)
+
+		var reqAddr address
+		if err := json.NewDecoder(r.Body).Decode(&reqAddr); err != nil {
 			moovhttp.Problem(w, err)
 			return
 		}
-		if cust == nil {
-			w.WriteHeader(http.StatusNotFound)
-			return
-		}
 
 		// todo: vince-10/12/2020: we need to perform this conversion for validation til we develop a clean separation layer between client and model structs
 		var addrs []address
-		for _, addr := range cust.Addresses {
+		for _, addr := range addresses {
 			addrs = append(addrs, address{
 				Type:       addr.Type,
+				OwnerType:  addr.OwnerType,
 				Address1:   addr.Address1,
 				Address2:   addr.Address2,
 				City:       addr.City,
@@ -71,32 +100,46 @@ func createCustomerAddress(logger log.Logger, repo CustomerRepository) http.Hand
 			return
 		}
 
-		if err := repo.addCustomerAddress(customerID, reqAddr); err != nil {
+		if err := repo.addAddress(ownerID, ownerType, reqAddr); err != nil {
 			moovhttp.Problem(w, err)
 			return
 		}
 
-		logger.Logf("added address for customer=%s", customerID)
+		logger.Logf("added address for %s=%s", string(ownerType), ownerID)
 		respondWithCustomer(logger, w, customerID, organization, requestID, repo)
 	}
 }
 
-func updateCustomerAddress(logger log.Logger, repo CustomerRepository) http.HandlerFunc {
+func updateAddress(logger log.Logger, ownerType client.OwnerType, repo CustomerRepository) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
 		w = route.Responder(logger, w, r)
 
-		customerID, addressId := route.GetCustomerID(w, r), getAddressId(w, r)
-		if customerID == "" || addressId == "" {
+		customerID := route.GetCustomerID(w, r)
+		if customerID == "" {
+			return
+		}
+		addressId := getAddressID(w, r)
+		if addressId == "" {
 			return
 		}
 
+		ownerID := customerID
+		var representativeID string
+		if ownerType == client.OWNERTYPE_REPRESENTATIVE {
+			representativeID = route.GetRepresentativeID(w, r)
+			if representativeID == "" {
+				return
+			}
+			ownerID = representativeID
+		}
+
 		requestID := moovhttp.GetRequestID(r)
 		organization := route.GetOrganization(w, r)
 		if organization == "" {
 			return
 		}
 
-		var req updateCustomerAddressRequest
+		var req updateAddressRequest
 		if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
 			moovhttp.Problem(w, err)
 			return
@@ -108,13 +151,25 @@ func updateCustomerAddress(logger log.Logger, repo CustomerRepository) http.Hand
 		}
 
 		if req.Type == "primary" {
-			cust, err := repo.GetCustomer(customerID, organization)
-			if err != nil {
-				moovhttp.Problem(w, err)
-				return
+			var addresses []client.Address
+			if ownerType == client.OWNERTYPE_CUSTOMER {
+				cust, err := repo.GetCustomer(customerID, organization)
+				if err != nil {
+					moovhttp.Problem(w, err)
+					return
+				}
+				addresses = cust.Addresses
+			} else {
+				rep, err := repo.GetRepresentative(representativeID)
+				if err != nil {
+					moovhttp.Problem(w, err)
+					return
+				}
+				addresses = rep.Addresses
+
 			}
 
-			for _, addr := range cust.Addresses {
+			for _, addr := range addresses {
 				if addr.Type == "primary" && addr.AddressID != addressId {
 					moovhttp.Problem(w, ErrAddressTypeDuplicate)
 					return
@@ -122,41 +177,54 @@ func updateCustomerAddress(logger log.Logger, repo CustomerRepository) http.Hand
 			}
 		}
 
-		if err := repo.updateCustomerAddress(customerID, addressId, req); err != nil {
-			logger.LogErrorf("error updating customer's address: customer=%s address=%s: %v", customerID, addressId, err)
+		if err := repo.updateAddress(ownerID, addressId, ownerType, req); err != nil {
+			logger.LogErrorf("error updating %s's address: %s=%s address=%s: %v", string(ownerType), string(ownerType), ownerID, addressId, err)
 			moovhttp.Problem(w, err)
 			return
 		}
 
-		logger.Logf("updating address=%s for customer=%s", addressId, customerID)
+		logger.Logf("updating address=%s for %s=%s", addressId, string(ownerType), customerID)
 
 		respondWithCustomer(logger, w, customerID, organization, requestID, repo)
 	}
 }
 
-func deleteCustomerAddress(logger log.Logger, repo CustomerRepository) http.HandlerFunc {
+func deleteAddress(logger log.Logger, ownerType client.OwnerType, repo CustomerRepository) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
 		w = route.Responder(logger, w, r)
 
-		customerID, addressId := route.GetCustomerID(w, r), getAddressId(w, r)
-		if customerID == "" || addressId == "" {
+		customerID, addressId := route.GetCustomerID(w, r), getAddressID(w, r)
+		if customerID == "" {
+			return
+		}
+
+		if addressId == "" {
 			return
 		}
 
-		err := repo.deleteCustomerAddress(customerID, addressId)
+		ownerID := customerID
+		if ownerType == client.OWNERTYPE_REPRESENTATIVE {
+			representativeID := route.GetRepresentativeID(w, r)
+			if representativeID == "" {
+				return
+			}
+			ownerID = representativeID
+		}
+
+		err := repo.deleteAddress(ownerID, ownerType, addressId)
 		if err != nil {
-			logger.LogErrorf("error deleting customer's address: customer=%s address=%s: %v", customerID, addressId, err)
+			logger.LogErrorf("error deleting %s's address: %s=%s address=%s: %v", string(ownerType), string(ownerType), customerID, addressId, err)
 			moovhttp.Problem(w, err)
 			return
 		}
 
-		logger.Logf("successfully deleted address=%s for customer=%s", addressId, customerID)
+		logger.Logf("successfully deleted address=%s for %s=%s", addressId, string(ownerType), customerID)
 
 		w.WriteHeader(http.StatusNoContent)
 	}
 }
 
-func getAddressId(w http.ResponseWriter, r *http.Request) string {
+func getAddressID(w http.ResponseWriter, r *http.Request) string {
 	varName := "addressID"
 	v, ok := mux.Vars(r)[varName]
 	if !ok || v == "" {
@@ -166,7 +234,7 @@ func getAddressId(w http.ResponseWriter, r *http.Request) string {
 	return v
 }
 
-type updateCustomerAddressRequest struct {
+type updateAddressRequest struct {
 	address   `json:",inline"`
 	Validated bool `json:"validated"`
 }
diff --git a/pkg/customers/customer_representatives.go b/pkg/customers/customer_representatives.go
new file mode 100644
index 0000000..a5fb422
--- /dev/null
+++ b/pkg/customers/customer_representatives.go
@@ -0,0 +1,435 @@
+// Copyright 2020 The Moov Authors
+// Use of this source code is governed by an Apache License
+// license that can be found in the LICENSE file.
+
+package customers
+
+import (
+	"encoding/json"
+	"errors"
+	"fmt"
+	"github.com/gorilla/mux"
+	"net/http"
+	"strings"
+	"time"
+
+	"github.com/moov-io/base"
+	moovhttp "github.com/moov-io/base/http"
+
+	"github.com/moov-io/customers/pkg/client"
+	"github.com/moov-io/customers/pkg/model"
+	"github.com/moov-io/customers/pkg/route"
+
+	"github.com/moov-io/base/log"
+)
+
+func AddRepresentativeRoutes(logger log.Logger, r *mux.Router, repo CustomerRepository, customerSSNStorage *ssnStorage) {
+	logger = logger.Set("package", "customers")
+
+	r.Methods("PUT").Path("/customers/{customerID}/representatives/{representativeID}").HandlerFunc(updateRepresentative(logger, repo, customerSSNStorage))
+	r.Methods("DELETE").Path("/customers/{customerID}/representatives/{representativeID}").HandlerFunc(deleteRepresentative(logger, repo))
+	r.Methods("POST").Path("/customers/{customerID}/representatives").HandlerFunc(createRepresentative(logger, repo, customerSSNStorage))
+}
+
+func deleteRepresentative(logger log.Logger, repo CustomerRepository) func(http.ResponseWriter, *http.Request) {
+	return func(w http.ResponseWriter, r *http.Request) {
+		w = route.Responder(logger, w, r)
+
+		representativeID := route.GetRepresentativeID(w, r)
+		if representativeID == "" {
+			return
+		}
+
+		err := repo.deleteRepresentative(representativeID)
+		if err != nil {
+			moovhttp.Problem(w, fmt.Errorf("deleting customer representative: %v", err))
+			return
+		}
+
+		w.WriteHeader(http.StatusNoContent)
+	}
+}
+
+// customerRepresentativeRequest holds the information for creating a Customer Representative from the HTTP api
+type customerRepresentativeRequest struct {
+	RepresentativeID string         `json:"-"`
+	CustomerID       string         `json:"customerID"`
+	FirstName        string         `json:"firstName"`
+	LastName         string         `json:"lastName"`
+	JobTitle         string         `json:"jobTitle,omitempty"`
+	BirthDate        model.YYYYMMDD `json:"birthDate,omitempty"`
+	SSN              string         `json:"SSN,omitempty"`
+	Phones           []phone        `json:"phones,omitempty"`
+	Addresses        []address      `json:"addresses,omitempty"`
+}
+
+func createRepresentative(logger log.Logger, repo CustomerRepository, customerSSNStorage *ssnStorage) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		w = route.Responder(logger, w, r)
+		w.Header().Set("Content-Type", "application/json; charset=utf-8")
+
+		var req customerRepresentativeRequest
+		if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
+			moovhttp.Problem(w, err)
+			return
+		}
+		if err := req.validate(); err != nil {
+			logger.LogErrorf("error validating new customer representative: %v", err)
+			moovhttp.Problem(w, err)
+			return
+		}
+
+		req.CustomerID = route.GetCustomerID(w, r)
+
+		representative, ssn, err := req.asRepresentative(customerSSNStorage)
+		if err != nil {
+			logger.LogErrorf("problem transforming request into Customer Representative=%s: %v", representative.RepresentativeID, err)
+			moovhttp.Problem(w, err)
+			return
+		}
+		if ssn != nil {
+			err := customerSSNStorage.repo.saveSSN(ssn)
+			if err != nil {
+				logger.LogErrorf("problem saving SSN for Customer Representative=%s: %v", representative.RepresentativeID, err)
+				moovhttp.Problem(w, fmt.Errorf("saveSSN: %v", err))
+				return
+			}
+		}
+		if err := repo.CreateRepresentative(representative, req.CustomerID); err != nil {
+			logger.LogErrorf("createCustomer: %v", err)
+			moovhttp.Problem(w, err)
+			return
+		}
+
+		logger.Logf("created customer representative=%s", representative.RepresentativeID)
+
+		representative, err = repo.GetRepresentative(representative.RepresentativeID)
+		if err != nil {
+			moovhttp.Problem(w, err)
+			return
+		}
+
+		w.WriteHeader(http.StatusOK)
+		json.NewEncoder(w).Encode(representative)
+	}
+}
+
+func updateRepresentative(logger log.Logger, repo CustomerRepository, customerSSNStorage *ssnStorage) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		w = route.Responder(logger, w, r)
+		w.Header().Set("Content-Type", "application/json; charset=utf-8")
+
+		organization := route.GetOrganization(w, r)
+		if organization == "" {
+			return
+		}
+
+		var req customerRepresentativeRequest
+		req.RepresentativeID = route.GetRepresentativeID(w, r)
+		if req.RepresentativeID == "" {
+			return
+		}
+
+		if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
+			moovhttp.Problem(w, err)
+			return
+		}
+		if err := req.validate(); err != nil {
+			logger.LogErrorf("error validating customer payload: %v", err)
+			moovhttp.Problem(w, err)
+			return
+		}
+
+		representative, ssn, err := req.asRepresentative(customerSSNStorage)
+		if err != nil {
+			logger.LogErrorf("transforming request into Customer Representative=%s: %v", representative.RepresentativeID, err)
+			moovhttp.Problem(w, err)
+			return
+		}
+		if ssn != nil {
+			err := customerSSNStorage.repo.saveSSN(ssn)
+			if err != nil {
+				logger.LogErrorf("error saving SSN for Customer Representative=%s: %v", representative.RepresentativeID, err)
+				moovhttp.Problem(w, fmt.Errorf("saving customer's SSN: %v", err))
+				return
+			}
+		}
+		if err := repo.updateRepresentative(representative, req.CustomerID); err != nil {
+			logger.LogErrorf("error updating customer representative: %v", err)
+			moovhttp.Problem(w, fmt.Errorf("updating customer representative: %v", err))
+			return
+		}
+
+		logger.Logf("updated customer representative=%s", representative.RepresentativeID)
+		representative, err = repo.GetRepresentative(representative.RepresentativeID)
+		if err != nil {
+			moovhttp.Problem(w, err)
+			return
+		}
+
+		w.WriteHeader(http.StatusOK)
+		json.NewEncoder(w).Encode(representative)
+	}
+}
+
+func (req customerRepresentativeRequest) validate() error {
+	if req.FirstName == "" || req.LastName == "" {
+		return errors.New("invalid customer representative fields: empty name field(s)")
+	}
+	if err := validateAddresses(req.Addresses); err != nil {
+		return fmt.Errorf("invalid customer representative addresses: %v", err)
+	}
+	if err := validatePhones(req.Phones); err != nil {
+		return fmt.Errorf("invalid customer representative phone: %v", err)
+	}
+
+	return nil
+}
+
+func (r *sqlCustomerRepository) GetRepresentative(representativeID string) (*client.Representative, error) {
+	reps, err := r.getRepresentativesByIds([]string{representativeID})
+	if err != nil {
+		return nil, fmt.Errorf("getting customer representative: %v", err)
+	}
+
+	if len(reps) == 0 {
+		return nil, errors.New("customer representative not found")
+	}
+
+	return reps[representativeID], nil
+}
+
+func (r *sqlCustomerRepository) getRepresentatives(customerIDs []string) (map[string][]client.Representative, error) {
+	query := fmt.Sprintf(
+		"select representative_id, customer_id, first_name, last_name, job_title, birth_date from representatives where customer_id in (?%s) and deleted_at is null;",
+		strings.Repeat(",?", len(customerIDs)-1),
+	)
+	rows, err := r.queryRowsByCustomerIDs(query, customerIDs)
+	if err != nil {
+		return nil, err
+	}
+	defer rows.Close()
+
+	ret := make(map[string][]client.Representative)
+	for rows.Next() {
+		var c client.Representative
+		var jobTitle *string
+		var birthDate *time.Time
+		if err := rows.Scan(
+			&c.RepresentativeID,
+			&c.CustomerID,
+			&c.FirstName,
+			&c.LastName,
+			&jobTitle,
+			&birthDate,
+		); err != nil {
+			return nil, fmt.Errorf("scanning row: %v", err)
+		}
+		if birthDate != nil {
+			c.BirthDate = birthDate.Format(model.YYYYMMDD_Format)
+		}
+		if jobTitle != nil {
+			c.JobTitle = *jobTitle
+		}
+		phonesByCustomerID, err := r.GetPhones([]string{c.RepresentativeID}, client.OWNERTYPE_REPRESENTATIVE)
+		if err != nil {
+			return nil, fmt.Errorf("fetching customer representative phones: %v", err)
+		}
+		c.Phones = phonesByCustomerID[c.RepresentativeID]
+		addressesByCustomerID, err := r.GetAddresses([]string{c.RepresentativeID}, client.OWNERTYPE_REPRESENTATIVE)
+		if err != nil {
+			return nil, fmt.Errorf("fetching customer representative addresses: %v", err)
+		}
+		c.Addresses = addressesByCustomerID[c.RepresentativeID]
+		ret[c.CustomerID] = append(ret[c.CustomerID], c)
+	}
+
+	return ret, nil
+}
+
+func (r *sqlCustomerRepository) getRepresentativesByIds(representativeIDs []string) (map[string]*client.Representative, error) {
+	query := fmt.Sprintf(
+		"select representative_id, customer_id, first_name, last_name, job_title, birth_date from representatives where representative_id in (?%s) and deleted_at is null;",
+		strings.Repeat(",?", len(representativeIDs)-1),
+	)
+	rows, err := r.queryRowsByCustomerIDs(query, representativeIDs)
+	if err != nil {
+		return nil, err
+	}
+	defer rows.Close()
+
+	ret := make(map[string]*client.Representative)
+	for rows.Next() {
+		var c client.Representative
+		var jobTitle *string
+		var birthDate *time.Time
+		if err := rows.Scan(
+			&c.RepresentativeID,
+			&c.CustomerID,
+			&c.FirstName,
+			&c.LastName,
+			&jobTitle,
+			&birthDate,
+		); err != nil {
+			return nil, fmt.Errorf("scanning row: %v", err)
+		}
+		if birthDate != nil {
+			c.BirthDate = birthDate.Format(model.YYYYMMDD_Format)
+		}
+		if jobTitle != nil {
+			c.JobTitle = *jobTitle
+		}
+		phonesByCustomerID, err := r.GetPhones([]string{c.RepresentativeID}, client.OWNERTYPE_REPRESENTATIVE)
+		if err != nil {
+			return nil, fmt.Errorf("fetching customer representative phones: %v", err)
+		}
+		c.Phones = phonesByCustomerID[c.RepresentativeID]
+		addressesByCustomerID, err := r.GetAddresses([]string{c.RepresentativeID}, client.OWNERTYPE_REPRESENTATIVE)
+		if err != nil {
+			return nil, fmt.Errorf("fetching customer representative addresses: %v", err)
+		}
+		c.Addresses = addressesByCustomerID[c.RepresentativeID]
+		ret[c.RepresentativeID] = &c
+	}
+
+	return ret, nil
+}
+
+func (r *sqlCustomerRepository) CreateRepresentative(c *client.Representative, customerID string) error {
+	tx, err := r.db.Begin()
+	if err != nil {
+		return err
+	}
+
+	// Insert customer record
+	query := `insert into representatives (representative_id, customer_id, first_name, last_name, job_title, birth_date, created_at, last_modified)
+values (?, ?, ?, ?, ?, ?, ?, ?);`
+	stmt, err := tx.Prepare(query)
+	if err != nil {
+		return err
+	}
+	defer stmt.Close()
+
+	var birthDate *string
+	if c.BirthDate != "" {
+		birthDate = &c.BirthDate
+	}
+
+	now := time.Now()
+	_, err = stmt.Exec(c.RepresentativeID, customerID, c.FirstName, c.LastName, c.JobTitle, birthDate, now, now)
+	if err != nil {
+		return fmt.Errorf("CreateRepresentative: insert into representatives err=%v | rollback=%v", err, tx.Rollback())
+	}
+
+	err = r.updatePhonesByOwnerID(tx, c.RepresentativeID, client.OWNERTYPE_REPRESENTATIVE, c.Phones)
+	if err != nil {
+		return fmt.Errorf("updating customer representative's phones: %v", err)
+	}
+
+	err = r.updateAddressesByOwnerID(tx, c.RepresentativeID, client.OWNERTYPE_REPRESENTATIVE, c.Addresses)
+	if err != nil {
+		return fmt.Errorf("updating customer representative's addresses: %v", err)
+	}
+
+	if err := tx.Commit(); err != nil {
+		return fmt.Errorf("CreateRepresentative: tx.Commit: %v", err)
+	}
+	return nil
+}
+
+func (r *sqlCustomerRepository) updateRepresentative(c *client.Representative, customerID string) error {
+	tx, err := r.db.Begin()
+	if err != nil {
+		return err
+	}
+	defer tx.Rollback()
+
+	query := `update representatives set first_name = ?, last_name = ?, job_title = ?, birth_date = ?, last_modified = ? where representative_id = ? and customer_id = ? and deleted_at is null;`
+	stmt, err := tx.Prepare(query)
+	if err != nil {
+		return err
+	}
+	defer stmt.Close()
+
+	now := time.Now()
+	res, err := stmt.Exec(c.FirstName, c.LastName, c.JobTitle, c.BirthDate, now, c.RepresentativeID, customerID)
+	if err != nil {
+		return fmt.Errorf("updating customer representative: %v", err)
+	}
+
+	numRows, err := res.RowsAffected()
+	if err != nil {
+		return fmt.Errorf("getting rows affected: %v", err)
+	}
+
+	if numRows == 0 {
+		return fmt.Errorf("no records to update with customer representative id=%s", c.RepresentativeID)
+	}
+
+	err = r.updatePhonesByOwnerID(tx, c.RepresentativeID, client.OWNERTYPE_REPRESENTATIVE, c.Phones)
+	if err != nil {
+		return fmt.Errorf("updating customer representative's phones: %v", err)
+	}
+
+	err = r.updateAddressesByOwnerID(tx, c.RepresentativeID, client.OWNERTYPE_REPRESENTATIVE, c.Addresses)
+	if err != nil {
+		return fmt.Errorf("updating customer representative's addresses: %v", err)
+	}
+
+	if err := tx.Commit(); err != nil {
+		return fmt.Errorf("updateRepresentative: tx.Commit: %v", err)
+	}
+	return nil
+}
+
+func (r *sqlCustomerRepository) deleteRepresentative(representativeID string) error {
+	query := `update representatives set deleted_at = ? where representative_id = ? and deleted_at is null;`
+	stmt, err := r.db.Prepare(query)
+	if err != nil {
+		return err
+	}
+	defer stmt.Close()
+
+	_, err = stmt.Exec(time.Now(), representativeID)
+	return err
+}
+
+func (req customerRepresentativeRequest) asRepresentative(storage *ssnStorage) (*client.Representative, *SSN, error) {
+	if req.RepresentativeID == "" {
+		req.RepresentativeID = base.ID()
+	}
+
+	representative := &client.Representative{
+		RepresentativeID: req.RepresentativeID,
+		CustomerID:       req.CustomerID,
+		FirstName:        req.FirstName,
+		LastName:         req.LastName,
+		JobTitle:         req.JobTitle,
+		BirthDate:        string(req.BirthDate),
+	}
+
+	for i := range req.Phones {
+		representative.Phones = append(representative.Phones, client.Phone{
+			Number:    req.Phones[i].Number,
+			Type:      req.Phones[i].Type,
+			OwnerType: req.Phones[i].OwnerType,
+		})
+	}
+	for i := range req.Addresses {
+		representative.Addresses = append(representative.Addresses, client.Address{
+			Address1:   req.Addresses[i].Address1,
+			Address2:   req.Addresses[i].Address2,
+			City:       req.Addresses[i].City,
+			State:      req.Addresses[i].State,
+			PostalCode: req.Addresses[i].PostalCode,
+			Country:    req.Addresses[i].Country,
+			Type:       req.Addresses[i].Type,
+			OwnerType:  req.Addresses[i].OwnerType,
+		})
+	}
+	if req.SSN != "" {
+		ssn, err := storage.encryptRaw(representative.RepresentativeID, client.OWNERTYPE_REPRESENTATIVE, req.SSN)
+		return representative, ssn, err
+	}
+	return representative, nil, nil
+}
diff --git a/pkg/customers/customer_search.go b/pkg/customers/customer_search.go
index f1e92de..d4e0b06 100644
--- a/pkg/customers/customer_search.go
+++ b/pkg/customers/customer_search.go
@@ -114,9 +114,18 @@ func (r *sqlCustomerRepository) searchCustomers(params SearchParams) ([]*client.
 			&c.NickName,
 			&c.Suffix,
 			&c.Type,
+			&c.BusinessName,
+			&c.DoingBusinessAs,
+			&c.BusinessType,
+			&c.EIN,
+			&c.DUNS,
+			&c.SICCode,
+			&c.NAICSCode,
 			&birthDate,
 			&c.Status,
 			&c.Email,
+			&c.Website,
+			&c.DateBusinessEstablished,
 			&c.CreatedAt,
 			&c.LastModified,
 		)
@@ -138,14 +147,18 @@ func (r *sqlCustomerRepository) searchCustomers(params SearchParams) ([]*client.
 		customerIDs = append(customerIDs, c.CustomerID)
 	}
 
-	phonesByCustomerID, err := r.getPhones(customerIDs)
+	phonesByCustomerID, err := r.GetPhones(customerIDs, client.OWNERTYPE_CUSTOMER)
 	if err != nil {
 		return nil, fmt.Errorf("fetching customer phones: %v", err)
 	}
-	addressesByCustomerID, err := r.getAddresses(customerIDs)
+	addressesByCustomerID, err := r.GetAddresses(customerIDs, client.OWNERTYPE_CUSTOMER)
 	if err != nil {
 		return nil, fmt.Errorf("fetching customer addresses: %v", err)
 	}
+	representativesByCustomerID, err := r.getRepresentatives(customerIDs)
+	if err != nil {
+		return nil, fmt.Errorf("fetching customer representatives: %v", err)
+	}
 	metadataByCustomerID, err := r.getMetadata(customerIDs)
 	if err != nil {
 		return nil, fmt.Errorf("fetching customer metadata: %v", err)
@@ -154,6 +167,7 @@ func (r *sqlCustomerRepository) searchCustomers(params SearchParams) ([]*client.
 	for _, c := range customers {
 		c.Phones = phonesByCustomerID[c.CustomerID]
 		c.Addresses = addressesByCustomerID[c.CustomerID]
+		c.Representatives = representativesByCustomerID[c.CustomerID]
 		c.Metadata = metadataByCustomerID[c.CustomerID].Metadata
 	}
 
@@ -162,7 +176,7 @@ func (r *sqlCustomerRepository) searchCustomers(params SearchParams) ([]*client.
 
 func buildSearchQuery(params SearchParams) (string, []interface{}) {
 	var args []interface{}
-	query := `select customer_id, first_name, middle_name, last_name, nick_name, suffix, type, birth_date, status, email, created_at, last_modified
+	query := `select customer_id, first_name, middle_name, last_name, nick_name, suffix, type, business_name, doing_business_as, business_type, ein, duns, sic_code, naics_code, birth_date, status, email, website, date_business_established, created_at, last_modified
 from customers where deleted_at is null`
 
 	if params.Organization != "" {
@@ -209,13 +223,13 @@ from customers where deleted_at is null`
 	return query, args
 }
 
-func (r *sqlCustomerRepository) getPhones(customerIDs []string) (map[string][]client.Phone, error) {
+func (r *sqlCustomerRepository) GetPhones(ownerIDs []string, ownerType client.OwnerType) (map[string][]client.Phone, error) {
 	query := fmt.Sprintf(
-		"select customer_id, number, valid, type from customers_phones where customer_id in (?%s)",
-		strings.Repeat(",?", len(customerIDs)-1),
+		"select owner_id, owner_type, number, valid, type from phones where owner_id in (?%s) and owner_type = ?",
+		strings.Repeat(",?", len(ownerIDs)-1),
 	)
 
-	rows, err := r.queryRowsByCustomerIDs(query, customerIDs)
+	rows, err := r.queryRowsByCustomerIDsAndOwnerType(query, ownerIDs, ownerType)
 	if err != nil {
 		return nil, err
 	}
@@ -224,9 +238,10 @@ func (r *sqlCustomerRepository) getPhones(customerIDs []string) (map[string][]cl
 	ret := make(map[string][]client.Phone)
 	for rows.Next() {
 		var p client.Phone
-		var customerID string
+		var ownerID string
 		err := rows.Scan(
-			&customerID,
+			&ownerID,
+			&p.OwnerType,
 			&p.Number,
 			&p.Valid,
 			&p.Type,
@@ -234,29 +249,30 @@ func (r *sqlCustomerRepository) getPhones(customerIDs []string) (map[string][]cl
 		if err != nil {
 			return nil, fmt.Errorf("scanning row: %v", err)
 		}
-		ret[customerID] = append(ret[customerID], p)
+		ret[ownerID] = append(ret[ownerID], p)
 	}
 
 	return ret, nil
 }
 
-func (r *sqlCustomerRepository) getAddresses(customerIDs []string) (map[string][]client.CustomerAddress, error) {
+func (r *sqlCustomerRepository) GetAddresses(customerIDs []string, ownerType client.OwnerType) (map[string][]client.Address, error) {
 	query := fmt.Sprintf(
-		"select customer_id, address_id, type, address1, address2, city, state, postal_code, country, validated from customers_addresses where customer_id in (?%s) and deleted_at is null;",
+		"select owner_id, owner_type, address_id, type, address1, address2, city, state, postal_code, country, validated from addresses where owner_id in (?%s) and owner_type = ? and deleted_at is null;",
 		strings.Repeat(",?", len(customerIDs)-1),
 	)
-	rows, err := r.queryRowsByCustomerIDs(query, customerIDs)
+	rows, err := r.queryRowsByCustomerIDsAndOwnerType(query, customerIDs, ownerType)
 	if err != nil {
 		return nil, err
 	}
 	defer rows.Close()
 
-	ret := make(map[string][]client.CustomerAddress)
+	ret := make(map[string][]client.Address)
 	for rows.Next() {
-		var a client.CustomerAddress
-		var customerID string
+		var a client.Address
+		var ownerID string
 		if err := rows.Scan(
-			&customerID,
+			&ownerID,
+			&a.OwnerType,
 			&a.AddressID,
 			&a.Type,
 			&a.Address1,
@@ -269,7 +285,7 @@ func (r *sqlCustomerRepository) getAddresses(customerIDs []string) (map[string][
 		); err != nil {
 			return nil, fmt.Errorf("scanning row: %v", err)
 		}
-		ret[customerID] = append(ret[customerID], a)
+		ret[ownerID] = append(ret[ownerID], a)
 	}
 
 	return ret, nil
@@ -304,6 +320,28 @@ func (r *sqlCustomerRepository) getMetadata(customerIDs []string) (map[string]cl
 	return result, nil
 }
 
+func (r *sqlCustomerRepository) queryRowsByCustomerIDsAndOwnerType(query string, customerIDs []string, ownerType client.OwnerType) (*sql.Rows, error) {
+	stmt, err := r.db.Prepare(query)
+	if err != nil {
+		return nil, fmt.Errorf("preparing query: %v", err)
+	}
+	defer stmt.Close()
+
+	var args []interface{}
+	for _, id := range customerIDs {
+		args = append(args, id)
+	}
+
+	args = append(args, string(ownerType))
+
+	rows, err := stmt.Query(args...)
+	if err != nil {
+		return nil, fmt.Errorf("executing query: %v", err)
+	}
+
+	return rows, nil
+}
+
 func (r *sqlCustomerRepository) queryRowsByCustomerIDs(query string, customerIDs []string) (*sql.Rows, error) {
 	stmt, err := r.db.Prepare(query)
 	if err != nil {
diff --git a/pkg/customers/customer_ssn.go b/pkg/customers/customer_ssn.go
index 442eb5b..40ff77d 100644
--- a/pkg/customers/customer_ssn.go
+++ b/pkg/customers/customer_ssn.go
@@ -7,6 +7,7 @@ package customers
 import (
 	"database/sql"
 	"fmt"
+	"github.com/moov-io/customers/pkg/client"
 	"strings"
 	"time"
 	"unicode/utf8"
@@ -17,42 +18,44 @@ import (
 )
 
 type SSN struct {
-	customerID string
-	encrypted  string
-	masked     string
+	ownerID   string
+	ownerType client.OwnerType
+	encrypted string
+	masked    string
 }
 
 func (s *SSN) String() string {
-	return fmt.Sprintf("SSN: customerID=%s masked=%s", s.customerID, s.masked)
+	return fmt.Sprintf("SSN: ownerId=%s ownerType=%s masked=%s", s.ownerID, s.ownerType, s.masked)
 }
 
 type ssnStorage struct {
 	keeper *secrets.StringKeeper
-	repo   CustomerSSNRepository
+	repo   SSNRepository
 }
 
-func NewSSNStorage(keeper *secrets.StringKeeper, repo CustomerSSNRepository) *ssnStorage {
+func NewSSNStorage(keeper *secrets.StringKeeper, repo SSNRepository) *ssnStorage {
 	return &ssnStorage{
 		keeper: keeper,
 		repo:   repo,
 	}
 }
 
-func (s *ssnStorage) encryptRaw(customerID, raw string) (*SSN, error) {
+func (s *ssnStorage) encryptRaw(ownerID string, ownerType client.OwnerType, raw string) (*SSN, error) {
 	defer func() {
 		raw = ""
 	}()
-	if customerID == "" || raw == "" {
-		return nil, fmt.Errorf("missing customer=%s and/or SSN", customerID)
+	if ownerID == "" || raw == "" {
+		return nil, fmt.Errorf("missing parent=%s and/or SSN", ownerID)
 	}
 	encrypted, err := s.keeper.EncryptString(raw)
 	if err != nil {
-		return nil, fmt.Errorf("ssnStorage: encrypt customer=%s: %v", customerID, err)
+		return nil, fmt.Errorf("ssnStorage: encrypt owner=%s: %v", ownerID, err)
 	}
 	return &SSN{
-		customerID: customerID,
-		encrypted:  encrypted,
-		masked:     maskSSN(raw),
+		ownerID:   ownerID,
+		ownerType: ownerType,
+		encrypted: encrypted,
+		masked:    maskSSN(raw),
 	}, nil
 }
 
@@ -67,55 +70,55 @@ func maskSSN(s string) string {
 	}
 }
 
-type CustomerSSNRepository interface {
-	saveCustomerSSN(*SSN) error
-	getCustomerSSN(customerID string) (*SSN, error)
+type SSNRepository interface {
+	saveSSN(*SSN) error
+	getSSN(ownerID string, ownerType client.OwnerType) (*SSN, error)
 }
 
-func NewCustomerSSNRepository(logger log.Logger, db *sql.DB) CustomerSSNRepository {
-	return &sqlCustomerSSNRepository{
+func NewCustomerSSNRepository(logger log.Logger, db *sql.DB) SSNRepository {
+	return &sqlSSNRepository{
 		db:     db,
 		logger: logger,
 	}
 }
 
-type sqlCustomerSSNRepository struct {
+type sqlSSNRepository struct {
 	db     *sql.DB
 	logger log.Logger
 }
 
 //
 
-func (r *sqlCustomerSSNRepository) saveCustomerSSN(ssn *SSN) error {
-	query := `replace into customer_ssn (customer_id, ssn, ssn_masked, created_at) values (?, ?, ?, ?);`
+func (r *sqlSSNRepository) saveSSN(ssn *SSN) error {
+	query := `replace into ssn (owner_id, owner_type, ssn, ssn_masked, created_at) values (?, ?, ?, ?, ?);`
 	stmt, err := r.db.Prepare(query)
 	if err != nil {
-		return fmt.Errorf("sqlCustomerSSNRepository: saveCustomerSSN prepare: %v", err)
+		return fmt.Errorf("sqlSSNRepository: saveSSN prepare: %v", err)
 	}
 	defer stmt.Close()
 
-	if _, err := stmt.Exec(ssn.customerID, ssn.encrypted, ssn.masked, time.Now()); err != nil {
-		return fmt.Errorf("sqlCustomerSSNRepository: saveCustomerSSN: exec: %v", err)
+	if _, err := stmt.Exec(ssn.ownerID, string(ssn.ownerType), ssn.encrypted, ssn.masked, time.Now()); err != nil {
+		return fmt.Errorf("sqlSSNRepository: saveSSN: exec: %v", err)
 	}
 	return nil
 }
 
-func (r *sqlCustomerSSNRepository) getCustomerSSN(customerID string) (*SSN, error) {
-	query := `select ssn, ssn_masked from customer_ssn where customer_id = ? limit 1;`
+func (r *sqlSSNRepository) getSSN(ownerID string, ownerType client.OwnerType) (*SSN, error) {
+	query := `select ssn, ssn_masked from ssn where owner_id = ? and owner_type = ? limit 1;`
 	stmt, err := r.db.Prepare(query)
 	if err != nil {
-		return nil, fmt.Errorf("sqlCustomerSSNRepository: getCustomerSSN prepare: %v", err)
+		return nil, fmt.Errorf("sqlSSNRepository: getSSN prepare: %v", err)
 	}
 	defer stmt.Close()
 
-	row := stmt.QueryRow(customerID)
+	row := stmt.QueryRow(ownerID, string(ownerType))
 
-	ssn := SSN{customerID: customerID}
+	ssn := SSN{ownerID: ownerID, ownerType: ownerType}
 	if err := row.Scan(&ssn.encrypted, &ssn.masked); err != nil {
 		if err == sql.ErrNoRows {
 			return nil, nil // not found
 		}
-		return nil, fmt.Errorf("sqlCustomerSSNRepository: getCustomerSSN scan: %v", err)
+		return nil, fmt.Errorf("sqlSSNRepository: getSSN scan: %v", err)
 	}
 	return &ssn, nil
 }
diff --git a/pkg/customers/customers.go b/pkg/customers/customers.go
index 9600f37..0c70201 100644
--- a/pkg/customers/customers.go
+++ b/pkg/customers/customers.go
@@ -113,29 +113,41 @@ func respondWithCustomer(logger log.Logger, w http.ResponseWriter, customerID, o
 // TODO(adam): What GDPR implications does this information have? IIRC if any EU citizen uses
 // this software we have to fully comply.
 type customerRequest struct {
-	CustomerID string                `json:"-"`
-	FirstName  string                `json:"firstName"`
-	MiddleName string                `json:"middleName"`
-	LastName   string                `json:"lastName"`
-	NickName   string                `json:"nickName"`
-	Suffix     string                `json:"suffix"`
-	Type       client.CustomerType   `json:"type"`
-	BirthDate  model.YYYYMMDD        `json:"birthDate"`
-	Status     client.CustomerStatus `json:"-"`
-	Email      string                `json:"email"`
-	SSN        string                `json:"SSN"`
-	Phones     []phone               `json:"phones"`
-	Addresses  []address             `json:"addresses"`
-	Metadata   map[string]string     `json:"metadata"`
+	CustomerID              string                   `json:"-"`
+	FirstName               string                   `json:"firstName"`
+	MiddleName              string                   `json:"middleName"`
+	LastName                string                   `json:"lastName"`
+	NickName                string                   `json:"nickName"`
+	Suffix                  string                   `json:"suffix"`
+	Type                    client.CustomerType      `json:"type"`
+	BusinessName            string                   `json:"businessName"`
+	DoingBusinessAs         string                   `json:"doingBusinessAs"`
+	BusinessType            client.BusinessType      `json:"businessType"`
+	EIN                     string                   `json:"EIN"`
+	DUNS                    string                   `json:"DUNS"`
+	SICCode                 client.SicCode           `json:"sicCode"`
+	NAICSCode               client.NaicsCode         `json:"naicsCode"`
+	BirthDate               model.YYYYMMDD           `json:"birthDate"`
+	Status                  client.CustomerStatus    `json:"-"`
+	Email                   string                   `json:"email"`
+	Website                 string                   `json:"website"`
+	DateBusinessEstablished string                   `json:"dateBusinessEstablished"`
+	SSN                     string                   `json:"SSN"`
+	Phones                  []phone                  `json:"phones"`
+	Addresses               []address                `json:"addresses"`
+	Representatives         []customerRepresentative `json:"customerRepresentatives"`
+	Metadata                map[string]string        `json:"metadata"`
 }
 
 type phone struct {
-	Number string           `json:"number"`
-	Type   client.PhoneType `json:"type"`
+	Number    string           `json:"number"`
+	Type      client.PhoneType `json:"type"`
+	OwnerType client.OwnerType `json:"ownerType"`
 }
 
 func (p *phone) validate() error {
 	p.Type = client.PhoneType(strings.ToLower(string(p.Type)))
+	p.OwnerType = client.OwnerType(strings.ToLower(string(p.OwnerType)))
 
 	switch p.Type {
 	case client.PHONETYPE_HOME, client.PHONETYPE_MOBILE, client.PHONETYPE_WORK:
@@ -143,11 +155,18 @@ func (p *phone) validate() error {
 		return fmt.Errorf("unknown type: %s", p.Type)
 	}
 
+	switch p.OwnerType {
+	case client.OWNERTYPE_CUSTOMER, client.OWNERTYPE_REPRESENTATIVE:
+	default:
+		return fmt.Errorf("unknown owner type: %s", p.OwnerType)
+	}
+
 	return nil
 }
 
 type address struct {
 	Type       client.AddressType `json:"type"`
+	OwnerType  client.OwnerType   `json:"ownerType"`
 	Address1   string             `json:"address1"`
 	Address2   string             `json:"address2,omitempty"`
 	City       string             `json:"city"`
@@ -158,6 +177,7 @@ type address struct {
 
 func (add *address) validate() error {
 	add.Type = client.AddressType(strings.ToLower(string(add.Type)))
+	add.OwnerType = client.OwnerType(strings.ToLower(string(add.OwnerType)))
 
 	switch add.Type {
 	case client.ADDRESSTYPE_PRIMARY, client.ADDRESSTYPE_SECONDARY:
@@ -165,12 +185,34 @@ func (add *address) validate() error {
 		return fmt.Errorf("unknown type: %s", add.Type)
 	}
 
+	switch add.OwnerType {
+	case client.OWNERTYPE_CUSTOMER, client.OWNERTYPE_REPRESENTATIVE:
+	default:
+		return fmt.Errorf("unknown owner type: %s", add.OwnerType)
+	}
+
 	if !usstates.Valid(add.State) {
 		return fmt.Errorf("create customer: invalid state=%s", add.State)
 	}
 	return nil
 }
 
+type customerRepresentative struct {
+	FirstName string    `json:"firstName"`
+	LastName  string    `json:"lastName"`
+	JobTitle  string    `json:"jobTitle,omitempty"`
+	BirthDate string    `json:"birthDate,omitempty"`
+	Addresses []address `json:"addresses,omitempty"`
+	Phones    []phone   `json:"phones,omitempty"`
+}
+
+func (rep *customerRepresentative) validate() error {
+	if rep.FirstName == "" || rep.LastName == "" {
+		return errors.New("invalid customer representative fields: empty name field(s)")
+	}
+	return nil
+}
+
 func (req customerRequest) validate() error {
 	if req.FirstName == "" || req.LastName == "" {
 		return errors.New("invalid customer fields: empty name field(s)")
@@ -187,6 +229,9 @@ func (req customerRequest) validate() error {
 	if err := validatePhones(req.Phones); err != nil {
 		return fmt.Errorf("invalid customer phone: %v", err)
 	}
+	if err := validateRepresentatives(req.Representatives); err != nil {
+		return fmt.Errorf("invalid customer representative: %v", err)
+	}
 
 	return nil
 }
@@ -244,6 +289,16 @@ func validatePhones(phones []phone) error {
 	return nil
 }
 
+func validateRepresentatives(representatives []customerRepresentative) error {
+	for _, r := range representatives {
+		if err := r.validate(); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
 func (req customerRequest) asCustomer(storage *ssnStorage) (*client.Customer, *SSN, error) {
 	if req.CustomerID == "" {
 		req.CustomerID = base.ID()
@@ -254,27 +309,37 @@ func (req customerRequest) asCustomer(storage *ssnStorage) (*client.Customer, *S
 	}
 
 	customer := &client.Customer{
-		CustomerID: req.CustomerID,
-		FirstName:  req.FirstName,
-		MiddleName: req.MiddleName,
-		LastName:   req.LastName,
-		NickName:   req.NickName,
-		Suffix:     req.Suffix,
-		Type:       req.Type,
-		BirthDate:  string(req.BirthDate),
-		Email:      req.Email,
-		Status:     req.Status,
-		Metadata:   req.Metadata,
+		CustomerID:              req.CustomerID,
+		FirstName:               req.FirstName,
+		MiddleName:              req.MiddleName,
+		LastName:                req.LastName,
+		NickName:                req.NickName,
+		Suffix:                  req.Suffix,
+		Type:                    req.Type,
+		BusinessName:            req.BusinessName,
+		DoingBusinessAs:         req.DoingBusinessAs,
+		BusinessType:            req.BusinessType,
+		EIN:                     req.EIN,
+		DUNS:                    req.DUNS,
+		SICCode:                 req.SICCode,
+		NAICSCode:               req.NAICSCode,
+		BirthDate:               string(req.BirthDate),
+		Email:                   req.Email,
+		Website:                 req.Website,
+		DateBusinessEstablished: req.DateBusinessEstablished,
+		Status:                  req.Status,
+		Metadata:                req.Metadata,
 	}
 
 	for i := range req.Phones {
 		customer.Phones = append(customer.Phones, client.Phone{
-			Number: req.Phones[i].Number,
-			Type:   req.Phones[i].Type,
+			Number:    req.Phones[i].Number,
+			Type:      req.Phones[i].Type,
+			OwnerType: req.Phones[i].OwnerType,
 		})
 	}
 	for i := range req.Addresses {
-		customer.Addresses = append(customer.Addresses, client.CustomerAddress{
+		customer.Addresses = append(customer.Addresses, client.Address{
 			AddressID:  base.ID(),
 			Address1:   req.Addresses[i].Address1,
 			Address2:   req.Addresses[i].Address2,
@@ -283,10 +348,42 @@ func (req customerRequest) asCustomer(storage *ssnStorage) (*client.Customer, *S
 			PostalCode: req.Addresses[i].PostalCode,
 			Country:    req.Addresses[i].Country,
 			Type:       req.Addresses[i].Type,
+			OwnerType:  req.Addresses[i].OwnerType,
 		})
 	}
+	for i := range req.Representatives {
+		custRep := client.Representative{
+			RepresentativeID: base.ID(),
+			FirstName:        req.Representatives[i].FirstName,
+			LastName:         req.Representatives[i].LastName,
+			JobTitle:         req.Representatives[i].JobTitle,
+			BirthDate:        req.Representatives[i].BirthDate,
+		}
+
+		for j := range req.Representatives[i].Addresses {
+			custRep.Addresses = append(custRep.Addresses, client.Address{
+				AddressID:  base.ID(),
+				Address1:   req.Representatives[i].Addresses[j].Address1,
+				Address2:   req.Representatives[i].Addresses[j].Address2,
+				City:       req.Representatives[i].Addresses[j].City,
+				State:      req.Representatives[i].Addresses[j].State,
+				PostalCode: req.Representatives[i].Addresses[j].PostalCode,
+				Country:    req.Representatives[i].Addresses[j].Country,
+				Type:       req.Representatives[i].Addresses[j].Type,
+				OwnerType:  req.Representatives[i].Addresses[j].OwnerType,
+			})
+		}
+		for j := range req.Representatives[i].Phones {
+			custRep.Phones = append(custRep.Phones, client.Phone{
+				Number:    req.Representatives[i].Phones[j].Number,
+				Type:      req.Representatives[i].Phones[j].Type,
+				OwnerType: req.Representatives[i].Phones[j].OwnerType,
+			})
+		}
+		customer.Representatives = append(customer.Representatives, custRep)
+	}
 	if req.SSN != "" {
-		ssn, err := storage.encryptRaw(customer.CustomerID, req.SSN)
+		ssn, err := storage.encryptRaw(customer.CustomerID, client.OWNERTYPE_CUSTOMER, req.SSN)
 		return customer, ssn, err
 	}
 	return customer, nil, nil
@@ -320,7 +417,7 @@ func createCustomer(logger log.Logger, repo CustomerRepository, customerSSNStora
 			return
 		}
 		if ssn != nil {
-			err := customerSSNStorage.repo.saveCustomerSSN(ssn)
+			err := customerSSNStorage.repo.saveSSN(ssn)
 			if err != nil {
 				logger.LogErrorf("problem saving SSN for Customer=%s: %v", cust.CustomerID, err)
 				moovhttp.Problem(w, fmt.Errorf("saveCustomerSSN: %v", err))
@@ -389,7 +486,7 @@ func updateCustomer(logger log.Logger, repo CustomerRepository, customerSSNStora
 			return
 		}
 		if ssn != nil {
-			err := customerSSNStorage.repo.saveCustomerSSN(ssn)
+			err := customerSSNStorage.repo.saveSSN(ssn)
 			if err != nil {
 				logger.LogErrorf("error saving SSN for Customer=%s: %v", cust.CustomerID, err)
 				moovhttp.Problem(w, fmt.Errorf("saving customer's SSN: %v", err))
@@ -464,9 +561,14 @@ type CustomerRepository interface {
 
 	replaceCustomerMetadata(customerID string, metadata map[string]string) error
 
-	addCustomerAddress(customerID string, address address) error
-	updateCustomerAddress(customerID, addressID string, req updateCustomerAddressRequest) error
-	deleteCustomerAddress(customerID string, addressID string) error
+	GetRepresentative(representativeID string) (*client.Representative, error)
+	CreateRepresentative(c *client.Representative, customerID string) error
+	updateRepresentative(c *client.Representative, customerID string) error
+	deleteRepresentative(representativeID string) error
+
+	addAddress(ownerID string, ownerType client.OwnerType, address address) error
+	updateAddress(ownerID, addressID string, ownerType client.OwnerType, req updateAddressRequest) error
+	deleteAddress(ownerID string, ownerType client.OwnerType, addressID string) error
 
 	getLatestCustomerOFACSearch(customerID, organization string) (*client.OfacSearch, error)
 	saveCustomerOFACSearch(customerID string, result client.OfacSearch) error
@@ -507,8 +609,8 @@ func (r *sqlCustomerRepository) CreateCustomer(c *client.Customer, organization
 	}
 
 	// Insert customer record
-	query := `insert into customers (customer_id, first_name, middle_name, last_name, nick_name, suffix, type, birth_date, status, email, created_at, last_modified, organization)
-values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`
+	query := `insert into customers (customer_id, first_name, middle_name, last_name, nick_name, suffix, type, business_name, doing_business_as, business_type, ein, duns, sic_code, naics_code, birth_date, status, email, website, date_business_established, created_at, last_modified, organization)
+values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`
 	stmt, err := tx.Prepare(query)
 	if err != nil {
 		return err
@@ -521,21 +623,26 @@ values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`
 	}
 
 	now := time.Now()
-	_, err = stmt.Exec(c.CustomerID, c.FirstName, c.MiddleName, c.LastName, c.NickName, c.Suffix, c.Type, birthDate, client.CUSTOMERSTATUS_UNKNOWN, c.Email, now, now, organization)
+	_, err = stmt.Exec(c.CustomerID, c.FirstName, c.MiddleName, c.LastName, c.NickName, c.Suffix, c.Type, c.BusinessName, c.DoingBusinessAs, c.BusinessType, c.EIN, c.DUNS, c.SICCode, c.NAICSCode, birthDate, client.CUSTOMERSTATUS_UNKNOWN, c.Email, c.Website, c.DateBusinessEstablished, now, now, organization)
 	if err != nil {
 		return fmt.Errorf("CreateCustomer: insert into customers err=%v | rollback=%v", err, tx.Rollback())
 	}
 
-	err = r.updatePhonesByCustomerID(tx, c.CustomerID, c.Phones)
+	err = r.updatePhonesByOwnerID(tx, c.CustomerID, client.OWNERTYPE_CUSTOMER, c.Phones)
 	if err != nil {
 		return fmt.Errorf("updating customer's phones: %v", err)
 	}
 
-	err = r.updateAddressesByCustomerID(tx, c.CustomerID, c.Addresses)
+	err = r.updateAddressesByOwnerID(tx, c.CustomerID, client.OWNERTYPE_CUSTOMER, c.Addresses)
 	if err != nil {
 		return fmt.Errorf("updating customer's addresses: %v", err)
 	}
 
+	err = r.updateRepresentativesByCustomerID(tx, c.CustomerID, c.Representatives)
+	if err != nil {
+		return fmt.Errorf("updating customer's representatives: %v", err)
+	}
+
 	if err := tx.Commit(); err != nil {
 		return fmt.Errorf("CreateCustomer: tx.Commit: %v", err)
 	}
@@ -549,8 +656,8 @@ func (r *sqlCustomerRepository) updateCustomer(c *client.Customer, organization
 	}
 	defer tx.Rollback()
 
-	query := `update customers set first_name = ?, middle_name = ?, last_name = ?, nick_name = ?, suffix = ?, type = ?, birth_date = ?, status = ?, email =?,
-	last_modified = ?,
+	query := `update customers set first_name = ?, middle_name = ?, last_name = ?, nick_name = ?, suffix = ?, type = ?, business_name = ?, doing_business_as = ?, business_type = ?, ein = ?, duns = ?, sic_code = ?, naics_code = ?, birth_date = ?, status = ?, email =?,
+	website = ?, date_business_established = ?, last_modified = ?,
 	organization = ? where customer_id = ? and deleted_at is null;`
 	stmt, err := tx.Prepare(query)
 	if err != nil {
@@ -559,7 +666,7 @@ func (r *sqlCustomerRepository) updateCustomer(c *client.Customer, organization
 	defer stmt.Close()
 
 	now := time.Now()
-	res, err := stmt.Exec(c.FirstName, c.MiddleName, c.LastName, c.NickName, c.Suffix, c.Type, c.BirthDate, c.Status, c.Email, now, organization, c.CustomerID)
+	res, err := stmt.Exec(c.FirstName, c.MiddleName, c.LastName, c.NickName, c.Suffix, c.Type, c.BusinessName, c.DoingBusinessAs, c.BusinessType, c.EIN, c.DUNS, c.SICCode, c.NAICSCode, c.BirthDate, c.Status, c.Email, c.Website, c.DateBusinessEstablished, now, organization, c.CustomerID)
 	if err != nil {
 		return fmt.Errorf("updating customer: %v", err)
 	}
@@ -573,26 +680,31 @@ func (r *sqlCustomerRepository) updateCustomer(c *client.Customer, organization
 		return fmt.Errorf("no records to update with customer id=%s", c.CustomerID)
 	}
 
-	err = r.updatePhonesByCustomerID(tx, c.CustomerID, c.Phones)
+	err = r.updatePhonesByOwnerID(tx, c.CustomerID, client.OWNERTYPE_CUSTOMER, c.Phones)
 	if err != nil {
 		return fmt.Errorf("updating customer's phones: %v", err)
 	}
 
-	err = r.updateAddressesByCustomerID(tx, c.CustomerID, c.Addresses)
+	err = r.updateAddressesByOwnerID(tx, c.CustomerID, client.OWNERTYPE_CUSTOMER, c.Addresses)
 	if err != nil {
 		return fmt.Errorf("updating customer's addresses: %v", err)
 	}
 
+	err = r.updateRepresentativesByCustomerID(tx, c.CustomerID, c.Representatives)
+	if err != nil {
+		return fmt.Errorf("updating customer's representatives: %v", err)
+	}
+
 	if err := tx.Commit(); err != nil {
 		return fmt.Errorf("CreateCustomer: tx.Commit: %v", err)
 	}
 	return nil
 }
 
-func (r *sqlCustomerRepository) updatePhonesByCustomerID(tx *sql.Tx, customerID string, phones []client.Phone) error {
-	deleteQuery := `delete from customers_phones where customer_id = ?`
+func (r *sqlCustomerRepository) updatePhonesByOwnerID(tx *sql.Tx, ownerID string, ownerType client.OwnerType, phones []client.Phone) error {
+	deleteQuery := `delete from phones where owner_id = ? and owner_type = ?`
 	var args []interface{}
-	args = append(args, customerID)
+	args = append(args, ownerID, ownerType)
 	if len(phones) > 0 {
 		deleteQuery = fmt.Sprintf("%s and number not in (?%s)", deleteQuery, strings.Repeat(",?", len(phones)-1))
 		for _, p := range phones {
@@ -612,7 +724,7 @@ func (r *sqlCustomerRepository) updatePhonesByCustomerID(tx *sql.Tx, customerID
 		return fmt.Errorf("executing query: %v", err)
 	}
 
-	replaceQuery := `replace into customers_phones (customer_id, number, valid, type) values (?, ?, ?, ?);`
+	replaceQuery := `replace into phones (owner_id, owner_type, number, valid, type) values (?, ?, ?, ?, ?);`
 	stmt, err = tx.Prepare(replaceQuery)
 	if err != nil {
 		return fmt.Errorf("preparing query: %v", err)
@@ -620,7 +732,7 @@ func (r *sqlCustomerRepository) updatePhonesByCustomerID(tx *sql.Tx, customerID
 	defer stmt.Close()
 
 	for _, phone := range phones {
-		_, err := stmt.Exec(customerID, phone.Number, phone.Valid, phone.Type)
+		_, err := stmt.Exec(ownerID, string(ownerType), phone.Number, phone.Valid, phone.Type)
 		if err != nil {
 			return fmt.Errorf("executing update on customer's phone: %v", err)
 		}
@@ -629,10 +741,10 @@ func (r *sqlCustomerRepository) updatePhonesByCustomerID(tx *sql.Tx, customerID
 	return nil
 }
 
-func (r *sqlCustomerRepository) updateAddressesByCustomerID(tx *sql.Tx, customerID string, addresses []client.CustomerAddress) error {
-	deleteQuery := `delete from customers_addresses where customer_id = ?`
+func (r *sqlCustomerRepository) updateAddressesByOwnerID(tx *sql.Tx, ownerID string, ownerType client.OwnerType, addresses []client.Address) error {
+	deleteQuery := `delete from addresses where owner_id = ? and owner_type = ?`
 	var args []interface{}
-	args = append(args, customerID)
+	args = append(args, ownerID, ownerType)
 	if len(addresses) > 0 {
 		deleteQuery = fmt.Sprintf("%s and address1 not in (?%s)", deleteQuery, strings.Repeat(",?", len(addresses)-1))
 		for _, a := range addresses {
@@ -652,8 +764,7 @@ func (r *sqlCustomerRepository) updateAddressesByCustomerID(tx *sql.Tx, customer
 		panic(err)
 	}
 
-	replaceQuery := `replace into customers_addresses(address_id, customer_id, type, address1, address2, city, state, postal_code, country, validated) values (?, ?, ?, ?, ?, ?, ?, ?,
-	?, ?);`
+	replaceQuery := `replace into addresses(address_id, owner_id, owner_type, type, address1, address2, city, state, postal_code, country, validated) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`
 	stmt, err = tx.Prepare(replaceQuery)
 	if err != nil {
 		return fmt.Errorf("preparing query: %v", err)
@@ -661,7 +772,38 @@ func (r *sqlCustomerRepository) updateAddressesByCustomerID(tx *sql.Tx, customer
 	defer stmt.Close()
 
 	for _, addr := range addresses {
-		_, err := stmt.Exec(addr.AddressID, customerID, addr.Type, addr.Address1, addr.Address2, addr.City, addr.State, addr.PostalCode, addr.Country, addr.Validated)
+		_, err := stmt.Exec(addr.AddressID, ownerID, string(ownerType), addr.Type, addr.Address1, addr.Address2, addr.City, addr.State, addr.PostalCode, addr.Country, addr.Validated)
+		if err != nil {
+			return fmt.Errorf("executing query: %v", err)
+		}
+	}
+
+	return nil
+}
+
+func (r *sqlCustomerRepository) updateRepresentativesByCustomerID(tx *sql.Tx, customerID string, representatives []client.Representative) error {
+	deleteQuery := `delete from representatives where customer_id = ?;`
+
+	stmt, err := tx.Prepare(deleteQuery)
+	if err != nil {
+		return fmt.Errorf("preparing query: %v", err)
+	}
+	defer stmt.Close()
+
+	_, err = stmt.Exec(customerID)
+	if err != nil {
+		panic(err)
+	}
+
+	replaceQuery := `replace into representatives(representative_id, customer_id, first_name, last_name, job_title, birth_date) values (?, ?, ?, ?, ?, ?);`
+	stmt, err = tx.Prepare(replaceQuery)
+	if err != nil {
+		return fmt.Errorf("preparing query: %v", err)
+	}
+	defer stmt.Close()
+
+	for _, rep := range representatives {
+		_, err := stmt.Exec(rep.RepresentativeID, customerID, rep.FirstName, rep.LastName, rep.JobTitle, rep.BirthDate)
 		if err != nil {
 			return fmt.Errorf("executing query: %v", err)
 		}
@@ -753,26 +895,26 @@ func (r *sqlCustomerRepository) replaceCustomerMetadata(customerID string, metad
 	return nil
 }
 
-func (r *sqlCustomerRepository) addCustomerAddress(customerID string, req address) error {
-	query := `insert into customers_addresses (address_id, customer_id, type, address1, address2, city, state, postal_code, country, validated) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`
+func (r *sqlCustomerRepository) addAddress(ownerID string, ownerType client.OwnerType, req address) error {
+	query := `insert into addresses (address_id, owner_id, owner_type, type, address1, address2, city, state, postal_code, country, validated) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`
 	stmt, err := r.db.Prepare(query)
 	if err != nil {
-		return fmt.Errorf("createCustomerAddress: prepare: %v", err)
+		return fmt.Errorf("addAddress: prepare: %v", err)
 	}
 	defer stmt.Close()
 
-	if _, err := stmt.Exec(base.ID(), customerID, req.Type, req.Address1, req.Address2, req.City, req.State, req.PostalCode, req.Country, false); err != nil {
-		return fmt.Errorf("createCustomerAddress: exec: %v", err)
+	if _, err := stmt.Exec(base.ID(), ownerID, string(ownerType), req.Type, req.Address1, req.Address2, req.City, req.State, req.PostalCode, req.Country, false); err != nil {
+		return fmt.Errorf("addAddress: exec: %v", err)
 	}
 	return nil
 }
 
-func (r *sqlCustomerRepository) updateCustomerAddress(customerID, addressID string, req updateCustomerAddressRequest) error {
-	query := `update customers_addresses set type = ?, address1 = ?, address2 = ?, city = ?, state = ?, postal_code = ?, country = ?,
-	validated = ? where customer_id = ? and address_id = ? and deleted_at is null;`
+func (r *sqlCustomerRepository) updateAddress(ownerID, addressID string, ownerType client.OwnerType, req updateAddressRequest) error {
+	query := `update addresses set type = ?, address1 = ?, address2 = ?, city = ?, state = ?, postal_code = ?, country = ?,
+	validated = ? where owner_id = ? and owner_type = ? and address_id = ? and deleted_at is null;`
 	stmt, err := r.db.Prepare(query)
 	if err != nil {
-		return fmt.Errorf("updateCustomerAddress: prepare: %v", err)
+		return fmt.Errorf("updateAddress: prepare: %v", err)
 	}
 	defer stmt.Close()
 
@@ -785,23 +927,24 @@ func (r *sqlCustomerRepository) updateCustomerAddress(customerID, addressID stri
 		req.PostalCode,
 		req.Country,
 		req.Validated,
-		customerID,
+		ownerID,
+		string(ownerType),
 		addressID)
 	if err != nil {
-		return fmt.Errorf("updateCustomerAddress: exec: %v", err)
+		return fmt.Errorf("updateAddress: exec: %v", err)
 	}
 	return nil
 }
 
-func (r *sqlCustomerRepository) deleteCustomerAddress(customerID string, addressID string) error {
-	query := `update customers_addresses set deleted_at = ? where customer_id = ? and address_id = ? and deleted_at is null;`
+func (r *sqlCustomerRepository) deleteAddress(ownerID string, ownerType client.OwnerType, addressID string) error {
+	query := `update addresses set deleted_at = ? where owner_id = ? and owner_type = ? and address_id = ? and deleted_at is null;`
 	stmt, err := r.db.Prepare(query)
 	if err != nil {
 		return err
 	}
 	defer stmt.Close()
 
-	_, err = stmt.Exec(time.Now(), customerID, addressID)
+	_, err = stmt.Exec(time.Now(), ownerID, string(ownerType), addressID)
 	return err
 }
 
diff --git a/pkg/route/customer_representatives.go b/pkg/route/customer_representatives.go
new file mode 100644
index 0000000..ac1720e
--- /dev/null
+++ b/pkg/route/customer_representatives.go
@@ -0,0 +1,27 @@
+// Copyright 2020 The Moov Authors
+// Use of this source code is governed by an Apache License
+// license that can be found in the LICENSE file.
+
+package route
+
+import (
+	"errors"
+	"net/http"
+
+	moovhttp "github.com/moov-io/base/http"
+
+	"github.com/gorilla/mux"
+)
+
+var (
+	ErrNoRepresentativeID = errors.New("no Representative ID found")
+)
+
+func GetRepresentativeID(w http.ResponseWriter, r *http.Request) string {
+	v, ok := mux.Vars(r)["representativeID"]
+	if !ok || v == "" {
+		moovhttp.Problem(w, ErrNoRepresentativeID)
+		return ""
+	}
+	return v
+}
diff --git a/version.go b/version.go
index 655a15d..81892ff 100644
--- a/version.go
+++ b/version.go
@@ -5,4 +5,4 @@
 package customers
 
 // Version number
-const Version = "v0.6.0-dev"
+const Version = "v0.5.0"


Test patch:
diff --git a/pkg/customers/address_test.go b/pkg/customers/address_test.go
index 0bdbcc1..7ae3c5f 100644
--- a/pkg/customers/address_test.go
+++ b/pkg/customers/address_test.go
@@ -15,7 +15,7 @@ import (
 	"github.com/moov-io/customers/pkg/client"
 )
 
-func TestCustomers__addCustomerAddress(t *testing.T) {
+func TestCustomers__addAddress(t *testing.T) {
 	db := createTestCustomerRepository(t)
 	repo := NewCustomerRepo(log.NewNopLogger(), db.db)
 
@@ -35,6 +35,7 @@ func TestCustomers__addCustomerAddress(t *testing.T) {
 		PostalCode: "12345",
 		Country:    "USA",
 		Type:       "primary",
+		OwnerType:  "customer",
 	}
 	payload, err := json.Marshal(addrPayload)
 	require.NoError(t, err)
@@ -52,9 +53,10 @@ func TestCustomers__addCustomerAddress(t *testing.T) {
 	var customerResp *client.Customer
 	require.NoError(t, json.Unmarshal(w.Body.Bytes(), &customerResp))
 	got := customerResp.Addresses[0]
-	want := client.CustomerAddress{
+	want := client.Address{
 		AddressID:  got.AddressID,
 		Type:       addrPayload.Type,
+		OwnerType:  client.OWNERTYPE_CUSTOMER,
 		Address1:   addrPayload.Address1,
 		Address2:   addrPayload.Address2,
 		City:       addrPayload.City,
@@ -80,7 +82,7 @@ func TestCustomers__addCustomerAddress(t *testing.T) {
 	require.Contains(t, errResp.ErrorMsg, ErrAddressTypeDuplicate.Error())
 }
 
-func TestCustomers__updateCustomerAddress(t *testing.T) {
+func TestCustomers__updateAddress(t *testing.T) {
 	db := createTestCustomerRepository(t)
 	repo := NewCustomerRepo(log.NewNopLogger(), db.db)
 
@@ -112,7 +114,7 @@ func TestCustomers__updateCustomerAddress(t *testing.T) {
 		},
 	}
 	for _, req := range addrRequests {
-		require.NoError(t, repo.addCustomerAddress(cust.CustomerID, req))
+		require.NoError(t, repo.addAddress(cust.CustomerID, client.OWNERTYPE_CUSTOMER, req))
 		cust, err = repo.GetCustomer(cust.CustomerID, organization) // refresh customer object after updating address
 		require.NoError(t, err)
 	}
@@ -128,9 +130,10 @@ func TestCustomers__updateCustomerAddress(t *testing.T) {
 		}
 	}
 
-	updateReq := updateCustomerAddressRequest{
+	updateReq := updateAddressRequest{
 		address: address{
 			Type:       "primary",
+			OwnerType:  "customer",
 			Address1:   "555 5th st",
 			City:       "Denver",
 			State:      "CO",
@@ -159,15 +162,16 @@ func TestCustomers__updateCustomerAddress(t *testing.T) {
 	var customerResp *client.Customer
 	require.NoError(t, json.Unmarshal(res.Body.Bytes(), &customerResp))
 
-	var got client.CustomerAddress
+	var got client.Address
 	for _, a := range customerResp.Addresses {
 		if a.AddressID == primaryAddressID {
 			got = a
 		}
 	}
-	want := client.CustomerAddress{
+	want := client.Address{
 		AddressID:  got.AddressID,
 		Type:       updateReq.Type,
+		OwnerType:  updateReq.OwnerType,
 		Address1:   updateReq.Address1,
 		Address2:   updateReq.Address2,
 		City:       updateReq.City,
@@ -196,7 +200,7 @@ func TestCustomers__updateCustomerAddress(t *testing.T) {
 	require.Contains(t, errResp.ErrorMsg, ErrAddressTypeDuplicate.Error())
 }
 
-func TestCustomers__deleteCustomerAddress(t *testing.T) {
+func TestCustomers__deleteAddress(t *testing.T) {
 	db := createTestCustomerRepository(t)
 	repo := NewCustomerRepo(log.NewNopLogger(), db.db)
 
@@ -217,7 +221,7 @@ func TestCustomers__deleteCustomerAddress(t *testing.T) {
 		Country:    "USA",
 		Type:       "primary",
 	}
-	require.NoError(t, repo.addCustomerAddress(cust.CustomerID, address))
+	require.NoError(t, repo.addAddress(cust.CustomerID, client.OWNERTYPE_CUSTOMER, address))
 
 	cust, err = repo.GetCustomer(cust.CustomerID, organization)
 	require.NoError(t, err)
@@ -246,7 +250,7 @@ func TestCustomers__updateCustomerAddressFailure(t *testing.T) {
 
 	w := httptest.NewRecorder()
 	req := httptest.NewRequest("GET", "/customers/foo/address/bar", nil)
-	updateCustomerAddress(log.NewNopLogger(), repo)(w, req)
+	updateAddress(log.NewNopLogger(), client.OWNERTYPE_CUSTOMER, repo)(w, req)
 	w.Flush()
 
 	if w.Code != http.StatusBadRequest {
@@ -256,7 +260,7 @@ func TestCustomers__updateCustomerAddressFailure(t *testing.T) {
 	// try the proper HTTP verb
 	w = httptest.NewRecorder()
 	req = httptest.NewRequest("PUT", "/customers/foo/address/bar", nil)
-	updateCustomerAddress(log.NewNopLogger(), repo)(w, req)
+	updateAddress(log.NewNopLogger(), client.OWNERTYPE_CUSTOMER, repo)(w, req)
 	w.Flush()
 
 	if w.Code != http.StatusBadRequest {
@@ -264,7 +268,7 @@ func TestCustomers__updateCustomerAddressFailure(t *testing.T) {
 	}
 }
 
-func TestCustomerRepository__updateCustomerAddress(t *testing.T) {
+func TestCustomerRepository__updateAddress(t *testing.T) {
 	db := createTestCustomerRepository(t)
 	repo := NewCustomerRepo(log.NewNopLogger(), db.db)
 
@@ -285,15 +289,16 @@ func TestCustomerRepository__updateCustomerAddress(t *testing.T) {
 		Country:    "USA",
 		Type:       "primary",
 	}
-	require.NoError(t, repo.addCustomerAddress(cust.CustomerID, addrRequest))
+	require.NoError(t, repo.addAddress(cust.CustomerID, client.OWNERTYPE_CUSTOMER, addrRequest))
 
 	cust, err = repo.GetCustomer(cust.CustomerID, organization)
 	require.NoError(t, err)
 
 	addressID := cust.Addresses[0].AddressID
-	updateReq := updateCustomerAddressRequest{
+	updateReq := updateAddressRequest{
 		address: address{
 			Type:       "primary",
+			OwnerType:  "customer",
 			Address1:   "555 5th st",
 			City:       "Denver",
 			State:      "CO",
@@ -302,16 +307,17 @@ func TestCustomerRepository__updateCustomerAddress(t *testing.T) {
 		},
 		Validated: true,
 	}
-	err = repo.updateCustomerAddress(cust.CustomerID, addressID, updateReq)
+	err = repo.updateAddress(cust.CustomerID, addressID, client.OWNERTYPE_CUSTOMER, updateReq)
 	require.NoError(t, err)
 
 	cust, err = repo.GetCustomer(cust.CustomerID, organization)
 	require.NoError(t, err)
 
 	require.Len(t, cust.Addresses, 1)
-	want := client.CustomerAddress{
+	want := client.Address{
 		AddressID:  addressID,
 		Type:       updateReq.Type,
+		OwnerType:  updateReq.OwnerType,
 		Address1:   updateReq.Address1,
 		Address2:   updateReq.Address2,
 		City:       updateReq.City,
@@ -324,7 +330,7 @@ func TestCustomerRepository__updateCustomerAddress(t *testing.T) {
 	require.Equal(t, want, got)
 }
 
-func TestCustomerRepository__deleteCustomerAddress(t *testing.T) {
+func TestCustomerRepository__deleteAddress(t *testing.T) {
 	db := createTestCustomerRepository(t)
 	repo := NewCustomerRepo(log.NewNopLogger(), db.db)
 
@@ -345,13 +351,13 @@ func TestCustomerRepository__deleteCustomerAddress(t *testing.T) {
 		Country:    "USA",
 		Type:       "primary",
 	}
-	require.NoError(t, repo.addCustomerAddress(cust.CustomerID, address))
+	require.NoError(t, repo.addAddress(cust.CustomerID, client.OWNERTYPE_CUSTOMER, address))
 
 	cust, err = repo.GetCustomer(cust.CustomerID, organization)
 	require.NoError(t, err)
 
 	addressID := cust.Addresses[0].AddressID
-	err = repo.deleteCustomerAddress(cust.CustomerID, addressID)
+	err = repo.deleteAddress(cust.CustomerID, client.OWNERTYPE_CUSTOMER, addressID)
 	require.NoError(t, err)
 
 	cust, err = repo.GetCustomer(cust.CustomerID, organization)
diff --git a/pkg/customers/customer_representative_ssn_test.go b/pkg/customers/customer_representative_ssn_test.go
new file mode 100644
index 0000000..8575b3b
--- /dev/null
+++ b/pkg/customers/customer_representative_ssn_test.go
@@ -0,0 +1,92 @@
+// Copyright 2020 The Moov Authors
+// Use of this source code is governed by an Apache License
+// license that can be found in the LICENSE file.
+
+package customers
+
+import (
+	"encoding/base64"
+	"github.com/moov-io/customers/pkg/client"
+	"testing"
+
+	"github.com/moov-io/base/database"
+
+	"github.com/moov-io/base"
+	"github.com/moov-io/base/log"
+)
+
+func TestRepresentativeSSNStorage(t *testing.T) {
+	storage := testCustomerSSNStorage(t)
+
+	if _, err := storage.encryptRaw("", client.OWNERTYPE_REPRESENTATIVE, ""); err == nil {
+		t.Errorf("expected error")
+	}
+	if _, err := storage.encryptRaw(base.ID(), client.OWNERTYPE_REPRESENTATIVE, ""); err == nil {
+		t.Errorf("expected error")
+	}
+
+	// encrypt SSN
+	representativeID := base.ID()
+	ssn, err := storage.encryptRaw(representativeID, client.OWNERTYPE_REPRESENTATIVE, "987654321")
+	if err != nil {
+		t.Error(err)
+	}
+	if ssn.ownerID != representativeID {
+		t.Errorf("ssn.ownerID=%s", ssn.ownerID)
+	}
+	if ssn.masked != "9#######1" {
+		t.Errorf("ssn.masked=%s", ssn.masked)
+	}
+
+	decrypted, err := storage.keeper.DecryptString(ssn.encrypted)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if decrypted != "987654321" {
+		t.Errorf("decrypted SSN=%s", decrypted)
+	}
+}
+
+func TestRepresentativeSSNRepository(t *testing.T) {
+	representativeID := base.ID()
+	ownerType := client.OWNERTYPE_REPRESENTATIVE
+	check := func(t *testing.T, customerSSNRepo *sqlSSNRepository) {
+
+		if ssn, err := customerSSNRepo.getSSN(representativeID, ownerType); ssn != nil || err != nil {
+			t.Fatalf("ssn=%v error=%v", ssn, err)
+		}
+
+		// write
+		bs := base64.StdEncoding.EncodeToString([]byte("987654321"))
+		ssn := &SSN{ownerID: representativeID, ownerType: ownerType, encrypted: bs, masked: "9#######1"}
+		if err := customerSSNRepo.saveSSN(ssn); err != nil {
+			t.Fatal(err)
+		}
+
+		// read again
+		ssn, err := customerSSNRepo.getSSN(representativeID, ownerType)
+		if ssn == nil || err != nil {
+			t.Fatalf("ssn=%v error=%v", ssn, err)
+		}
+		out, err := base64.StdEncoding.DecodeString(string(ssn.encrypted))
+		if err != nil {
+			t.Fatal(err)
+		}
+		if v := string(out); v != "987654321" {
+			t.Errorf("ssn.encrypte=%s", v)
+		}
+		if ssn.masked != "9#######1" {
+			t.Errorf("ssn.masked=%s", ssn.masked)
+		}
+	}
+
+	// SQLite tests
+	sqliteDB := database.CreateTestSqliteDB(t)
+	defer sqliteDB.Close()
+	check(t, &sqlSSNRepository{sqliteDB.DB, log.NewNopLogger()})
+
+	// MySQL tests
+	mysqlDB := database.CreateTestMySQLDB(t)
+	defer mysqlDB.Close()
+	check(t, &sqlSSNRepository{mysqlDB.DB, log.NewNopLogger()})
+}
diff --git a/pkg/customers/customer_representatives_test.go b/pkg/customers/customer_representatives_test.go
new file mode 100644
index 0000000..605b38d
--- /dev/null
+++ b/pkg/customers/customer_representatives_test.go
@@ -0,0 +1,559 @@
+// Copyright 2020 The Moov Authors
+// Use of this source code is governed by an Apache License
+// license that can be found in the LICENSE file.
+
+package customers
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/http/httptest"
+	"strings"
+	"testing"
+
+	"github.com/stretchr/testify/require"
+
+	"github.com/moov-io/base/database"
+
+	"github.com/moov-io/customers/pkg/client"
+
+	"github.com/gorilla/mux"
+	"github.com/moov-io/base/log"
+)
+
+func setupMockOrganizationCustomerAndRepresentative(t *testing.T, repo *sqlCustomerRepository) (string, *client.Customer, *client.Representative) {
+	organization := "best-business"
+	cust, _, _ := (customerRequest{
+		FirstName:    "Jane",
+		LastName:     "Doe",
+		Email:        "jane@example.com",
+		BusinessName: "Best Business",
+		BusinessType: client.BUSINESSTYPE_CORPORATION,
+		EIN:          "123-456-789",
+	}).asCustomer(testCustomerSSNStorage(t))
+	if err := repo.CreateCustomer(cust, organization); err != nil {
+		t.Fatal(err)
+	}
+
+	rep, _, _ := (customerRepresentativeRequest{
+		CustomerID: cust.CustomerID,
+		FirstName:  "Jane",
+		LastName:   "Doe",
+		JobTitle:   "CEO",
+	}).asRepresentative(testCustomerSSNStorage(t))
+	if err := repo.CreateRepresentative(rep, cust.CustomerID); err != nil {
+		t.Fatal(err)
+	}
+
+	return organization, cust, rep
+}
+
+func setupMockCustomer(t *testing.T, repo *sqlCustomerRepository) (*client.Customer, string) {
+	organization := "best-business"
+	cust, _, _ := (customerRequest{
+		FirstName:    "Jane",
+		LastName:     "Doe",
+		Email:        "jane@example.com",
+		BusinessName: "Best Business",
+		BusinessType: client.BUSINESSTYPE_CORPORATION,
+		EIN:          "123-456-789",
+	}).asCustomer(testCustomerSSNStorage(t))
+	if err := repo.CreateCustomer(cust, organization); err != nil {
+		t.Fatal(err)
+	}
+
+	return cust, organization
+}
+
+func TestCustomers__DeleteRepresentative(t *testing.T) {
+	repo := createTestCustomerRepository(t)
+	defer repo.close()
+
+	_, cust, rep := setupMockOrganizationCustomerAndRepresentative(t, repo)
+
+	got, err := repo.GetRepresentative(rep.RepresentativeID)
+	require.NoError(t, err)
+	require.NotNil(t, got)
+
+	router := mux.NewRouter()
+	w := httptest.NewRecorder()
+	req := httptest.NewRequest("DELETE", fmt.Sprintf("/customers/%s/representatives/%s", cust.CustomerID, rep.RepresentativeID), nil)
+
+	AddRepresentativeRoutes(log.NewNopLogger(), router, repo, testCustomerSSNStorage(t))
+	router.ServeHTTP(w, req)
+	w.Flush()
+
+	require.Equal(t, http.StatusNoContent, w.Code)
+	require.Empty(t, w.Body)
+	got, err = repo.GetRepresentative(rep.RepresentativeID)
+	require.Error(t, err)
+	require.Nil(t, got)
+}
+
+func TestCustomerRepository__CreateRepresentative(t *testing.T) {
+	check := func(t *testing.T, repo *sqlCustomerRepository) {
+		organization, cust, rep := setupMockOrganizationCustomerAndRepresentative(t, repo)
+
+		cust, err := repo.GetCustomer(cust.CustomerID, organization)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if cust == nil {
+			t.Error("got nil Customer")
+		}
+
+		rep, err = repo.GetRepresentative(rep.RepresentativeID)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if rep == nil {
+			t.Error("got nil Representative")
+		}
+	}
+
+	// SQLite tests
+	sqliteDB := database.CreateTestSqliteDB(t)
+	defer sqliteDB.Close()
+	check(t, &sqlCustomerRepository{sqliteDB.DB, log.NewNopLogger()})
+
+	// MySQL tests
+	mysqlDB := database.CreateTestMySQLDB(t)
+	defer mysqlDB.Close()
+	check(t, &sqlCustomerRepository{mysqlDB.DB, log.NewNopLogger()})
+}
+
+func TestCustomers__customerRepresentativeRequest(t *testing.T) {
+	req := &customerRepresentativeRequest{JobTitle: "awesome job title"}
+	if err := req.validate(); err == nil {
+		t.Error("expected error")
+	}
+	req.FirstName = "jane"
+	if err := req.validate(); err == nil {
+		t.Error("expected error")
+	}
+
+	req.LastName = "doe"
+	if err := req.validate(); err != nil {
+		t.Errorf("unexpected error: %v", err)
+	}
+
+	req.Phones = append(req.Phones, phone{
+		Number:    "123.456.7890",
+		Type:      "mobile",
+		OwnerType: "customer",
+	})
+	if err := req.validate(); err != nil {
+		t.Errorf("unexpected error: %v", err)
+	}
+
+	req.Addresses = append(req.Addresses, address{
+		Address1:   "123 1st st",
+		City:       "fake city",
+		State:      "CA",
+		PostalCode: "90210",
+		Country:    "US",
+		Type:       "primary",
+		OwnerType:  client.OWNERTYPE_REPRESENTATIVE,
+	})
+	if err := req.validate(); err != nil {
+		t.Errorf("unexpected error: %v", err)
+	}
+
+	// asCustomer
+	representative, _, _ := req.asRepresentative(testCustomerSSNStorage(t))
+	if representative.RepresentativeID == "" {
+		t.Errorf("empty Customer Representative: %#v", representative)
+	}
+	if len(representative.Phones) != 1 {
+		t.Errorf("representative.Phones: %#v", representative.Phones)
+	}
+	if len(representative.Addresses) != 1 {
+		t.Errorf("representative.Addresses: %#v", representative.Addresses)
+	}
+}
+
+func TestCustomers__CreateRepresentative(t *testing.T) {
+	repo := createTestCustomerRepository(t)
+	defer repo.close()
+
+	newCust, organization := setupMockCustomer(t, repo)
+	if newCust.CustomerID == "" {
+		t.Error("empty Customer.CustomerID")
+	}
+
+	w := httptest.NewRecorder()
+	phone := `{"number": "555.555.5555", "type": "mobile", "ownerType": "representative"}`
+	address := `{"type": "primary", "ownerType": "representative", "address1": "123 1st St", "city": "Denver", "state": "CO", "postalCode": "12345", "country": "USA"}`
+	body := fmt.Sprintf(`{"firstName": "jane", "lastName": "doe", "birthDate": "1991-04-01", "ssn": "987654321", "phones": [%s], "addresses": [%s]}`, phone, address)
+	req := httptest.NewRequest("POST", fmt.Sprintf("/customers/%s/representatives", newCust.CustomerID), strings.NewReader(body))
+	req.Header.Set("x-organization", organization)
+	req.Header.Set("x-request-id", "test")
+
+	customerSSNStorage := testCustomerSSNStorage(t)
+
+	router := mux.NewRouter()
+	AddRepresentativeRoutes(log.NewNopLogger(), router, repo, customerSSNStorage)
+	router.ServeHTTP(w, req)
+	w.Flush()
+
+	if w.Code != http.StatusOK {
+		t.Errorf("bogus status code: %d: %v", w.Code, w.Body.String())
+	}
+
+	var cust *client.Customer
+	if err := json.NewDecoder(w.Body).Decode(&cust); err != nil {
+		t.Fatal(err)
+	}
+	if cust.CustomerID == "" {
+		t.Error("empty Customer.CustomerID")
+	}
+
+	// sad path
+	w = httptest.NewRecorder()
+	req = httptest.NewRequest("POST", fmt.Sprintf("/customers/%s/representatives", newCust.CustomerID), strings.NewReader("null"))
+	req.Header.Set("x-organization", "test")
+	req.Header.Set("x-request-id", "test")
+	router.ServeHTTP(w, req)
+	w.Flush()
+
+	if w.Code != http.StatusBadRequest {
+		t.Fatalf("bogus HTTP status code: %d", w.Code)
+	}
+
+	// customerSSNStorage sad path
+	w = httptest.NewRecorder()
+	req = httptest.NewRequest("POST", fmt.Sprintf("/customers/%s/representatives", newCust.CustomerID), strings.NewReader(body))
+	req.Header.Set("x-organization", "test")
+
+	if r, ok := customerSSNStorage.repo.(*testCustomerSSNRepository); !ok {
+		t.Fatalf("got %T", customerSSNStorage.repo)
+	} else {
+		r.err = errors.New("bad error")
+	}
+	router.ServeHTTP(w, req)
+	w.Flush()
+
+	if w.Code != http.StatusBadRequest {
+		t.Errorf("bogus HTTP status code: %d: %v", w.Code, w.Body.String())
+	}
+	if s := w.Body.String(); !strings.Contains(s, "saveSSN: ") {
+		t.Errorf("unexpected error: %v", s)
+	}
+}
+
+func TestCustomers__updateRepresentative(t *testing.T) {
+	repo := createTestCustomerRepository(t)
+	defer repo.close()
+
+	organization := "best-business"
+	createCustomerReq := &customerRequest{
+		FirstName:    "Jane",
+		LastName:     "Doe",
+		Email:        "jane@example.com",
+		BusinessName: "Best Business",
+		BusinessType: client.BUSINESSTYPE_CORPORATION,
+		EIN:          "123-456-789",
+	}
+	cust, _, _ := createCustomerReq.asCustomer(testCustomerSSNStorage(t))
+	if err := repo.CreateCustomer(cust, organization); err != nil {
+		t.Fatal(err)
+	}
+
+	createRepresentativeReq := &customerRepresentativeRequest{
+		CustomerID: cust.CustomerID,
+		FirstName:  "Jane",
+		LastName:   "Doe",
+		JobTitle:   "CEO",
+		Phones: []phone{
+			{
+				Number:    "123.456.7890",
+				Type:      "mobile",
+				OwnerType: "representative",
+			},
+		},
+		Addresses: []address{
+			{
+				Address1:   "123 1st st",
+				City:       "fake city",
+				State:      "CA",
+				PostalCode: "90210",
+				Country:    "US",
+				Type:       "primary",
+				OwnerType:  "representative",
+			},
+		},
+	}
+	rep, _, _ := createRepresentativeReq.asRepresentative(testCustomerSSNStorage(t))
+	if err := repo.CreateRepresentative(rep, cust.CustomerID); err != nil {
+		t.Fatal(err)
+	}
+
+	_, err := repo.GetRepresentative(rep.RepresentativeID)
+	require.NoError(t, err)
+
+	router := mux.NewRouter()
+	w := httptest.NewRecorder()
+
+	updateReq := *createRepresentativeReq
+	updateReq.RepresentativeID = rep.RepresentativeID
+	updateReq.FirstName = "Jim"
+	updateReq.LastName = "Smith"
+	updateReq.JobTitle = "CEO"
+	updateReq.BirthDate = "2020-01-01"
+	updateReq.Phones = []phone{
+		{
+			Number:    "555.555.5555",
+			Type:      "mobile",
+			OwnerType: "representative",
+		},
+	}
+	updateReq.Addresses = []address{
+		{
+			Address1:   "555 5th st",
+			City:       "real city",
+			State:      "CA",
+			PostalCode: "90210",
+			Country:    "US",
+			Type:       "primary",
+			OwnerType:  "representative",
+		},
+	}
+	payload, err := json.Marshal(&updateReq)
+	require.NoError(t, err)
+
+	req := httptest.NewRequest("PUT", fmt.Sprintf("/customers/%s/representatives/%s", cust.CustomerID, rep.RepresentativeID), bytes.NewReader(payload))
+	req.Header.Set("x-organization", organization)
+	req.Header.Set("x-request-id", "test")
+	AddRepresentativeRoutes(log.NewNopLogger(), router, repo, testCustomerSSNStorage(t))
+	router.ServeHTTP(w, req)
+	w.Flush()
+	require.Equal(t, http.StatusOK, w.Code)
+
+	var got *client.Representative
+	require.NoError(t, json.NewDecoder(w.Body).Decode(&got))
+	want, _, _ := updateReq.asRepresentative(testCustomerSSNStorage(t))
+	require.NoError(t, err)
+	require.Equal(t, want, got)
+
+	/* Error when settings two addresses as primary */
+	updateReq.Addresses = []address{
+		{
+			Address1:   "555 5th st",
+			City:       "real city",
+			State:      "CA",
+			PostalCode: "90210",
+			Country:    "US",
+			Type:       "primary",
+			OwnerType:  "representative",
+		},
+		{
+			Address1:   "444 4th st",
+			City:       "real city",
+			State:      "CA",
+			PostalCode: "90210",
+			Country:    "US",
+			Type:       "primary",
+			OwnerType:  "representative",
+		},
+	}
+	payload, err = json.Marshal(&updateReq)
+	require.NoError(t, err)
+	req = req.Clone(context.Background())
+	req.Body = ioutil.NopCloser(bytes.NewReader(payload))
+	w = httptest.NewRecorder()
+	router.ServeHTTP(w, req)
+	require.Equal(t, http.StatusBadRequest, w.Code)
+	var errResp struct {
+		ErrorMsg string `json:"error"`
+	}
+	require.NoError(t, json.Unmarshal(w.Body.Bytes(), &errResp))
+	require.Contains(t, errResp.ErrorMsg, ErrAddressTypeDuplicate.Error())
+}
+
+func TestCustomerRepository__updateRepresentative(t *testing.T) {
+	repo := createTestCustomerRepository(t)
+	defer repo.close()
+
+	organization := "best-business"
+	createReq := &customerRequest{
+		FirstName:    "Jane",
+		LastName:     "Doe",
+		Email:        "jane@example.com",
+		BusinessName: "Best Business",
+		BusinessType: client.BUSINESSTYPE_CORPORATION,
+		EIN:          "123-456-789",
+	}
+	cust, _, _ := createReq.asCustomer(testCustomerSSNStorage(t))
+	if err := repo.CreateCustomer(cust, organization); err != nil {
+		t.Fatal(err)
+	}
+
+	createRepresentativeReq := &customerRepresentativeRequest{
+		CustomerID: cust.CustomerID,
+		FirstName:  "Jane",
+		LastName:   "Doe",
+		JobTitle:   "CEO",
+		Phones: []phone{
+			{
+				Number: "123.456.7890",
+				Type:   "mobile",
+			},
+		},
+		Addresses: []address{
+			{
+				Address1:   "123 1st st",
+				City:       "fake city",
+				State:      "CA",
+				PostalCode: "90210",
+				Country:    "US",
+				Type:       "primary",
+				OwnerType:  "customer",
+			},
+		},
+	}
+	rep, _, _ := createRepresentativeReq.asRepresentative(testCustomerSSNStorage(t))
+	err := repo.CreateRepresentative(rep, cust.CustomerID)
+	require.NoError(t, err)
+
+	updateReq := customerRepresentativeRequest{
+		RepresentativeID: rep.RepresentativeID,
+		CustomerID:       cust.CustomerID,
+		FirstName:        "Jim",
+		LastName:         "Smith",
+		Phones: []phone{
+			{
+				Number:    "555.555.5555",
+				Type:      "mobile",
+				OwnerType: "customer",
+			},
+		},
+		Addresses: []address{
+			{
+				Address1:  "555 5th st",
+				City:      "real city",
+				Type:      "primary",
+				OwnerType: "customer",
+			},
+		},
+	}
+
+	updatedRep, _, _ := updateReq.asRepresentative(testCustomerSSNStorage(t))
+	err = repo.updateRepresentative(updatedRep, cust.CustomerID)
+	require.NoError(t, err)
+
+	require.Equal(t, updateReq.FirstName, updatedRep.FirstName)
+	require.Equal(t, updateReq.LastName, updatedRep.LastName)
+	require.Equal(t, updateReq.Phones[0].Number, updatedRep.Phones[0].Number)
+	require.Equal(t, updateReq.Addresses[0].Address1, updatedRep.Addresses[0].Address1)
+	require.Equal(t, updateReq.Addresses[0].City, updatedRep.Addresses[0].City)
+}
+
+func TestCustomersRepository__addRepresentativeAddress(t *testing.T) {
+	repo := createTestCustomerRepository(t)
+	defer repo.close()
+
+	organization := "best-business"
+	createReq := &customerRequest{
+		FirstName:    "Jane",
+		LastName:     "Doe",
+		Email:        "jane@example.com",
+		BusinessName: "Best Business",
+		BusinessType: client.BUSINESSTYPE_CORPORATION,
+		EIN:          "123-456-789",
+	}
+	cust, _, _ := createReq.asCustomer(testCustomerSSNStorage(t))
+	if err := repo.CreateCustomer(cust, organization); err != nil {
+		t.Fatal(err)
+	}
+
+	createRepresentativeReq := &customerRepresentativeRequest{
+		CustomerID: cust.CustomerID,
+		FirstName:  "Jane",
+		LastName:   "Doe",
+		JobTitle:   "CEO",
+		Phones: []phone{
+			{
+				Number: "123.456.7890",
+				Type:   "mobile",
+			},
+		},
+	}
+	rep, _, _ := createRepresentativeReq.asRepresentative(testCustomerSSNStorage(t))
+	if err := repo.CreateRepresentative(rep, cust.CustomerID); err != nil {
+		t.Fatal(err)
+	}
+
+	// add an address
+	if err := repo.addAddress(rep.RepresentativeID, client.OWNERTYPE_REPRESENTATIVE, address{
+		Address1:   "123 1st st",
+		City:       "fake city",
+		State:      "CA",
+		PostalCode: "90210",
+		Country:    "US",
+		Type:       "primary",
+		OwnerType:  "representative",
+	},
+	); err != nil {
+		t.Fatal(err)
+	}
+
+	// re-read
+	rep, err := repo.GetRepresentative(rep.RepresentativeID)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(rep.Addresses) != 1 {
+		t.Errorf("got %d Addresses", len(rep.Addresses))
+	}
+	if rep.Addresses[0].Address1 != "123 1st st" {
+		t.Errorf("rep.Addresses[0].Address1=%s", rep.Addresses[0].Address1)
+	}
+}
+
+func TestRepresentatives__minimumFields(t *testing.T) {
+	repo := createTestCustomerRepository(t)
+	defer repo.close()
+
+	organization, cust, _ := setupMockOrganizationCustomerAndRepresentative(t, repo)
+
+	w := httptest.NewRecorder()
+	body := `{"firstName": "jane", "lastName": "doe"}`
+	req := httptest.NewRequest("POST", fmt.Sprintf("/customers/%s/representatives", cust.CustomerID), strings.NewReader(body))
+	req.Header.Set("x-organization", organization)
+	req.Header.Set("x-request-id", "test")
+
+	router := mux.NewRouter()
+	AddRepresentativeRoutes(log.NewNopLogger(), router, repo, testCustomerSSNStorage(t))
+	router.ServeHTTP(w, req)
+	w.Flush()
+
+	if w.Code != http.StatusOK {
+		t.Errorf("bogus status code: %d: %v", w.Code, w.Body.String())
+	}
+}
+
+func TestRepresentatives__BadReq(t *testing.T) {
+	repo := createTestCustomerRepository(t)
+	defer repo.close()
+
+	organization, cust, _ := setupMockOrganizationCustomerAndRepresentative(t, repo)
+
+	w := httptest.NewRecorder()
+	req := httptest.NewRequest("POST", fmt.Sprintf("/customers/%s/representatives", cust.CustomerID), strings.NewReader("®"))
+	req.Header.Set("x-organization", organization)
+	req.Header.Set("x-request-id", "test")
+
+	router := mux.NewRouter()
+	AddRepresentativeRoutes(log.NewNopLogger(), router, repo, testCustomerSSNStorage(t))
+	router.ServeHTTP(w, req)
+	w.Flush()
+
+	if !strings.Contains(w.Body.String(), "invalid character") {
+		t.Errorf("Expected SSN error received %s", w.Body.String())
+	}
+}
diff --git a/pkg/customers/customer_search_test.go b/pkg/customers/customer_search_test.go
index 3b6c622..f0f442d 100644
--- a/pkg/customers/customer_search_test.go
+++ b/pkg/customers/customer_search_test.go
@@ -86,18 +86,21 @@ func TestRepository__searchCustomers(t *testing.T) {
 	org := "test"
 	createCustomer := func(repo CustomerRepository, i int) *client.Customer {
 		var req = &customerRequest{
-			FirstName: fmt.Sprintf("jane-%d", i),
-			LastName:  fmt.Sprintf("doe-%d", i),
-			Email:     fmt.Sprintf("jane-%d@moov.com", i),
+			FirstName:    fmt.Sprintf("jane-%d", i),
+			LastName:     fmt.Sprintf("doe-%d", i),
+			Email:        fmt.Sprintf("jane-%d@moov.com", i),
+			BusinessName: fmt.Sprintf("janes-business-%d", i),
 			Phones: []phone{
 				{
-					Number: "555-555-5555",
-					Type:   "primary",
+					Number:    "555-555-5555",
+					Type:      "primary",
+					OwnerType: "customer",
 				},
 			},
 			Addresses: []address{
 				{
 					Type:       "primary",
+					OwnerType:  "customer",
 					Address1:   "123 Cool St.",
 					City:       "San Francisco",
 					State:      "CA",
@@ -105,6 +108,20 @@ func TestRepository__searchCustomers(t *testing.T) {
 					Country:    "US",
 				},
 			},
+			Representatives: []customerRepresentative{
+				{
+					FirstName: "Jane",
+					LastName:  "Doe",
+					Phones: []phone{
+						{
+							Number:    "555-555-5555",
+							Type:      "primary",
+							OwnerType: "representative",
+						},
+					},
+					JobTitle: "CEO",
+				},
+			},
 			Metadata: map[string]string{"key": "val"},
 		}
 		cust, _, _ := req.asCustomer(testCustomerSSNStorage(t))
diff --git a/pkg/customers/customer_ssn_test.go b/pkg/customers/customer_ssn_test.go
index fefe3f9..2aebf0b 100644
--- a/pkg/customers/customer_ssn_test.go
+++ b/pkg/customers/customer_ssn_test.go
@@ -6,6 +6,7 @@ package customers
 
 import (
 	"encoding/base64"
+	"github.com/moov-io/customers/pkg/client"
 	"testing"
 
 	"github.com/moov-io/base/database"
@@ -29,11 +30,11 @@ type testCustomerSSNRepository struct {
 	ssn *SSN
 }
 
-func (r *testCustomerSSNRepository) saveCustomerSSN(*SSN) error {
+func (r *testCustomerSSNRepository) saveSSN(*SSN) error {
 	return r.err
 }
 
-func (r *testCustomerSSNRepository) getCustomerSSN(customerID string) (*SSN, error) {
+func (r *testCustomerSSNRepository) getSSN(ownerID string, ownerType client.OwnerType) (*SSN, error) {
 	if r.ssn != nil {
 		return r.ssn, nil
 	}
@@ -43,21 +44,21 @@ func (r *testCustomerSSNRepository) getCustomerSSN(customerID string) (*SSN, err
 func TestCustomerSSNStorage(t *testing.T) {
 	storage := testCustomerSSNStorage(t)
 
-	if _, err := storage.encryptRaw("", ""); err == nil {
+	if _, err := storage.encryptRaw("", client.OWNERTYPE_CUSTOMER, ""); err == nil {
 		t.Errorf("expected error")
 	}
-	if _, err := storage.encryptRaw(base.ID(), ""); err == nil {
+	if _, err := storage.encryptRaw(base.ID(), client.OWNERTYPE_CUSTOMER, ""); err == nil {
 		t.Errorf("expected error")
 	}
 
 	// encrypt SSN
 	customerID := base.ID()
-	ssn, err := storage.encryptRaw(customerID, "123456789")
+	ssn, err := storage.encryptRaw(customerID, client.OWNERTYPE_CUSTOMER, "123456789")
 	if err != nil {
 		t.Error(err)
 	}
-	if ssn.customerID != customerID {
-		t.Errorf("ssn.customerID=%s", ssn.customerID)
+	if ssn.ownerID != customerID {
+		t.Errorf("ssn.ownerID=%s", ssn.ownerID)
 	}
 	if ssn.masked != "1#######9" {
 		t.Errorf("ssn.masked=%s", ssn.masked)
@@ -74,21 +75,22 @@ func TestCustomerSSNStorage(t *testing.T) {
 
 func TestCustomerSSNRepository(t *testing.T) {
 	customerID := base.ID()
-	check := func(t *testing.T, customerSSNRepo *sqlCustomerSSNRepository) {
+	ownerType := client.OWNERTYPE_CUSTOMER
+	check := func(t *testing.T, customerSSNRepo *sqlSSNRepository) {
 
-		if ssn, err := customerSSNRepo.getCustomerSSN(customerID); ssn != nil || err != nil {
+		if ssn, err := customerSSNRepo.getSSN(customerID, ownerType); ssn != nil || err != nil {
 			t.Fatalf("ssn=%v error=%v", ssn, err)
 		}
 
 		// write
 		bs := base64.StdEncoding.EncodeToString([]byte("123456789"))
-		ssn := &SSN{customerID: customerID, encrypted: bs, masked: "1#######9"}
-		if err := customerSSNRepo.saveCustomerSSN(ssn); err != nil {
+		ssn := &SSN{ownerID: customerID, ownerType: ownerType, encrypted: bs, masked: "1#######9"}
+		if err := customerSSNRepo.saveSSN(ssn); err != nil {
 			t.Fatal(err)
 		}
 
 		// read again
-		ssn, err := customerSSNRepo.getCustomerSSN(customerID)
+		ssn, err := customerSSNRepo.getSSN(customerID, ownerType)
 		if ssn == nil || err != nil {
 			t.Fatalf("ssn=%v error=%v", ssn, err)
 		}
@@ -107,10 +109,10 @@ func TestCustomerSSNRepository(t *testing.T) {
 	// SQLite tests
 	sqliteDB := database.CreateTestSqliteDB(t)
 	defer sqliteDB.Close()
-	check(t, &sqlCustomerSSNRepository{sqliteDB.DB, log.NewNopLogger()})
+	check(t, &sqlSSNRepository{sqliteDB.DB, log.NewNopLogger()})
 
 	// MySQL tests
 	mysqlDB := database.CreateTestMySQLDB(t)
 	defer mysqlDB.Close()
-	check(t, &sqlCustomerSSNRepository{mysqlDB.DB, log.NewNopLogger()})
+	check(t, &sqlSSNRepository{mysqlDB.DB, log.NewNopLogger()})
 }
diff --git a/pkg/customers/customers_test.go b/pkg/customers/customers_test.go
index 69f0b3e..e00513b 100644
--- a/pkg/customers/customers_test.go
+++ b/pkg/customers/customers_test.go
@@ -39,6 +39,8 @@ type testCustomerRepository struct {
 	createdCustomer   *client.Customer
 	updatedStatus     client.CustomerStatus
 	savedSearchResult *client.OfacSearch
+
+	customerRepresentative *client.Representative
 }
 
 func (r *testCustomerRepository) GetCustomer(customerID, organization string) (*client.Customer, error) {
@@ -82,15 +84,15 @@ func (r *testCustomerRepository) replaceCustomerMetadata(customerID string, meta
 	return r.err
 }
 
-func (r *testCustomerRepository) addCustomerAddress(customerID string, address address) error {
+func (r *testCustomerRepository) addAddress(ownerID string, ownerType client.OwnerType, address address) error {
 	return r.err
 }
 
-func (r *testCustomerRepository) updateCustomerAddress(customerID, addressID string, req updateCustomerAddressRequest) error {
+func (r *testCustomerRepository) updateAddress(ownerID, addressID string, ownerType client.OwnerType, req updateAddressRequest) error {
 	return r.err
 }
 
-func (r *testCustomerRepository) deleteCustomerAddress(customerID string, addressID string) error {
+func (r *testCustomerRepository) deleteAddress(ownerID string, ownerType client.OwnerType, addressID string) error {
 	return r.err
 }
 
@@ -109,6 +111,25 @@ func (r *testCustomerRepository) saveCustomerOFACSearch(customerID string, resul
 	return r.err
 }
 
+func (r *testCustomerRepository) GetRepresentative(representativeID string) (*client.Representative, error) {
+	if r.err != nil {
+		return nil, r.err
+	}
+	return r.customerRepresentative, nil
+}
+
+func (r *testCustomerRepository) CreateRepresentative(c *client.Representative, customerID string) error {
+	return r.err
+}
+
+func (r *testCustomerRepository) updateRepresentative(c *client.Representative, customerID string) error {
+	return r.err
+}
+
+func (r *testCustomerRepository) deleteRepresentative(representativeID string) error {
+	return r.err
+}
+
 func TestCustomers__formatCustomerName(t *testing.T) {
 	if out := formatCustomerName(nil); out != "" {
 		t.Errorf("got %q", out)
@@ -295,8 +316,9 @@ func TestCustomers__customerRequest(t *testing.T) {
 	}
 
 	req.Phones = append(req.Phones, phone{
-		Number: "123.456.7890",
-		Type:   "mobile",
+		Number:    "123.456.7890",
+		Type:      "mobile",
+		OwnerType: "customer",
 	})
 	if err := req.validate(); err != nil {
 		t.Errorf("unexpected error: %v", err)
@@ -309,6 +331,7 @@ func TestCustomers__customerRequest(t *testing.T) {
 		PostalCode: "90210",
 		Country:    "US",
 		Type:       "primary",
+		OwnerType:  "customer",
 	})
 	if err := req.validate(); err != nil {
 		t.Errorf("unexpected error: %v", err)
@@ -328,7 +351,7 @@ func TestCustomers__customerRequest(t *testing.T) {
 }
 
 func TestCustomers__addressValidate(t *testing.T) {
-	add := address{Type: "primary"}
+	add := address{Type: "primary", OwnerType: "customer"}
 
 	add.State = "IA"
 	if err := add.validate(); err != nil {
@@ -343,8 +366,8 @@ func TestCustomers__addressValidate(t *testing.T) {
 
 func TestCustomers__CreateCustomer(t *testing.T) {
 	w := httptest.NewRecorder()
-	phone := `{"number": "555.555.5555", "type": "mobile"}`
-	address := `{"type": "primary", "address1": "123 1st St", "city": "Denver", "state": "CO", "postalCode": "12345", "country": "USA"}`
+	phone := `{"number": "555.555.5555", "type": "mobile", "ownerType": "customer"}`
+	address := `{"type": "primary", "ownerType": "customer", "address1": "123 1st St", "city": "Denver", "state": "CO", "postalCode": "12345", "country": "USA"}`
 	body := fmt.Sprintf(`{"firstName": "jane", "lastName": "doe", "email": "jane@example.com", "birthDate": "1991-04-01", "ssn": "123456789", "type": "individual", "phones": [%s], "addresses": [%s]}`, phone, address)
 	req := httptest.NewRequest("POST", "/customers", strings.NewReader(body))
 	req.Header.Set("x-organization", "test")
@@ -419,8 +442,9 @@ func TestCustomers__updateCustomer(t *testing.T) {
 		SSN:       "123456789",
 		Phones: []phone{
 			{
-				Number: "123.456.7890",
-				Type:   "mobile",
+				Number:    "123.456.7890",
+				Type:      "mobile",
+				OwnerType: "customer",
 			},
 		},
 		Addresses: []address{
@@ -431,6 +455,7 @@ func TestCustomers__updateCustomer(t *testing.T) {
 				PostalCode: "90210",
 				Country:    "US",
 				Type:       "primary",
+				OwnerType:  "customer",
 			},
 		},
 	}
@@ -452,8 +477,9 @@ func TestCustomers__updateCustomer(t *testing.T) {
 	updateReq.BirthDate = "2020-01-01"
 	updateReq.Phones = []phone{
 		{
-			Number: "555.555.5555",
-			Type:   "mobile",
+			Number:    "555.555.5555",
+			Type:      "mobile",
+			OwnerType: "customer",
 		},
 	}
 	updateReq.Addresses = []address{
@@ -464,6 +490,7 @@ func TestCustomers__updateCustomer(t *testing.T) {
 			PostalCode: "90210",
 			Country:    "US",
 			Type:       "primary",
+			OwnerType:  "customer",
 		},
 	}
 	payload, err := json.Marshal(&updateReq)
@@ -499,6 +526,7 @@ func TestCustomers__updateCustomer(t *testing.T) {
 			PostalCode: "90210",
 			Country:    "US",
 			Type:       "primary",
+			OwnerType:  "customer",
 		},
 		{
 			Address1:   "444 4th st",
@@ -507,6 +535,7 @@ func TestCustomers__updateCustomer(t *testing.T) {
 			PostalCode: "90210",
 			Country:    "US",
 			Type:       "primary",
+			OwnerType:  "customer",
 		},
 	}
 	payload, err = json.Marshal(&updateReq)
@@ -550,8 +579,9 @@ func TestCustomers__repository(t *testing.T) {
 		Email:     "jane@example.com",
 		Phones: []phone{
 			{
-				Number: "123.456.7890",
-				Type:   "mobile",
+				Number:    "123.456.7890",
+				Type:      "mobile",
+				OwnerType: "customer",
 			},
 		},
 		Addresses: []address{
@@ -654,8 +684,9 @@ func TestCustomerRepository__updateCustomer(t *testing.T) {
 		Email:     "jane@example.com",
 		Phones: []phone{
 			{
-				Number: "123.456.7890",
-				Type:   "mobile",
+				Number:    "123.456.7890",
+				Type:      "mobile",
+				OwnerType: "customer",
 			},
 		},
 		Addresses: []address{
@@ -679,15 +710,17 @@ func TestCustomerRepository__updateCustomer(t *testing.T) {
 		Email:      "jim@google.com",
 		Phones: []phone{
 			{
-				Number: "555.555.5555",
-				Type:   "mobile",
+				Number:    "555.555.5555",
+				Type:      "mobile",
+				OwnerType: "customer",
 			},
 		},
 		Addresses: []address{
 			{
-				Address1: "555 5th st",
-				City:     "real city",
-				Type:     "primary",
+				Address1:  "555 5th st",
+				City:      "real city",
+				Type:      "primary",
+				OwnerType: "customer",
 			},
 		},
 	}
@@ -734,7 +767,7 @@ func TestCustomerRepository__updateCustomerStatus(t *testing.T) {
 	}
 }
 
-func TestCustomersRepository__addCustomerAddress(t *testing.T) {
+func TestCustomersRepository__addAddress(t *testing.T) {
 	repo := createTestCustomerRepository(t)
 	defer repo.close()
 
@@ -749,13 +782,14 @@ func TestCustomersRepository__addCustomerAddress(t *testing.T) {
 	}
 
 	// add an address
-	if err := repo.addCustomerAddress(cust.CustomerID, address{
+	if err := repo.addAddress(cust.CustomerID, client.OWNERTYPE_CUSTOMER, address{
 		Address1:   "123 1st st",
 		City:       "fake city",
 		State:      "CA",
 		PostalCode: "90210",
 		Country:    "US",
 		Type:       "primary",
+		OwnerType:  "customer",
 	},
 	); err != nil {
 		t.Fatal(err)
@@ -1022,6 +1056,7 @@ func mockCustomerRequest() customerRequest {
 	p := phone{}
 	p.Number = "123-456-7892"
 	p.Type = "mobile"
+	p.OwnerType = "customer"
 	c.Phones = append(c.Phones, p)
 
 	a := address{}
@@ -1031,6 +1066,7 @@ func mockCustomerRequest() customerRequest {
 	a.Country = "USA"
 	a.PostalCode = "19456"
 	a.State = "MA"
+	a.OwnerType = "customer"
 	c.Addresses = append(c.Addresses, a)
 	return c
 }
diff --git a/pkg/route/customer_representatives_test.go b/pkg/route/customer_representatives_test.go
new file mode 100644
index 0000000..0386bae
--- /dev/null
+++ b/pkg/route/customer_representatives_test.go
@@ -0,0 +1,19 @@
+// Copyright 2020 The Moov Authors
+// Use of this source code is governed by an Apache License
+// license that can be found in the LICENSE file.
+
+package route
+
+import (
+	"net/http/httptest"
+	"testing"
+)
+
+func TestCustomers__GetRepresentativeID(t *testing.T) {
+	w := httptest.NewRecorder()
+	req := httptest.NewRequest("GET", "/ping", nil)
+
+	if id := GetRepresentativeID(w, req); id != "" {
+		t.Errorf("unexpected id: %v", id)
+	}
+}