# Member Model

Standard member JSON model returned from many API endpoints.

### Example

```json
{
  "id": 42,
  "properties": {
    "first_name": "Ola",
    "last_name": "Nordmann",
    "birthday": "1990-10-23",
    "interests": [
      "bikes_and_cars",
      "sportwear"
    ],
    "child_birth_years": [
      2010,
      2011,
      2011
    ],
    "language": "no"
  },
  "consents": {
    "consent1": { "status": true, "updated_at": "2018-12-14T21:57:20.063Z" },
    "consent2": { "status": false, "updated_at": "2018-10-25T21:57:43.738Z" }
  },
  "sms_status": "enabled",
  "email_status": "hard_bounced",
  "push_status": "disabled",
  "optin_channel": "webforms",
  "optin_subchannel": "campaign-10-2017",
  "created_at": "2017-01-19T10:07:08.336+01:00",
  "updated_at": "2017-04-03T09:35:19.313+02:00",
  "banned_until": "2137-04-03T09:35:19.313+02:00",
  "person_id": 99,
  "has_password": false,
  "subunit_ids": [1, 2],
  "has_push_token": false,
  "social_logins": [],
  "favorite_stores": [1, 2]
}
```

Key | Description                                                                    | Type
--------- |--------------------------------------------------------------------------------| ---------
id | Member ID                                                                      | integer
properties | Object with member's properties                                                | JSON Object
properties\['language'\] | Language used by user                                                          | string
consents | Member's consents JSON model (see below)                                       | JSON Object
sms_status | Status of sms channel                                                          | string
email_status | Status of email channel                                                        | string
push_status | Status of push channel                                                         | string
optin_channel | Channel (`x-product-name` header) which had been used to register member       | string
optin_subchannel | Subchannel (`X-Subproduct-Name` header) which had been used to register member | string
created_at | Time when the user was firstly created                                         | string
updated_at | Time when the user was last updated                                            | string
banned_until | Time since member was/is banned (not updatable through OAuth)                  | string
person_id | Unique Member's identifier (set internally)                                    | string
has_password | Has this Member password set?                                                  | boolean
subunit_ids | Subunits the member belongs to. See [Subunits](doc-341674)            | integer[]
has_push_token | Has this Member push token set?           | boolean
social_logins | Member social login types          | string[]    
favorite_stores | Member favorite stores. See [Stores](doc-341692)            | integer[]

### Member's consents JSON model

JSON model for consents. Keys can be dynamically created based on customer's need.

It consists of: `'consent-slug': { "status": <boolean_value>, "updated_at": <time> }`

* If status is `true` - Member approved consent.
* If status is `false` - Member disapproved consent.
* If you can't find slug on Member: he/she haven't disapproved or approved consent.

`updated_at` is the time of last consent update. It can be also not provided or null.

Available consents for Loyalty Club are described in [schema](api-3510800).

### Validation on members

All members' endpoints have properties validation. Properties are validated to conform loyalty club's schema.

If something is wrong, you will receive explanation of errors in response.

### Schema validation errors

```shell
curl -X PUT -H "x-product-name: custom-product-name" \
  -H "X-Customer-Private-Token: token" \
  -H "content-type: application/json" -d '{
  "properties": {
    "first_name": "",
    "last_name": "err",
    "gender": "man",
    "birthday": "201X-01-01"
  }
}' "https://tbp.bstcm.no/api/v2/loyalty_clubs/:loyalty_club_slug/members/:msisdn"
```

> Example response (with code 400):

```json
{
  "email": [
    {
      "error": "invalid",
      "property": "email"
    }
  ],
  "properties": [
    {
      "error": {
        "language": [
          {
            "error": "value_not_match",
            "value": "een",
            "values": "en, no",
            "property": "language"
          }
        ],
        "optin_channel": [
          {
            "error": "not_contain_required_property",
            "property": "optin_channel"
          }
        ]
      }
    }
  ]
}
```

Error | Description
-------|------------
required | Required property is missing
invalid_date_format | Invalid date format
invalid_time_format | Invalid time format
invalid_date_time_format | Invalid date with time format
must_be_valid_RFC3339_date_time_string | Format beyond the RFC3339 standard
invalid_URI | Invalid URI
additional_array_elements | Additional elements in the array
additional_properties | Additional properties
property_not_match_all_of | The property did not match all of the required schemas
property_not_match_any_of | The property did not match any of the required schema
property_matched_more_than_one | The property matched more than one of the required schemas
depends_on_a_missing_property | The validated property has a property that depends on the other missing property
value_not_match | The property value did not match one of the given values.
schema_cannot_be_found | The extended schema cannot be found
not_a_valid_schema | The property was not a valid schema
minimum_string_length | The property was not of a minimum string length of minimum limit.
maximum_string_length | The property was not of a maximum string length of maximum limit.
less_item_than_minimum | The property did not contain a minimum number of minimum items limit 
more_item_than_maximum | The property had more items than the allowed items limit
less_properties_than_minimum | The property did not contain a minimum number of properties
more_properties_than_maximum | The property had more properties than allowed
not_have_value_of_exclusively | The property did not have value of exclusively
not_have_value_of_inclusively | The property did not have value of inclusively
more_decimal_places_than_maximum | The property had more decimal places than the allowed maximum
matched_the_disallowed_schema | The property matched the disallowed schema
the_regex_not_match | The property did not match the regex 
not_contain_required_property | The validated property did not contain a required property
contained_undefined_properties | The validated property contained undefined properties
referenced_schema_cannot_be_found | The referenced schema cannot be found
invalid_schema | The property was not a valid schema
matched_one_or_more_types | The property matched one or more of the given types
one_or_more_types_not_match | The property did not match one or more of the given types
type_not_match | The property did not match the given type
contained_duplicated_array_values | The property contained duplicated array values
invalid_email | Invalid email format
invalid_mx | Invalid (inaccessible) email domain
disposable_email | The email was [disposable](https://github.com/lisinge/valid_email2/blob/master/vendor/disposable_emails.yml)
duplicated_email | The email was duplicated in community
duplicated_msisdn_in_community | The msisdn was duplicated in community
duplicated_in_community | The value was duplicated in community
non_existing_stores_ids | There is no existing stores with given ids
minimum_years_since | The date is less than N years ago
