NAV
cURL

Introduction

Welcome to the HOALife API Documentation. HOALife's API is intended to be consumed by programmers to consume or generate data with the HOALife system.

While this documentation is comprehensive, access to some endpoints may not be included in all Customer Agreements. Contact sales@hoalife.com to learn more.

The API provides scoped Read, Write, Update, and Destroy actions for most resources.

JSON is the only currently supported response format, following the JSON:API spec. All responses will have the application/vnd.api+json content type. Any POST or PUT requests must specify the application/vnd.api+json Content-Type header.

API Clients

This API is completely accessible without an API Client, however, we do provide some API Clients to allow you to leverage this API without worrying about implementation details.

Ruby

The hoalife Ruby gem will seamlessly take care of this API's authentication, signature verification, rate limiting, pagination, and error handling.

$ gem install hoalife

View the README for usage details and examples.

Authentication

via HTTP Header

To authorize, use this code:

# With shell, you can just pass the correct header with each request
curl https://api.hoalife.com/api/ \
  -H "Authorization: Token sk_SUPERSECRET"

Make sure to replace sk_SUPERSECRET with your API key.

HOALife expects for the API key to be included in all API requests to the server in a header that looks like the following:

Authorization: Token sk_SUPERSECRET

via Basic Authentication

To authorize, use this code:

# cURL will encode the username and password in the header for you. YMMV with other libraries.
curl https://sk_SUPERSECRET:sk_SUPERSECRET@api.hoalife.com/api/

Make sure to replace sk_SUPERSECRET with your API key.

When using Basic Authentication, enter your API key for both the username and password. cURL will Base64 and encode these for you, sending the Authorization header as follows:

Authorization: Basic c2tfU1VQRVJTRUNSRVQ6c2tfU1VQRVJTRUNSRVQ=

via URL Parameter

To authorize, use this code:

# With shell, you can just pass the correct header with each request
curl https://api.hoalife.com/api/?api_key=sk_SUPERSECRET

Make sure to replace sk_SUPERSECRET with your API key.

Passing your API key via URL parameter is also possible. This is helpful when testing requests via a web browser.

Rate Limit

To ensure a consistent and reliable service, this API limits the number of requests per API key within a given time frame. The default limit is 1 requests per 2 seconds. The rate limit is enforced as a GCRA "Leaky Bucket". Higher volume rate limits are available per the Customer Agreement. Contact sales@hoalife.com to learn more.

Every request has HTTP headers to help you stay within limits and be a well-behaving API client. Exceeding these limits will result in a 429. Continued requests after a 429 may result in requests from your IP being blocked.

HTTP Header Name Description
X-RateLimit-Limit The maximum number of requests per period
X-RateLimit-Period The period, in seconds, that the limit is enforced
X-RateLimit-Used The number of consumed requests within the period
X-RateLimit-Remaining The number of remaining requests within the period

Accommodating the rate limit could be as simple as this pseudo-code
sleep 2sec if X-RateLimit-Remaining < 1.

Verify Authenticity

Paranoid? No problem. All responses provided by this API are signed via HMAC SHA256.

A signature is created by generating an HMAC of the raw response body with a SHA256 digest, using the shared Signing Secret. You'll find this signature in the HTTP header X-Signature.

def verified?
  digest = OpenSSL::Digest.new("sha256")
  OpenSSL::HMAC.hexdigest(digest, "ss_SUPERSECRET", response.body) == response.headers["X-Signature"]
end

Make sure to replace ss_SUPERSECRET with your provided Signing Secret.

Querying, Ordering, and Pagination

Querying

Most attributes of a resource are query-able so that you can filter resource collections based on an attribute. Include the attribute as a query parameter in the URL external_id=EXT42.

By default, exact matching will be used. If you'd like to craft an approximate query, you can specify the operator as part of the parameter value.

Operator Example SQL equivalent
default foo=4 foo = 4
gt foo=gt,4 foo > 4
gte foo=gte,4 foo >= 4
lt foo=lt,4 foo < 4
lte foo=lte,4 foo <= 4
ilike bar=ilike,%25BAZ%25 bar ILIKE %BAZ%
!= foo=!=,4 foo != 4

Ordering

You can specify the order of a resource collection by passing the order URL query parameter order=foo.

By default, the resource will be ordered by the created_at attribute in ascending order. You can specify the direction of the order clause by specifying asc or desc as part of the parameter value.

Operator Example SQL equivalent
default order=foo ORDER BY foo ASC
asc order=foo&order_dir=asc ORDER BY foo ASC
desc order=foo&order_dir=desc ORDER BY foo DESC

Pagination

Recourse collections are paginated, with 25 resources per page. Traversing pages can be done via the page=X URL query parameter.

There are a number of helpful attributes in a collection response to help you traverse pages. If you have specified order or query attributes, they will be reflected in the pagination links.

"meta": {
  "total": 167,
  "total_pages": 7
},
"links": {
  "self": "/api/accounts/1/properties?page=1",
  "next": "/api/accounts/1/properties?page=2",
  "prev": "/api/accounts/1/properties"
}

Accounts

Accounts represent both Associations which are managed, and Management companies.

Get All Accounts

curl "https://api.hoalife.com/api/accounts" \
  -H "Authorization: Token sk_SUPERSECRET"

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "1",
      "type": "account",
      "attributes": {
        "id": 1,
        "parent_id": null,
        "name": "XYZ HOA Management",
        "repeat_violation_strategy": "six_month_rolling_window",
        "escalation_threshold": 3,
        "violation_lookback_period": "two_months",
        "mailing_street_1": "123 HOALife Way",
        "mailing_street_2": null,
        "mailing_city": "Sun Valley",
        "mailing_state": "ID",
        "mailing_postal_code": "83313",
        "organizational": true,
        "external_id": null,
        "created_at": "2019-07-30T21:16:44.624Z",
        "updated_at": "2019-08-01T14:49:17.016Z"
      },
      "relationships": {}
    },
    {
      "id": "2",
      "type": "account",
      "attributes": {
        "id": 2,
        "parent_id": 1,
        "name": "Goodview HOA",
        "repeat_violation_strategy": "six_month_rolling_window",
        "escalation_threshold": null,
        "violation_lookback_period": null,
        "mailing_street_1": "123 Goodview Dr",
        "mailing_street_2": null,
        "mailing_city": "Ketchum",
        "mailing_state": "ID",
        "mailing_postal_code": "83340",
        "organizational": false,
        "external_id": null,
        "created_at": "2019-07-30T21:16:44.640Z",
        "updated_at": "2019-07-31T15:44:01.644Z"
      },
      "relationships": {}
    },
    {
      "id": "3",
      "type": "account",
      "attributes": {
        "id": 3,
        "parent_id": 1,
        "name": "Sleepyville HOA",
        "repeat_violation_strategy": "six_month_rolling_window",
        "escalation_threshold": null,
        "violation_lookback_period": null,
        "mailing_street_1": "123 Sleepy Ct",
        "mailing_street_2": null,
        "mailing_city": "Sun Valley",
        "mailing_state": "ID",
        "mailing_postal_code": "83353",
        "organizational": false,
        "external_id": null,
        "created_at": "2019-08-01T14:37:15.287Z",
        "updated_at": "2019-08-01T14:37:15.287Z"
      },
      "relationships": {}
    }
  ],
  "meta": {
    "current_page": 1,
    "total": 3,
    "total_pages": 1
  },
  "links": {
    "self": "/api/accounts?page=1",
    "next": "/api/accounts",
    "prev": "/api/accounts"
  }
}

This endpoint retrieves all Accounts accessible by the API key.

HTTP Request

GET https://api.hoalife.com/api/accounts

Attributes

Parameter Type Description
id Integer Unique identifier of an Account
parent_id Integer Unique identifier of parent organizational Account
name String Name of an Account
escalation_threshold Integer Number of repeat Violations which trigger the creation of an Escalation
mailing_street_1 String Mailing street address used on violation notices
mailing_street_2 String Mailing street address used on violation notices
mailing_city String Mailing city address used on violation notices
mailing_state String Mailing state address used on violation notices
mailing_postal_code String Mailing postal code address used on violation notices
repeat_violation_strategy String Strategy for calculating repeat Violations
violation_lookback_period Integer Number of days to warn about prior Violations
external_id String A unique identifier from an external system used to map the record
organizational Boolean Indicates if the Account is organizational (Management Company) or not (Association)

Query Parameters

Parameter Query By Order By
id true true
parent_id false false
name true true
escalation_threshold true true
mailing_street_1 true true
mailing_street_2 true true
mailing_city true true
mailing_state true true
mailing_postal_code true true
repeat_violation_strategy false false
violation_lookback_period false false
external_id true false
organizational false false

Create Account

curl "https://api.hoalife.com/api/accounts" \
  -X POST \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "account",
        "attributes": {
          "name": "Foo Bar22",
          "external_id": "123",
          "organizational": false
        },
        "relationships": {
          "parent": {
            "data": {
              "type": "account",
              "id": 5
            }
          }
        }
      }
    }
  '

The above command returns JSON structured like this:

{
  "data": {
    "id": "731",
    "type": "account",
    "attributes": {
      "id": 42,
      "name": "Foo Bar",
      "organizational": false,
      "created_at": "2019-08-12T23:53:04.537Z",
      "updated_at": "2019-08-12T23:53:04.537Z",
      "repeat_violation_strategy": "six_month_rolling_window",
      "external_id": "123",
      "parent_id": 5,
      "violation_lookback_period": 0,
      "escalation_threshold": null,
      "mailing_street_2": null,
      "mailing_street_1": null,
      "mailing_city": null,
      "mailing_state": null,
      "mailing_postal_code": null
    },
    "relationships": {}
  }
}

This endpoint creates a new Account.

HTTP Request

POST https://api.hoalife.com/api/accounts

Account Writable Attributes

Parameter Type Description Required
parent_id Integer Unique identifier of parent organizational Account true
name String Name of an Account true
external_id String A unique identifier from an external system used to map the record true
escalation_threshold Integer Number of repeat Violations which trigger the creation of an Escalation false
mailing_street_1 String Mailing street address used on violation notices false
mailing_street_2 String Mailing street address used on violation notices false
mailing_city String Mailing city address used on violation notices false
mailing_state String Mailing state address used on violation notices false
mailing_postal_code String Mailing postal code address used on violation notices false
repeat_violation_strategy String Strategy for calculating repeat Violations false
violation_lookback_period Integer Number of days to warn about prior Violations false
organizational Boolean Indicates if the Account is organizational (Management Company) or not (Association) false

Writable Attribute Requirements

Some attributes have strict requirements.

Parameter Options Default
repeat_violation_strategy consecutive, one_month_rolling_window, three_month_rolling_window, six_month_rolling_window, one_year_rolling_window six_month_rolling_window
violation_lookback_period 0, 30, 60, 90, 120, 150, 180, 365 0

Update Account

curl "https://api.hoalife.com/api/accounts/42" \
  -X PUT \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "account",
        "attributes": {
          "name": "Foo Bar22"
        }
      }
    }
  '

The above command will return updated JSON, just like for the Create action with a successful status code of 201 CREATED.

This endpoint updates an existing Account.

HTTP Request

PUT https://api.hoalife.com/api/accounts/:account_id

URL Parameters

Parameter Type Description
:account_id Integer Unique identifier of the Account the request is being made for

Editable Attributes

See Writable Attributes for the Create action. The parent Account cannot be changed.

Destroy Account

curl "https://api.hoalife.com/api/accounts/42" \
  -X DELETE \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json"

The above command will return an empty response successful response with a successful status code of 202 Accepted.

This endpoint destroys an existing Account. Because Account objects have many dependent resources, the actual deletion of the data is performed in a background process. This means that the API may continue to return data for the Account even after you've requested a it be deleted.

HTTP Request

DELETE https://api.hoalife.com/api/accounts/:account_id

URL Parameters

Parameter Type Description
:account_id Integer Unique identifier of the Account the request is being made for

Users

Users with access to the given Account and any child accounts.

Get All Users

curl "https://api.hoalife.com/api/users" \
  -H "Authorization: Token sk_SUPERSECRET"

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "1",
      "type": "user",
      "attributes": {
        "id": 1,
        "email": "admin@example.com",
        "first_name": "Bob",
        "last_name": "Admin",
        "timezone": "Mountain Time (US & Canada)",
        "authorizations": [
          {
            "id": 444,
            "account_id": 1,
            "role": "administrator"
          }
        ]
      }
    },
    {
      "id": "2",
      "type": "user",
      "attributes": {
        "id": 2,
        "email": "sub-account-manager@example.com",
        "first_name": "Jane",
        "last_name": "SubAccountManger",
        "timezone": "Pacific Time (US & Canada)",
        "authorizations": [
          {
            "id": 555,
            "account_id": 2,
            "role": "manager"
          },
          {
            "id": 556,
            "account_id": 3,
            "role": "manager"
          }
        ]
      }
    },
    {
      "id": "3",
      "type": "user",
      "attributes": {
        "id": 3,
        "email": "inspector@example.com",
        "first_name": "Sally",
        "last_name": "Inspector",
        "timezone": "Eastern Time (US & Canada)",
        "authorizations": [
          {
            "id": 777,
            "account_id": 4,
            "role": "inspector"
          }
        ]
      }
    }
  ],
  "meta": {
    "current_page": 1,
    "total": 3,
    "total_pages": 1
  },
  "links": {
    "self": "/api/users?page=1",
    "next": "/api/users",
    "prev": "/api/users"
  }
}

This endpoint retrieves all Users accessible by the API key. If the API key has access to multiple Accounts, all Users for all those accounts will be returned. Scope Users to a specific Account by adding an account_id query parameter. Users may have many authorizations to many different accounts.

HTTP Request

GET https://api.hoalife.com/api/users

Attributes

Parameter Type Description
id Integer Unique identifier of the User
email String Email address of the User
first_name String User's first name
last_name String User's last name
timezone String String representing a user's timezone
authorizations Array[Object] Accounts which the user has been authorized to access with a given role

Query Parameters

Parameter Query By Order By
id true true
email true true
first_name true true
last_name true true
account_id true false
role true false

User Authorizations

User Authorizations to the given Account and any child accounts.

Get All User Authorizations

curl "https://api.hoalife.com/api/users/authorizations" \
  -H "Authorization: Token sk_SUPERSECRET"

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "111",
      "type": "authorization",
      "attributes": {
        "id": 111,
        "role": "staff",
        "account_id": 1,
        "user": {
          "id": 1,
          "email": "bob@example.com",
          "first_name": "Bob",
          "last_name": "Smith",
          "timezone": "Mountain Time (US & Canada)"
        }
      },
      "relationships": {}
    },
    {
      "id": "222",
      "type": "authorization",
      "attributes": {
        "id": 222,
        "role": "read_only",
        "account_id": 1,
        "user": {
          "id": 2,
          "email": "boardmember@example.com",
          "first_name": "Board",
          "last_name": "Member",
          "timezone": "Mountain Time (US & Canada)"
        }
      },
      "relationships": {}
    },
  ],
  "meta": {
    "current_page": 1,
    "total": 2,
    "total_pages": 1
  },
  "links": {
    "self": "/api/users/authorizations?page=1",
    "next": "/api/users/authorizations",
    "prev": "/api/users/authorizations"
  }
}

This endpoint retrieves all User Authorizations accessible by the API key. If the API key has access to multiple Accounts, all User Authorizations for all those accounts will be returned. Scope User Authorizations to a specific Account by adding an account_id query parameter.

HTTP Request

GET https://api.hoalife.com/api/users/authorizations

Attributes

Parameter Type Description
id Integer Unique identifier of the User Authorization
role String The authorization level for the User
account_id Integer Unique identifier of the Account the Authorization is for
user Object Information about the User the Authorization is for

Query Parameters

Parameter Query By Order By
id true true
account_id true true
role true true
email true false
first_name true false
last_name true false

Create User Authorization

When creating a User Authorization, passing the user's information is recommended. If a User does not exist for a given email address, a user will be created. If the User does exist, the record will be looked up by the email attribute.

Alternatively, if the User already exists and you know the User's id, you can pass the id via a relationship. The former method is preferred to avoid an additional API request.

Only one Authorization per User per Account is possible. Per Account hierarchy branch User Authorizations are encouraged to scope a User's access. Multiple User Authorizations throughout the same Account hierarchy branch is possible, but not recommended.

Available roles are administrator, manager, staff, inspector, and read_only.

curl "https://api.hoalife.com/api/users/authorizations" \
  -X POST \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "authorization",
        "attributes": {
          "role": "read_only",
          "send_invitation_email": false,
          "user": {
            "first_name": "Bob",
            "last_name": "Smith",
            "email": "bob@example.com"
          }
        },
        "relationships": {
          "account": {
            "data": {
              "type": "account",
              "id": 5
            }
          }
        }
      }
    }
  '

# OR

curl "https://api.hoalife.com/api/users/authorizations" \
  -X POST \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "authorization",
        "attributes": {
          "role": "read_only",
          "send_invitation_email": false
        },
        "relationships": {
          "account": {
            "data": {
              "type": "account",
              "id": 5
            }
          },
          "user": {
            "data": {
              "type": "user",
              "id": 2
            }
          },
        }
      }
    }
  '

The above command returns JSON structured like this:

{
  "data": {
    "id": "3333",
    "type": "authorization",
    "attributes": {
      "id": 3333,
      "role": "read_only",
      "account_id": 5,
      "user": {
        "id": 1,
        "email": "bob@example.com",
        "first_name": "Bob",
        "last_name": "Smith",
        "timezone": "Mountain Time (US & Canada)"
      }
    }
  },
  "relationships": {}
  }
}

This endpoint creates a User Authorization.

HTTP Request

POST https://api.hoalife.com/api/users/authorizations

User Authorization Writable Attributes

Parameter Type Description Required
role String The authorization level for the User true
account_id Integer Unique identifier of the Account the Authorization is for true
User[first_name] String User's first name true
User[last_name] String User's last name true
User[email_name] String User's email true

Update User Authorization

curl "https://api.hoalife.com/api/users/authorization/42" \
  -X PUT \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "authorization",
        "attributes": {
          "role": "read_only"
        }
      }
    }
  '

The above command will return updated JSON, just like for the Create action with a successful status code of 201 CREATED.

This endpoint updates an existing User Authorization.

HTTP Request

PUT https://api.hoalife.com/api/users/authorization/:user_authorization_id

URL Parameters

Parameter Type Description
:user_authorization_id Integer Unique identifier of the User Authorization the request is being made for

Editable Attributes

Only the role attribute is editable for a User Authorization.

Destroy User Authorization

curl "https://api.hoalife.com/api/users/authorization/42" \
  -X DELETE \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json"

The above command will return an empty response successful response with a successful status code of 202 Accepted.

This endpoint destroys an existing User Authorization.

HTTP Request

DELETE https://api.hoalife.com/api/user_authorization/:user_authorization_id

URL Parameters

Parameter Type Description
:user_authorization_id Integer Unique identifier of the User Authorization the request is being made for

Properties

Properties represent a property or unit in an Association.

Get All Properties

curl "https://api.hoalife.com/api/properties" \
  -H "Authorization: Token sk_SUPERSECRET"

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "1",
      "type": "property",
      "attributes": {
        "id": 1,
        "account_id": 2,
        "formatted_id": "PRP-1",
        "street_1": "944 Awesome Street",
        "street_2": null,
        "city": "Sun Valley",
        "state": "ID",
        "postal_code": "83353",
        "override_geocoding": false,
        "latitude": "37.233333",
        "longitude": "-115.808333",
        "route_leg": null,
        "route": "Awesome Street",
        "emails": [
            "johnAndJudySmithOnFacebook@aol.com"
        ],
        "phone_numbers": [],
        "created_at": "2019-07-30T21:16:45.265Z",
        "updated_at": "2019-07-30T21:16:45.265Z",
        "mailing_name": "John and Judy Smith",
        "mailing_street_1": "944 Awesome Street",
        "mailing_street_2": null,
        "mailing_city": "Sun Valley",
        "mailing_state": "ID",
        "mailing_postal_code": "83353",
        "notes": [
            {
                "body_text": "Neighbor has complained about poor lawn hygiene.",
                "author": "John Owner",
                "pinned": true,
                "created_at": "2019-08-05T03:26:02.917Z"
            }
        ],
        "tags":[{"title":"Board Member","id":1,"color":"#6fa7ce"}],
        "external_id": null
      },
      "relationships": {}
    },
    ...
    {
      "id": "25",
      "type": "property",
      "attributes": {
        "id": 25,
        "account_id": 2,
        "formatted_id": "PRP-25",
        "street_1": "4242 Cowbell Drive",
        "street_2": null,
        "city": "Sun Valley",
        "state": "ID",
        "postal_code": "83353",
        "override_geocoding": false,
        "latitude": "37.233333",
        "longitude": "-115.808333",
        "route_leg": null,
        "route": "Cowbell Drive",
        "emails": [
            "earl-larae@cowbelldrive.com", "earl-larae@yahsnooze.com"
        ],
        "phone_numbers": [
            "+132155512345", "+132155512346"
        ],
        "created_at": "2019-07-30T21:16:45.460Z",
        "updated_at": "2019-07-30T21:16:45.460Z",
        "mailing_name": "Earl LaRae",
        "mailing_street_1": "PO BOX 42424242",
        "mailing_street_2": null,
        "mailing_city": "Sun Valley",
        "mailing_state": "ID",
        "mailing_postal_code": "83353",
        "notes": [],
        "tags": [],
        "external_id": null
      },
      "relationships": {}
    }
  ],
  "meta": {
    "current_page": 1,
    "total": 858,
    "total_pages": 35
  },
  "links": {
    "self": "/api/properties?page=1",
    "next": "/api/properties?page=2",
    "prev": "/api/properties"
  }
}

This endpoint retrieves all Properties accessible by the API key. If the API key has access to multiple Accounts, all Properties for all those accounts will be returned. Scope Properties to a specific Account by adding an account_id query parameter.

HTTP Request

GET https://api.hoalife.com/api/properties

Attributes

Parameter Type Description
id Integer Unique identifier of the Property
account_id Integer Unique identifier of Account the Property belongs to
formatted_id String Humanized unique identifier
street_1 String Street address of the property
street_2 String Street address of the property
city String City of the property
state String State of the property
postal_code String Postal code of the property
override_geocoding Boolean Manually specified latitude and longitude or attempt to geocode the property's address.
latitude String GPS Latitude coordinate
longitude String GPS Longitude coordinate
route_leg String Leg of a given route
route String Inspection route
emails Array[String] Array of strings of the property owner's email addresses
phone_numbers Array[String] Array of strings of the property owner's phone numbers
mailing_name String Mailing name of the property
mailing_street_1 String Mailing street address of the property
mailing_street_2 String Mailing street address of the property
mailing_city String Mailing city address of the property
mailing_state String Mailing state address of the property
mailing_postal_code String Mailing postal code address of the property
notes Array[Object] Property notes
tags Array[Object] Property tags
external_id String A unique identifier from an external system used to map the record

Query Parameters

Parameter Query By Order By
id true true
account_id true true
formatted_id true true
street_1 true true
street_2 true true
city true true
state true true
postal_code true true
override_geocoding true true
latitude true true
longitude true true
route_leg true true
route true true
emails false false
phone_numbers false false
mailing_name true true
mailing_street_1 true true
mailing_street_2 true true
mailing_city true true
mailing_state true true
mailing_postal_code true true
notes false false
tags false false
external_id true true

Create Property

curl "https://api.hoalife.com/api/properties" \
  -X POST \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "property",
        "attributes": {
          "street_1": "4242 Cowbell Drive",
          "city": "Sun Valley",
          "state": "ID",
          "postal_code": "83353",
          "external_id": "123"
        },
        "relationships": {
          "account": {
            "data": {
              "type": "account",
              "id": 5
            }
          }
        }
      }
    }
  '

The above command returns JSON structured like this:

{
  "data": {
      "id": "25",
      "type": "property",
      "attributes": {
        "id": 25,
        "account_id": 5,
        "formatted_id": "PRP-25",
        "street_1": "4242 Cowbell Drive",
        "street_2": null,
        "city": "Sun Valley",
        "state": "ID",
        "postal_code": "83353",
        "override_geocoding": false,
        "latitude": "37.233333",
        "longitude": "-115.808333",
        "route_leg": null,
        "route": "Cowbell Drive",
        "emails": [
            "earl-larae@cowbelldrive.com", "earl-larae@yahsnooze.com"
        ],
        "phone_numbers": [
            "+132155512345", "+132155512346"
        ],
        "created_at": "2019-07-30T21:16:45.460Z",
        "updated_at": "2019-07-30T21:16:45.460Z",
        "mailing_name": "Earl LaRae",
        "mailing_street_1": "PO BOX 42424242",
        "mailing_street_2": null,
        "mailing_city": "Sun Valley",
        "mailing_state": "ID",
        "mailing_postal_code": "83353",
        "notes": [],
        "external_id": "123"
      },
    },
    "relationships": {}
  }
}

This endpoint creates a new Property.

HTTP Request

POST https://api.hoalife.com/api/properties

Property Writable Attributes

Parameter Type Description Required
account_id Integer Unique identifier of Account the Property belongs to true
street_1 String Street address of the property true
street_2 String Street address of the property false
city String City of the property true
state String State of the property true
postal_code String Postal code of the property true
override_geocoding Boolean Use the supplied latitude and longitude or automatically geocode the property's address. Default false. false
latitude Float GPS Latitude coordinate of the Property false
longitude Float GPS Longitude coordinate of the Property false
route String Inspection route property belongs to, such as the property street name. May be overridden if override_geocoding is false. false
route_leg String Inspection sub-route property belongs to, such as 'odd' or 'A'. May be overridden if override_geocoding is false. false
emails Array[String] Array of strings of the property owner's email addresses false
phone_numbers Array[String] Array of strings of the property owner's phone numbers false
mailing_name String Mailing street address of the property false*
mailing_street_1 String Mailing street address of the property false
mailing_street_2 String Mailing street address of the property false
mailing_city String Mailing city address of the property false*
mailing_state String Mailing state address of the property false*
mailing_postal_code String Mailing postal code address of the property false*
tags Array[String] Array of strings representing the tag ids or titles false
external_id String A unique identifier from an external system used to map the record false

Update Property

curl "https://api.hoalife.com/api/properties/42" \
  -X PUT \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "property",
        "attributes": {
          "street_1": "123 Updated St",
          "tags": ["1", "Board Member"]
        }
      }
    }
  '

The above command will return updated JSON, just like for the Create action with a successful status code of 201 CREATED.

This endpoint updates an existing Property.

HTTP Request

PUT https://api.hoalife.com/api/properties/:property_id

URL Parameters

Parameter Type Description
:property_id Integer Unique identifier of the Property the request is being made for

Editable Attributes

See Writable Attributes for the Create action. The associated Account cannot be changed.

Destroy Property

curl "https://api.hoalife.com/api/properties/42" \
  -X DELETE \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json"

The above command will return an empty response successful response with a successful status code of 202 Accepted.

This endpoint destroys an existing Property. Because Property objects have many dependent resources, the actual deletion of the data is performed in a background process. This means that the API may continue to return data for the Property even after you've requested a it be deleted.

HTTP Request

DELETE https://api.hoalife.com/api/properties/:property_id

URL Parameters

Parameter Type Description
:property_id Integer Unique identifier of the Property the request is being made for

Property Supplemental Mailing Addresses

Supplemental mailing addresses for properties. The primary property mailing address should be provided as Property data.

Get All Property Supplemental Mailing Addresses

curl "https://api.hoalife.com/api/properties/supplemental_mailing_addressses" \
  -H "Authorization: Token sk_SUPERSECRET"

The above command returns JSON structured like this:

{
  "data": [
    {
  "data": [
    {
      "id": "1",
      "type": "supplemental_mailing_address",
      "attributes": {
        "id": 1,
        "property_id": 42,
        "send_notices": true,
        "mailing_name": "John Smith",
        "mailing_street_1": "1234 Tall Oak Court",
        "mailing_street_2": "",
        "mailing_city": "Low Point",
        "mailing_state": "NC",
        "mailing_postal_code": "23365",
        "external_id": "abc-123"
      },
      "relationships": {}
    },
    {
      "id": "2",
      "type": "supplemental_mailing_address",
      "attributes": {
        "id": 2,
        "property_id": 42,
        "send_notices": false,
        "mailing_name": "Jane Smith",
        "mailing_street_1": "22558 Casa Grande Drive",
        "mailing_street_2": "",
        "mailing_city": "Cookersfield",
        "mailing_state": "IA",
        "mailing_postal_code": "91106",
        "external_id": "abc-122"
      },
      "relationships": {}
    }
  ],
  "meta": {
    "current_page": 1,
    "total": 2,
    "total_pages": 1

    "self": "/api/properties/supplemental_mailing_addresses?page=1",
    "next": "/api/properties/supplemental_mailing_addresses?page=2",
    "prev": "/api/properties/supplemental_mailing_addresses"
  }
}

This endpoint retrieves all Property Supplemental Mailing Addresses for the given Property ID.

This endpoint retrieves all Property Supplemental Mailing Addresses accessible by the API key. If the API key has access to multiple Accounts, all Properties for all those accounts will be returned. Scope Property Supplemental Mailing Addresses to a specific Property by adding an property_id query parameter.

HTTP Request

GET https://api.hoalife.com/api/properties/supplemental_mailing_addresses

Attributes

Parameter Type Description
id Integer Unique identifier of the Property
property_id Integer Unique identifier of the Property belongs to the Supplemental Mailing Address belongs to
mailing_name String Mailing name
mailing_street_1 String Mailing street address
mailing_street_2 String Mailing street address
mailing_city String Mailing city address
mailing_state String Mailing state address
mailing_postal_code String Mailing postal code address
external_id String A unique identifier from an external system used to map the record

Query Parameters

Parameter Query By Order By
id true true
property_id true true
mailing_name true true
mailing_street_1 true true
mailing_street_2 true true
mailing_city true true
mailing_state true true
mailing_postal_code true true
external_id true true

Create Property Supplemental Mailing Address

curl "https://api.hoalife.com/api/properties/supplemental_mailing_address" \
  -X POST \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "supplemental_mailing_address",
        "attributes": {
          "mailing_name": "Jane Smith",
          "mailing_street_1": "22558 Casa Grande Drive",
          "mailing_city": "Cookersfield",
          "mailing_state": "IA",
          "mailing_postal_code": "91106",
          "send_notices": true,
          "external_id": "abc-123"
        },
        "relationships": {
          "property": {
            "data": {
              "type": "property",
              "id": 42
            }
          }
        }
      }
    }
  '

The above command returns JSON structured like this:

{
  "data": {
      "id": "25",
      "type": "supplemental_mailing_address",
      "attributes": {
        "id": 2,
        "property_id": 42,
        "send_notices": true,
        "mailing_name": "Jane Smith",
        "mailing_street_1": "22558 Casa Grande Drive",
        "mailing_street_2": "",
        "mailing_city": "Cookersfield",
        "mailing_state": "IA",
        "mailing_postal_code": "91106",
        "external_id": "abc-123"
      },
    },
    "relationships": {}
  }
}

This endpoint creates a new Property Supplemental Mailing Address.

HTTP Request

POST https://api.hoalife.com/api/properties/supplemental_mailing_address

Property Supplemental Mailing Address Writable Attributes

Parameter Type Description Required
property_id Integer Unique identifier of the Property the Supplemental Mailing Address belongs to true
mailing_name String Mailing street address true
mailing_street_1 String Mailing street address true
mailing_street_2 String Mailing street address false
mailing_city String Mailing city address true
mailing_state String Mailing state address true
mailing_postal_code String Mailing postal code address true
send_notices Boolean Notices be sent to this address false
external_id String A unique identifier from an external system used to map the record false

Update Property Supplemental Mailing Address

curl "https://api.hoalife.com/api/properties/supplemental_mailing_addresses/25" \
  -X PUT \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "supplemental_mailing_address",
        "attributes": {
          "mailing_name": "Josh Carunner",
        }
      }
    }
  '

The above command will return updated JSON, just like for the Create action with a successful status code of 201 CREATED.

This endpoint updates an existing Property Supplemental Mailing Address.

HTTP Request

PUT https://api.hoalife.com/api/properties/supplemental_mailing_addresses/:supplemental_mailing_addresses_id

URL Parameters

Parameter Type Description
:supplemental_mailing_addresses_id Integer Unique identifier of the Property Supplemental Mailing Address the request is being made for

Editable Attributes

See Writable Attributes for the Create action. The associated Property cannot be changed.

Destroy Property

curl "https://api.hoalife.com/api/properties/supplemental_mailing_addresses/42" \
  -X DELETE \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json"

The above command will return an empty response successful response with a successful status code of 202 Accepted.

This endpoint destroys an existing Property Supplemental Mailing Address.

HTTP Request

DELETE https://api.hoalife.com/api/properties/supplemental_mailing_addresses/:supplemental_mailing_addresses_id

URL Parameters

Parameter Type Description
:supplemental_mailing_addresses_id Integer Unique identifier of the Property Supplemental Mailing Address the request is being made for

Assets

Assets represent a asset or common area in an association.

Get All Assets

curl "https://api.hoalife.com/api/assets" \
  -H "Authorization: Token sk_SUPERSECRET"

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "1",
      "type": "asset",
      "attributes": {
        "id": 1,
        "account_id": 2,
        "formatted_id": "AST-1",
        "description": "Pool",
        "latitude": "37.233333",
        "longitude": "-115.808333",
        "created_at": "2019-07-30T21:16:45.460Z",
        "updated_at": "2019-07-30T21:16:45.460Z",
        "external_id": null
      },
      "relationships": {}
    },
    ...
    {
      "id": "25",
      "type": "asset",
      "attributes": {
        "id": 25,
        "account_id": 2,
        "formatted_id": "AST-25",
        "description": "West Entrence Common Area",
        "latitude": "37.233333",
        "longitude": "-115.808333",
        "created_at": "2019-07-30T21:16:45.460Z",
        "updated_at": "2019-07-30T21:16:45.460Z",
        "external_id": null
      },
      "relationships": {}
    }
  ],
  "meta": {
    "current_page": 1,
    "total": 858,
    "total_pages": 35
  },
  "links": {
    "self": "/api/assets?page=1",
    "next": "/api/assets?page=2",
    "prev": "/api/assets"
  }
}

This endpoint retrieves all Assets accessible by the API key. If the API key has access to multiple Accounts, all Assets for all those accounts will be returned. Scope Assets to a specific Account by adding an account_id query parameter.

HTTP Request

GET https://api.hoalife.com/api/assets

Attributes

Parameter Type Description
id Integer Unique identifier of the Asset
account_id Integer Unique identifier of Account the Asset belongs to
formatted_id String Humanized unique identifier
description String Description of the asset
latitude String GPS Latitude coordinate
longitude String GPS Longitude coordinate
external_id String A unique identifier from an external system used to map the record

Query Parameters

Parameter Query By Order By
id true true
account_id true true
formatted_id true true
description true true
latitude true true
longitude true true
external_id true true

Create Asset

curl "https://api.hoalife.com/api/assets" \
  -X POST \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "asset",
        "attributes": {
          "description": "4242 Cowbell Drive",
          "latitude": "37.233333",
          "longitude": "-115.808333",
          "external_id": "123"
        },
        "relationships": {
          "account": {
            "data": {
              "type": "account",
              "id": 5
            }
          }
        }
      }
    }
  '

The above command returns JSON structured like this:

{
  "data": {
      "id": "25",
      "type": "asset",
      "attributes": {
        "id": 25,
        "account_id": 5,
        "formatted_id": "AST-25",
        "latitude": "37.233333",
        "longitude": "-115.808333",
        "created_at": "2019-07-30T21:16:45.460Z",
        "updated_at": "2019-07-30T21:16:45.460Z",
        "external_id": "123"
      },
    },
    "relationships": {}
  }
}

This endpoint creates a new Asset.

HTTP Request

POST https://api.hoalife.com/api/assets

Asset Writable Attributes

Parameter Type Description Required
account_id Integer Unique identifier of Account the Asset belongs to true
description String Description the Asset true
latitude Float GPS Latitude coordinate of the Asset false
longitude Float GPS Longitude coordinate of the Asset false
external_id String A unique identifier from an external system used to map the record false

Update Asset

curl "https://api.hoalife.com/api/assets/42" \
  -X PUT \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "asset",
        "attributes": {
          "description": "Common aread West entrance"
        }
      }
    }
  '

The above command will return updated JSON, just like for the Create action with a successful status code of 201 CREATED.

This endpoint updates an existing Asset.

HTTP Request

PUT https://api.hoalife.com/api/assets/:asset_id

URL Parameters

Parameter Type Description
:asset_id Integer Unique identifier of the Asset the request is being made for

Editable Attributes

See Writable Attributes for the Create action. The associated Account cannot be changed.

Destroy Asset

curl "https://api.hoalife.com/api/assets/42" \
  -X DELETE \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json"

The above command will return an empty response successful response with a successful status code of 202 Accepted.

This endpoint destroys an existing Asset. Because Asset objects have many dependent resources, the actual deletion of the data is performed in a background process. This means that the API may continue to return data for the Asset even after you've requested a it be deleted.

HTTP Request

DELETE https://api.hoalife.com/api/assets/:asset_id

URL Parameters

Parameter Type Description
:asset_id Integer Unique identifier of the Asset the request is being made for

CCR Articles

CCR Articles represent a group of similar Violation Types an Association enforces.

Get All CCR Articles

curl "https://api.hoalife.com/api/ccr_articles" \
  -H "Authorization: Token sk_SUPERSECRET"

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "1",
      "type": "ccr_article",
      "attributes": {
        "id": 1,
        "article": "5.14.a",
        "title": "Lot Maintenance",
        "description": "As stated in Article 5.14(a) - Each Owner of a Lot shall maintain all Improvements located thereon in good and sufficient repair and shall keep the improvements thereon painted or stained, lawn cut, shrubbery trimmed, windows glazed, rubbish and debris removed, weeds cut and otherwise maintain the same in a neat and aesthetically pleasing condition.",
        "created_at": "2019-07-30T21:16:47.540Z",
        "updated_at": "2019-07-31T15:44:01.646Z",
        "account_id": 2,
        "external_id": null
      },
      "relationships": {}
    },
    ...
    {
      "id": "4",
      "type": "ccr_article",
      "attributes": {
        "id": 4,
        "article": "5.24.c",
        "title": "Fences and Walls",
        "description": "As stated in Article 5.24(c) - All fences and walls shall be constructed and installed and maintained in good appearance and condition at the expense of the Owner of the Lot on which they are located and all damaged fencing and walls shall be repainted or replaced to original design, materials, and color within a reasonable time after said damage occurs.",
        "created_at": "2019-07-30T21:16:48.006Z",
        "updated_at": "2019-07-30T21:16:48.009Z",
        "account_id": 2,
        "external_id": null
      },
      "relationships": {}
    }
  ],
  "meta": {
    "current_page": 1,
    "total": 4,
    "total_pages": 1
  },
  "links": {
    "self": "/api/ccr_articles?page=1",
    "next": "/api/ccr_articles",
    "prev": "/api/ccr_articles"
  }
}

This endpoint retrieves all CCR Articles accessible by the API key. If the API key has access to multiple Accounts, all CCR Articles for all those accounts will be returned. Scope CCR Articles to a specific Account by adding an account_id query parameter.

HTTP Request

GET https://api.hoalife.com/api/ccr_articles

Attributes

Parameter Type Description
id Integer Unique identifier of the CCR Article
account_id Integer Unique identifier of Account the CCR Article belongs to
article String Article of CCRs, used for ordering and nesting
title String Title of the CCR Article
description String Description of the CCR Article
external_id String A unique identifier from an external system used to map the record

Query Parameters

Parameter Query By Order By
id true true
account_id true true
article true true
title true true
description true true
external_id true true

Create CCR Article

curl "https://api.hoalife.com/api/ccr_articles" \
  -X POST \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "ccr_article",
        "attributes": {
          "article": "5.24.c",
          "title": "Fences and Walls",
          "description": "As stated in Article 5.24(c) - All fences and walls shall be constructed and installed and maintained in good appearance and condition at the expense of the Owner of the Lot on which they are located and all damaged fencing and walls shall be repainted or replaced to original design, materials, and color within a reasonable time after said damage occurs.",
          "external_id": "123"
        },
        "relationships": {
          "account": {
            "data": {
              "type": "account",
              "id": 5
            }
          }
        }
      }
    }
  '

The above command returns JSON structured like this:

{
  "data": {
      "id": "4",
      "type": "ccr_article",
      "attributes": {
        "id": 4,
        "article": "5.24.c",
        "title": "Fences and Walls",
        "description": "As stated in Article 5.24(c) - All fences and walls shall be constructed and installed and maintained in good appearance and condition at the expense of the Owner of the Lot on which they are located and all damaged fencing and walls shall be repainted or replaced to original design, materials, and color within a reasonable time after said damage occurs.",
        "created_at": "2019-07-30T21:16:48.006Z",
        "updated_at": "2019-07-30T21:16:48.009Z",
        "account_id": 2,
        "external_id": null
      }
    },
    "relationships": {}
  }
}

This endpoint creates a new CCR Article.

HTTP Request

POST https://api.hoalife.com/api/ccr_articles

CCR Article Writable Attributes

Parameter Type Description Required
account_id Integer Unique identifier of Account the CCR Article belongs to true
article String Article of CCRs, used for ordering and nesting false
title String Title of the CCR Article true
description String Description of the CCR Article true
external_id String A unique identifier from an external system used to map the record false

Update CCR Article

curl "https://api.hoalife.com/api/ccr_articles/42" \
  -X PUT \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "property",
        "attributes": {
          "title": "Fences and Walls and Doors"
        }
      }
    }
  '

The above command will return updated JSON, just like for the Create action with a successful status code of 201 CREATED.

This endpoint updates an existing CCR Article.

HTTP Request

PUT https://api.hoalife.com/api/ccr_articles/:ccr_article_id

URL Parameters

Parameter Type Description
:ccr_article_id Integer Unique identifier of the CCR Article the request is being made for

Editable Attributes

See Writable Attributes for the Create action. The associated Account cannot be changed.

Destroy CCR Article

curl "https://api.hoalife.com/api/ccr_articles/42" \
  -X DELETE \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json"

The above command will return an empty response successful response with a successful status code of 202 Accepted.

This endpoint destroys an existing CCR Article. Because CCR Article objects have many dependent resources, the actual deletion of the data is performed in a background process. This means that the API may continue to return data for the CCR Article even after you've requested a it be deleted.

HTTP Request

DELETE https://api.hoalife.com/api/ccr_articles/:ccr_article_id

URL Parameters

Parameter Type Description
:ccr_article_id Integer Unique identifier of the CCR Article the request is being made for

CCR Violation Types

CCR Violation Types represent a rule that the Association enforces and records violations for.

Get All CCR Violation Types

curl "https://api.hoalife.com/api/ccr_violation_types" \
  -H "Authorization: Token sk_SUPERSECRET"

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "1",
      "type": "ccr_violation_type",
      "attributes": {
        "id": 1,
        "title": "Broadleaf and/or weeds in turf",
        "resolution_step": "Apply broadleaf/week mitigation",
        "days_to_cure": 20,
        "created_at": "2019-07-30T21:16:47.707Z",
        "updated_at": "2019-07-31T15:44:01.640Z",
        "ccr_article_id": 1,
        "external_id": null
      },
      "relationships": {}
    },
    ...
    {
      "id": "4",
      "type": "ccr_violation_type",
      "attributes": {
        "id": 4,
        "title": "Dead tree(s) needs to be removed/replaced",
        "resolution_step": "Remove dead tree(s)",
        "days_to_cure": 20,
        "created_at": "2019-07-30T21:16:47.712Z",
        "updated_at": "2019-07-30T21:16:47.712Z",
        "ccr_article_id": 1,
        "external_id": null
      },
      "relationships": {}
    }
  ],
  "meta": {
    "current_page": 1,
    "total": 4,
    "total_pages": 1
  },
  "links": {
    "self": "/api/ccr_violation_types?page=1",
    "next": "/api/ccr_violation_types",
    "prev": "/api/ccr_violation_types"
  }
}

This endpoint retrieves all CCR Violation Types accessible by the API key. If the API key has access to multiple Accounts or CCR Violation Types, all Violation Types for all those accounts will be returned. Scope CCR Violation Types to a specific Account by adding an account_id query parameter.

HTTP Request

GET https://api.hoalife.com/api/ccr_violation_types

Attributes

Parameter Type Description
id Integer Unique identifier of the CCR Violation Type
account_id Integer Unique identifier of Account the CCR Violation Type belongs to
ccr_article_id Integer Unique identifier of CCR Article the CCR Violation Type belongs to
title String Title of the CCR Violation Type
resolution_step String Suggested step for resolution of the Violation
days_to_cure Integer Days after the Violation was recorded that a Cure Reminder Notification will be sent
external_id String A unique identifier from an external system used to map the record

Query Parameters

Parameter Query By Order By
id true true
account_id true true
ccr_article_id true true
article true true
title true true
resolution_step true true
days_to_cure true true
external_id true true

Create CCR Violation Type

curl "https://api.hoalife.com/api/ccr_violation_types" \
  -X POST \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "ccr_violation_type",
        "attributes": {
          "title": "Dead tree(s) needs to be removed/replaced",
          "resolution_step": "Remove dead tree(s)",
          "days_to_cure": 20,
          "external_id": "123"
        },
        "relationships": {
          "ccr_article": {
            "data": {
              "type": "ccr_article",
              "id": 1
            }
          }
        }
      }
    }
  '

The above command returns JSON structured like this:

{
  "data": {
      "id": "4",
      "type": "ccr_violation_type",
      "attributes": {
        "id": 4,
        "title": "Dead tree(s) needs to be removed/replaced",
        "resolution_step": "Remove dead tree(s)",
        "days_to_cure": 20,
        "created_at": "2019-07-30T21:16:47.712Z",
        "updated_at": "2019-07-30T21:16:47.712Z",
        "ccr_article_id": 1,
        "external_id": "123"
      },
    },
    "relationships": {}
  }
}

This endpoint creates a new CCR Violation Type.

HTTP Request

POST https://api.hoalife.com/api/ccr_violation_types

CCR Violation Type Writable Attributes

Parameter Type Description Required
ccr_article_id Integer Unique identifier of CCR Article the CCR Violation Type belongs to true
title String Title of the CCR Violation Type true
resolution_step String Suggested step for resolution of the Violation false
days_to_cure Integer Days after the Violation was recorded that a Cure Reminder Notification will be sent false
external_id String A unique identifier from an external system used to map the record false

Update CCR Violation Type

curl "https://api.hoalife.com/api/ccr_violation_types/42" \
  -X PUT \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "ccr_violation_type",
        "attributes": {
          "title": "Dead tree(s) needs to be replaced"
        }
      }
    }
  '

The above command will return updated JSON, just like for the Create action with a successful status code of 201 CREATED.

This endpoint updates an existing CCR Violation Type.

HTTP Request

PUT https://api.hoalife.com/api/ccr_violation_types/:ccr_violation_type_id

URL Parameters

Parameter Type Description
:ccr_violation_type_id Integer Unique identifier of the CCR Violation Type the request is being made for

Editable Attributes

See Writable Attributes for the Create action. The associated CCR Article cannot be changed.

Destroy CCR Violation Type

curl "https://api.hoalife.com/api/ccr_violation_types/42" \
  -X DELETE \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json"

The above command will return an empty response successful response with a successful status code of 202 Accepted.

This endpoint destroys an existing CCR Violation Type. Because CCR Violation Type objects have many dependent resources, the actual deletion of the data is performed in a background process. This means that the API may continue to return data for the CCR Violation Type even after you've requested a it be deleted.

HTTP Request

DELETE https://api.hoalife.com/api/ccr_violation_types/:ccr_violation_type_id

URL Parameters

Parameter Type Description
:ccr_violation_type_id Integer Unique identifier of the CCR Violation Type the request is being made for

Inspections

Inspections represent an inspection of the entire Association for Violations.

Get All Inspections

curl "https://api.hoalife.com/api/accounts/inspections" \
  -H "Authorization: Token sk_SUPERSECRET"

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "1",
      "type": "inspection",
      "attributes": {
        "id": 1,
        "account_id": 2,
        "state": "completed",
        "completed_at": "2019-07-30T21:16:49.510Z",
        "duration": 7488,
        "created_at": "2019-07-30T21:16:49.194Z",
        "updated_at": "2019-07-31T15:44:01.575Z",
        "total_violations": 18,
        "inspector": {
          "name": "John Owner",
          "email": "john-owner@hoalife.com"
        }
      },
      "relationships": {}
    },
    {
      "id": "2",
      "type": "inspection",
      "attributes": {
        "id": 2,
        "account_id": 3,
        "state": "started",
        "completed_at": null,
        "duration": 0,
        "created_at": "2019-08-05T14:45:21.291Z",
        "updated_at": "2019-08-05T14:45:21.291Z",
        "total_violations": 0,
        "inspector": {
          "name": "John Owner",
          "email": "john-owner@hoalife.com"
        }
      },
      "relationships": {}
    }
  ],
  "meta": {
    "current_page": 1,
    "total": 2,
    "total_pages": 1
  },
  "links": {
    "self": "/api/inspections?page=1",
    "next": "/api/inspections",
    "prev": "/api/inspections"
  }
}

This endpoint retrieves all Inspections accessible by the API key. If the API key has access to multiple Accounts, all Inspections for all those accounts will be returned. Scope Inspections to a specific Account by adding an account_id query parameter.

HTTP Request

GET https://api.hoalife.com/api/inspections

Attributes

Parameter Type Description
id Integer Unique identifier of the Inspection
account_id Integer Unique identifier of Account the Inspection belongs to
completed_at String Date the Inspection was completed
duration Integer Number of seconds between the Inspection's created_at and completed_at values
total_violations Integer The number of Violations recorded in the Inspection

Query Parameters

Parameter Query By Order By
id true true
account_id true true
completed_at true true
duration true true
total_violations false false

Violations

Violations represent a recorded infraction of a Violation Type for given Property.

Get All Violations

curl "https://api.hoalife.com/api/violations" \
  -H "Authorization: Token sk_SUPERSECRET"

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "1",
      "type": "violation",
      "attributes": {
        "id": 1,
        "ccr_violation_type_id": 5,
        "comment": "Very bad stuff, here",
        "external_id": null,
        "violated_at": "2019-06-15T12:04:16.111Z",
        "cure_by": "2019-06-25T12:04:16.111Z",
        "created_at": "2019-07-30T21:16:48.873Z",
        "updated_at": "2019-07-31T15:44:01.522Z",
        "property_id": 56,
        "inspection_id": null,
        "upload_urls": [],
        "consecutive_violation_count": 1,
        "inspector": {
          "name": "John Owner",
          "email": "john-owner@hoalife.com"
        }
      },
      "relationships": {}
    },
    ...
    {
      "id": "4",
      "type": "violation",
      "attributes": {
        "id": 4,
        "ccr_violation_type_id": 1,
        "comment": "",
        "external_id": null,
        "violated_at": "2019-07-30T22:07:17.135Z",
        "cure_by": null,
        "created_at": "2019-07-30T22:07:17.135Z",
        "updated_at": "2019-07-31T15:44:01.634Z",
        "property_id": 28,
        "inspection_id": null,
        "upload_urls": [
          {
            "url": "https://hoal-subdomain.s3.us-west-2.amazonaws.com/aaff3c01-3753-43c7-bc37-98c092e7ab2c/camper.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSPPTZMGN7FDW4AQ%2F20190805%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20190805T145317Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&X-Amz-Signature=999c66db8f6e182793b921989b8724160a45cc973f706f4f7bc56e5bcc9c08eb",
            "url_expiration": "2019-08-06T14:53:17.301Z"
          }
        ],
        "consecutive_violation_count": 1,
        "inspector": {
          "name": "John Owner",
          "email": "john-owner@hoalife.com"
        }
      },
      "relationships": {}
    }
  ],
  "meta": {
    "current_page": 1,
    "total": 4,
    "total_pages": 1
  },
  "links": {
    "self": "/api/violations?page=1",
    "next": "/api/violations",
    "prev": "/api/violations"
  }
}

This endpoint retrieves all Violations accessible by the API key. If the API key has access to multiple Accounts, all Violations for all those accounts will be returned. Scope Violations to a specific Account by adding an account_id query parameter.

HTTP Request

GET https://api.hoalife.com/api/violations

Attributes

Parameter Type Description
id Integer Unique identifier of the Violation
property_id Integer Unique identifier of Property the Violation belongs to
account_id Integer Unique identifier of Account the Violation belongs to
ccr_violation_type_id Integer Unique identifier of CCR Violation Type the Violation belongs to
inspection_id Integer Unique identifier of Inspection the Violation belongs to
violated_at String Date the infraction occured
cure_by String Date the infraction should be resolved by
comment String A comment added by the inspector
upload_urls Array[Object] Image uploads associated with the Violation
external_id String A unique identifier from an external system used to map the record

Query Parameters

Parameter Query By Order By
id true true
account_id true true
property_id true true
ccr_violation_type_id true true
inspection_id true true
violated_at true true
cure_by true true
comment true true
external_id true true

Create Violation

curl "https://api.hoalife.com/api/violations" \
  -X POST \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "violation",
        "attributes": {
          "comment": "",
          "external_id": "123",
          "violated_at": "2019-07-30T22:07:17.135Z",
          "upload_urls": [
            "https://foobar.com/image.jpg"
          ]
        },
        "relationships": {
          "ccr_violation_type": {
            "data": {
              "type": "ccr_violation_type",
              "id": 1
            }
          },
          "property": {
            "data": {
              "type": "property",
              "id": 2
            }
          },
          "inspector": {
            "data": {
              "type": "user",
              "email": "user-with-access@example.com"
            }
          }
        }
      }
    }
  '

The above command returns JSON structured like this:

{
  "data": {
      "id": "4",
      "type": "violation",
      "attributes": {
        "id": 4,
        "ccr_violation_type_id": 1,
        "comment": "",
        "external_id": "123",
        "violated_at": "2019-07-30T22:07:17.135Z",
        "created_at": "2019-07-30T22:07:17.135Z",
        "updated_at": "2019-07-31T15:44:01.634Z",
        "property_id": 2,
        "inspection_id": null,
        "upload_urls": [],
        "consecutive_violation_count": 1,
        "inspector": {
          "name": "John User With Access",
          "email": "user-with-access@example.com"
        }
      },
    },
    "relationships": {}
  }
}

This endpoint creates a new Violation.

HTTP Request

POST https://api.hoalife.com/api/violations

Writable Attributes

Parameter Type Description Required
property_id Integer Unique identifier of Property the Violation belongs to true
ccr_violation_type_id Integer Unique identifier of CCR Violation Type the Violation belongs to true
owner_email String Email of a HOALife User who has access to the Property true
violated_at String Date the infraction occured in ISO8601 format false
comment String A comment added by the inspector false
cure_by String Date the violation should be cured by in ISO8601 false
external_id String A unique identifier from an external system used to map the record false
upload_urls Array[String] An array of publicly accessible URLs false

Note when passing upload_urls: URLs passed are validated and copied in a background process. The responding JSON may not contain the uploads until this completes. This may take many seconds depending on the amount of data that must be copied.

Update Violation

curl "https://api.hoalife.com/api/violations/42" \
  -X PUT \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "violation",
        "attributes": {
          "comment": "Dead tree(s) needs to be replaced",
          "upload_urls": [
            "https://foobar.com/image.jpg"
          ]
        }
      }
    }
  '

The above command will return updated JSON, just like for the Create action with a successful status code of 201 CREATED.

This endpoint updates an existing Violation.

HTTP Request

PUT https://api.hoalife.com/api/violations/:violation_id

URL Parameters

Parameter Type Description
:violation_id Integer Unique identifier of the Violation the request is being made for

Editable Attributes

Parameter Type Description Required
comment String A comment added by the inspector false
external_id String A unique identifier from an external system used to map the record false
cure_by String Date the violation should be cured by in ISO8601 false
upload_urls Array[String] An array of publicly accessible URLs false

Note when passing upload_urls: URLs passed are validated and copied in a background process. The responding JSON may not contain the uploads until this completes. This may take many seconds depending on the amount of data that must be copied.

Destroy Violation

curl "https://api.hoalife.com/api/violations/42" \
  -X DELETE \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json"

The above command will return an empty response successful response with a successful status code of 202 Accepted.

This endpoint destroys an existing Violation. Because Violation objects have many dependent resources, the actual deletion of the data is performed in a background process. This means that the API may continue to return data for the Violation even after you've requested a it be deleted.

HTTP Request

DELETE https://api.hoalife.com/api/violations/:violation_id

URL Parameters

Parameter Type Description
:violation_id Integer Unique identifier of the Violation the request is being made for

Escalations

Escalations represent a group of Violations which have contributed to exceeding the Account's escalation_threshold.

Get All Escalations

curl "https://api.hoalife.com/api/escalations" \
  -H "Authorization: Token sk_SUPERSECRET"

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "1",
      "type": "escalation",
      "attributes": {
        "id": 1,
        "state": "resolved",
        "resolved_at": "2019-08-03T24:16:22.118Z",
        "account_id": 2,
        "property_id": 56,
        "created_at": "2019-07-30T21:16:49.818Z",
        "updated_at": "2019-07-31T15:40:39.125Z",
        "violations": [
          {
            "id": 1,
            "triggered_escalation": false,
            "link": "/api/violations?id=1"
          },
          {
            "id": 2,
            "triggered_escalation": false,
            "link": "/api/violations?id=2"
          },
          {
            "id": 3,
            "triggered_escalation": true,
            "link": "/api/violations?id=3"
          }
        ],
        "resolver": {
          "name": "John Owner",
          "email": "john-owner@hoalife.com"
        },
        "notes": [
          {
            "body_text": "Confirmed property is currently not compliant \n  \nhttps://app.hoalife.com/authenticated_uploads/Pn1YWIZjUghE0+B3cCG+CG8e1b0nPX%2FQAkm2soWSu3f4lDHvZoVck7VU39hp--Jzsz3YIEJ%2Fs2oru1--3+77KoR+M6S96SqFMVD8Tw==",
            "author": "John Owner",
            "pinned": false,
            "created_at": "2019-08-05T16:08:24.542Z"
          }
        ]
      },
      "relationships": {}
    },
    {
      "id": "2",
      "type": "escalation",
      "attributes": {
        "id":2,
        "state": "in_process",
        "resolved_at": null,
        "account_id": 2,
        "property_id": 56,
        "created_at": "2019-07-30T21:16:49.818Z",
        "updated_at": "2019-07-31T15:40:39.125Z",
        "violations": [
          {
            "id": 4,
            "triggered_escalation": false,
            "link": "/api/violations?id=4"
          },
          {
            "id": 5,
            "triggered_escalation": false,
            "link": "/api/violations?id=5"
          },
          {
            "id": 6,
            "triggered_escalation": true,
            "link": "/api/violations?id=6"
          }
        ],
        "resolver": {
          "name": null,
          "email": null
        },
        "notes": []
      },
      "relationships": {}
    }
  ],
  "meta": {
    "current_page": 1,
    "total": 2,
    "total_pages": 1
  },
  "links": {
    "self": "/api/escalations?page=1",
    "next": "/api/escalations",
    "prev": "/api/escalations"
  }
}

This endpoint retrieves all Escalations accessible by the API key. If the API key has access to multiple Accounts, all Escalations for all those accounts will be returned. Scope Escalations to a specific Account by adding an account_id query parameter.

HTTP Request

GET https://api.hoalife.com/api/escalations

Attributes

Parameter Type Description
id Integer Unique identifier of the Escalation
account_id Integer Unique identifier of Account the Escalation belongs to
property_id Integer Unique identifier of Property the Escalation belongs to
state String State of the Escalation
resolved_at String Date the Escalation was marked as resolved
violations Array[Object] Information pertaining to the violations associated with the Escalation
resolver Object Information pertaining to the user who marked the Escalation as resolved
notes Array[Object] Escalation notes

Query Parameters

Parameter Query By Order By
id true true
account_id true true
property_id true true
state true true
resolved_at true true
violations false false
resolver false false
notes false false

Deficiencies

Deficiencies represent a recorded flaw for a given Asset.

Get All Deficiencies

curl "https://api.hoalife.com/api/deficiencies" \
  -H "Authorization: Token sk_SUPERSECRET"

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "1",
      "type": "deficiency",
      "attributes": {
        "id": 1,
        "description": "Pool circulation pump is non-functional",
        "details": "Pool circulation pump does not turn on. No indications of power",
        "state": "resolved",
        "external_id": null,
        "resolved_at": "2019-06-15T12:04:16.111Z",
        "created_at": "2019-07-30T21:16:48.873Z",
        "updated_at": "2019-07-31T15:44:01.522Z",
        "asset_id": 56,
        "inspection_id": null,
        "upload_urls": [],
        "formatted_id": "DEF-1"
      },
      "relationships": {}
    },
    ...
    {
      "id": "4",
      "type": "deficiency",
      "attributes": {
        "id": 4,
        "description": "Entry light out",
        "details": "West entry light is out",
        "state": "identified",
        "external_id": null,
        "resolved_at": null,
        "created_at": "2019-07-30T22:07:17.135Z",
        "updated_at": "2019-07-31T15:44:01.634Z",
        "asset_id": 28,
        "inspection_id": 4,
        "upload_urls": [
          {
            "url": "https://hoal-subdomain.s3.us-west-2.amazonaws.com/aaff3c01-3753-43c7-bc37-98c092e7ab2c/camper.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSPPTZMGN7FDW4AQ%2F20190805%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20190805T145317Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&X-Amz-Signature=999c66db8f6e182793b921989b8724160a45cc973f706f4f7bc56e5bcc9c08eb",
            "url_expiration": "2019-08-06T14:53:17.301Z"
          }
        ],
        "formatted_id": "DEF-4"
      },
      "relationships": {}
    }
  ],
  "meta": {
    "current_page": 1,
    "total": 4,
    "total_pages": 1
  },
  "links": {
    "self": "/api/deficiencies?page=1",
    "next": "/api/deficiencies",
    "prev": "/api/deficiencies"
  }
}

This endpoint retrieves all Deficiencies accessible by the API key. If the API key has access to multiple Accounts, all Deficiencies for all those accounts will be returned. Scope Deficiencies to a specific Account by adding an account_id query parameter.

HTTP Request

GET https://api.hoalife.com/api/deficiencies

Attributes

Parameter Type Description
id Integer Unique identifier of the Deficiency
asset_id Integer Unique identifier of Asset the Deficiency belongs to
account_id Integer Unique identifier of Account the Deficiency belongs to
inspection_id Integer Unique identifier of Inspection the Deficiency belongs to
state String Current state of the deficiency
resolved_at String Date the infraction occured
description String A short description added by the inspector
details String A long details about the deficiencies added by the inspector
upload_urls Array[Object] Image uploads associated with the Deficiency
external_id String A unique identifier from an external system used to map the record
formatted_id String Humanized unique identifier

Query Parameters

Parameter Query By Order By
id true true
account_id true true
state true true
asset_id true true
inspection_id true true
resolved_at true true
description true true
details true true
external_id true true
formatted_id true true

Create Deficiency

curl "https://api.hoalife.com/api/deficiencies" \
  -X POST \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "deficiency",
        "attributes": {
          "description": "Foo",
          "details": "Bar",
          "external_id": "123",
          "state": "resolved"
          "resolved_at": "2019-07-30T22:07:17.135Z",
        },
        "relationships": {
          "asset": {
            "data": {
              "type": "asset",
              "id": 2
            }
          }
        }
      }
    }
  '

The above command returns JSON structured like this:

{
  "data": {
      "id": "4",
      "type": "deficiency",
      "attributes": {
        "id": 4,
        "description": "Foo",
        "details": "Bar",
        "external_id": "123",
        "resolved_at": "2019-07-30T22:07:17.135Z",
        "created_at": "2019-07-30T22:07:17.135Z",
        "updated_at": "2019-07-31T15:44:01.634Z",
        "asset_id": 2,
        "inspection_id": null,
        "upload_urls": [],
     },
    },
    "relationships": {}
  }
}

This endpoint creates a new Deficiency.

HTTP Request

POST https://api.hoalife.com/api/deficiencies

Deficiency Writable Attributes

Parameter Type Description Required
asset_id Integer Unique identifier of Asset the Deficiency belongs to true
resolved_at String Date the deficiency was resolved false
description String A short description added by the inspector true
details String A long details about the deficiencies added by the inspector true
external_id String A unique identifier from an external system used to map the record false

Update Deficiency

curl "https://api.hoalife.com/api/deficiencies/42" \
  -X PUT \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "deficiency",
        "attributes": {
          "details": "Dead tree(s) needs to be replaced"
        }
      }
    }
  '

The above command will return updated JSON, just like for the Create action with a successful status code of 201 CREATED.

This endpoint updates an existing Deficiency.

HTTP Request

PUT https://api.hoalife.com/api/deficiencies/:deficiency_id

URL Parameters

Parameter Type Description
:deficiency_id Integer Unique identifier of the Deficiency the request is being made for

Editable Attributes

See Writable Attributes for the Create action. The associated Account cannot be changed.

Destroy Deficiency

curl "https://api.hoalife.com/api/deficiencies/42" \
  -X DELETE \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json"

The above command will return an empty response successful response with a successful status code of 202 Accepted.

This endpoint destroys an existing Deficiency. Because Deficiency objects have many dependent resources, the actual deletion of the data is performed in a background process. This means that the API may continue to return data for the Deficiency even after you've requested a it be deleted.

HTTP Request

DELETE https://api.hoalife.com/api/deficiencies/:deficiency_id

URL Parameters

Parameter Type Description
:deficiency_id Integer Unique identifier of the Deficiency the request is being made for

Notes

Notes are attached to other data objects, including property, escalation, and deficiency.

Create Note

curl "https://api.hoalife.com/api/notes" \
  -X POST \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "note",
        "attributes": {
          "body_text": "This is my very important note",
          "pinned": true
        },
        "relationships": {
          "attached_to": {
            "data": {
              "type": "property",
              "id": 1
            }
          },
          "author": {
            "data": {
              "id": 1
            }
          }
        }
      }
    }
  '

The above command returns JSON structured like this:

{
  "data": {
      "id": "4",
      "type": "note",
      "attributes": {
        "id": 4,
        "pinned": true,
        "author_id": 1,
        "body_text": "This is my very important note",
        "attached_to_type": "property",
        "attached_to_id": 1,
        "created_at": "2019-07-30T21:16:47.712Z",
        "updated_at": "2019-07-30T21:16:47.712Z",
      },
    },
    "relationships": {}
  }
}

This endpoint creates a new Note.

HTTP Request

POST https://api.hoalife.com/api/notes

Note Writable Attributes

Parameter Type Description Required
author_id Integer Unique identifier of User who authored the note (defaults to first user in account scope if null) false
attached_to_type String Type of entity the note is attached to true
attached_to_id String ID of the entity the note is attached to true
body_text String The note's text true
pinned Boolean Denote if the note should be pinned false

Destroy Note

curl "https://api.hoalife.com/api/notes/42" \
  -X DELETE \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json"

The above command will return an empty response successful response with a successful status code of 202 Accepted.

This endpoint destroys an existing Note. Because Note objects have many dependent resources, the actual deletion of the data is performed in a background process. This means that the API may continue to return data for the Note even after you've requested a it be deleted.

HTTP Request

DELETE https://api.hoalife.com/api/notes/:note_id

URL Parameters

Parameter Type Description
:note_id Integer Unique identifier of the Note the request is being made for

Errors

{
  "data": {
    "id": "556629c9-c2ad-494b-82d4-53d9639f7174",
    "type": "error",
    "attributes": {
      "id": "556629c9-c2ad-494b-82d4-53d9639f7174",
      "title": "Resource Not Found",
      "status": 404,
      "detail": "Resource not found with this API key's scope"
    }
  }
}
Error Code Meaning
401 Bad Request -- Request was not sufficient to provide a response.
401 Unauthorized -- Provided API key was not valid.
403 Forbidden -- Provided API key does not have access to the requested resource.
404 Not Found -- Resource does not exist.
429 Too Many Requests -- Rate limit exceeded
500 Internal Server Error -- An error has occured and we've been notified.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.

Validation Errors

POST and PUT requests to create or update resources may respond with a 400 when not enough data was provided. In this case, reference the detail object for an explaination.

{
  "data": {
    "id": "656629c9-c2ad-494b-82d4-53d9639f7174",
    "type": "error",
    "attributes": {
      "id": "656629c9-c2ad-494b-82d4-53d9639f7174",
      "title": "Invalid data",
      "status": 400,
      "detail": {
        "name": "can't be blank",
        "parent_id": "is invalid"
      }
    }
  }
}

Webhooks

Webhooks allow your application to be notified, in real-time, about changes in HOALife. As a change happens, HOALife will make an HTTP POST with the event's data to your publicly accessible webserver. Contact HOALife to configure a webhook endpoint.

Respond with a 200 status code to confirm receipt of the webhook. Non-2XX status codes will result in a Retry of the webhook.

{
  "event": "property.update",
  "date": "2020-04-14T16:40:17.332Z",
  "payload": {
    "data": {
      "id": "25",
      "type": "property",
      "attributes": {
        "id": 25,
        "account_id": 5,
        "formatted_id": "PRP-25",
        "street_1": "4242 Cowbell Drive",
        "street_2": null,
        "city": "Sun Valley",
        "state": "ID",
        "postal_code": "83353",
        "override_geocoding": false,
        "latitude": "37.233333",
        "longitude": "-115.808333",
        "route_leg": null,
        "route": "Cowbell Drive",
        "emails": [
            "earl-larae@cowbelldrive.com", "earl-larae@yahsnooze.com"
        ],
        "phone_numbers": [
            "+132155512345", "+132155512346"
        ],
        "created_at": "2019-07-30T21:16:45.460Z",
        "updated_at": "2019-07-30T21:16:45.460Z",
        "mailing_name": "Earl LaRae",
        "mailing_street_1": "PO BOX 42424242",
        "mailing_street_2": null,
        "mailing_city": "Sun Valley",
        "mailing_state": "ID",
        "mailing_postal_code": "83353",
        "notes": [],
        "external_id": "123"
      },
    },
    "relationships": {}
  }
}
Webhook Description
account.create New Account Created
account.update Account Updated
account.destroy Account Destroyed
ccr.article.create New CCR Article Created
ccr.article.update CCR Article Updated
ccr.article.destroy CCR Article Destroyed
ccr.violation_type.create New CCR Violation Type Created
ccr.violation_type.update CCR Violation Type Updated
ccr.violation_type.destroy CCR Violation Type Destroyed
user_account.create User Added to Account
user_account.update User Permission Updated
user_account.destroy User Removed from Account
inspections.violation.create Inspection Violation Created
inspections.violation.cure_reminder Inspection Violation Cure Reminder
inspections.violation.individual_create Individual Inspection Violation Created
inspections.violation_delivery.create Inspection Violation Notice Delivery Created
inspections.violation_delivery.sent Inspection Violation Notice Sent
inspections.violation_delivery.failed Inspection Violation Notice Delivery Failure
inspections.violation_response.create Property Owner Violation Response Created
inspections.violation.tag.added Inspection Violation Tag Added
inspections.violation.tag.removed Inspection Violation Tag Removed
inspections.violation.closed Inspection Violation Closed
inspections.violation.regression Inspection Violation Reopened
inspections.violation.update Inspection Violation Updated
inspections.violation.destroy Inspection Violation Destroyed
inspection.complete Inspection Completed
inspection.create Inspection Created
inspection.inspection_reminder Association Due for Inspection
inspections.escalation.create Inspection Escalation Created
inspections.escalation.snoozed Inspection Escalation Snoozed
inspections.escalation.snooze_expired Inspection Escalation Snooze Expired
inspections.escalation.resolve Inspection Escalation Resolved
inspections.escalation.note.create Inspection Escalation Note Created
inspections.escalations.letter.create Inspection Escalation Letter Created
inspections.suggested_violation.create Inspection Violation Suggestion Created
inspections.suggested_deficiency.create Inspection Deficiency Suggestion Created
property.create Property Created
property.update Property Updated
property.destroy Property Destroyed
property.note.create Property Note Created
property.tag.added Property Tag Added
property.tag.removed Property Tag Removed
properties.ownership_change_suggested Property Ownership Change Suggested
properties.ownership_change Property Ownership Changed
inspections.deficiency.create Asset Deficiency Created
inspections.deficiency.resolve Asset Deficiency Resolved
inspections.deficiency.snoozed Asset Deficiency Snoozed
inspections.deficiency.snooze_expired Asset Deficiency Snooze Expired
inspections.deficiency.note.create Asset Deficiency Note Created
inspections.deficiency.tag.added Asset Deficiency Tag Added
inspections.deficiency.tag.removed Asset Deficiency Tag Removed
asset.create Asset Created
asset.update Asset Updated
asset.destroy Asset Destroyed
asset.tag.added Asset Tag Added
asset.tag.removed Asset Tag Removed
violation_cover_letter.create Violation Cover letter Created
violation_cover_letter.update Violation Cover letter Updated
violation_cover_letter.destroy Violation Cover letter Destroyed
letter_templates.escalation.create Escalation Letter Template Created
letter_templates.escalation.update Escalation Letter Template Updated
letter_templates.escalation.destroy Escalation Letter Template Destroyed
letters.letter_delivery.create Letter Delivery Created
letters.letter_delivery.sent Letter Delivery Sent
letters.letter_delivery.failed Letter Delivery Failure
conversation.create Conversation Started
conversations.sent_message.create Conversation Message Sent
conversations.received_message.create Conversation Message Received

Verify Webhook Request Authenticity

Webhook POST requests will include the X-Signature HTTP header just like our API endpoint responses. See Verify Response Authenticity for details.

Idempotentcy

Webhooks may be retried a later time if a network error is encountered. Ensure your webhook endpoint supports handling of webhooks in an idempotent manner.

Retries

If a 2XX response code is not provided by your webhook endpoint, the webhook will be resent with an exponential back-off period. This accommodates service outages of your webhook endpoint.

Ordering

Many webhooks may be fired at once in near parallel order. As a result, it is important to consider the expected order of receipt and real-world order of receipt. For example, when an inspection is created, any related inspections.violation.create webhooks may be triggered shortly afterwards. You might be expecting the inspection.create webhook to be delivered first, however, this is not a guarantee (network latency or errors may disrupt this expectation).

Utilize your application's shared state (perhaps existence/absence of a database record) and non-2XX response codes to leverage Retries as a method of enforcing ordering of data. For example, if you require receipt of the inspection.create webhook before processing any inspections.violation.create webhooks, you could respond to any inspections.violation.create webhooks with a 404 until you've received and processed the inspection.create webhook. The 404-ed inspections.violation.create will automatically be retried.

Quick Responses

Webhooks are intended to quickly be fired and receive a response. A strict 4 second timeout is enforced for webhook network requests. Do any time consuming work outside of the network request of the webhook to avoid the request being terminated and the webhook being resent.