NAV Navbar
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.

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 (10 per 5sec)

To ensure a consistent and reliable service, this API limits the number of requests per API key within a given time frame. This limit of 10 requests per 5 seconds. The rate limit is enforced as a GCRA "Leaky Bucket".

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 5sec if X-RateLimit-Remaining < 1.

Verify Response 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": "https://api.hoalife.com/api/accounts/1/properties?page=1",
  "next": "https://api.hoalife.com/api/accounts/1/properties?page=2",
  "prev": "https://api.hoalife.com/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": "https://api.hoalife.com/api/accounts?page=1",
    "next": "https://api.hoalife.com/api/accounts",
    "prev": "https://api.hoalife.com/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"
        },
        "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

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

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

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"
            }
        ],
        "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": [],
        "external_id": null
      },
      "relationships": {}
    }
  ],
  "meta": {
    "current_page": 1,
    "total": 858,
    "total_pages": 35
  },
  "links": {
    "self": "https://api.hoalife.com/api/properties?page=1",
    "next": "https://api.hoalife.com/api/properties?page=2",
    "prev": "https://api.hoalife.com/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
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
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

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*
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"
        }
      }
    }
  '

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

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": "https://api.hoalife.com/api/ccr_articles?page=1",
    "next": "https://api.hoalife.com/api/ccr_articles",
    "prev": "https://api.hoalife.com/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

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

Violation Types

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

Get All Violation Types

curl "https://api.hoalife.com/api/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": "https://api.hoalife.com/api/violation_types?page=1",
    "next": "https://api.hoalife.com/api/violation_types",
    "prev": "https://api.hoalife.com/api/violation_types"
  }
}

This endpoint retrieves all 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 Violation Types to a specific Account by adding an account_id query parameter.

HTTP Request

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

Attributes

Parameter Type Description
id Integer Unique identifier of the Violation Type
account_id Integer Unique identifier of Account the Violation Type belongs to
ccr_article_id Integer Unique identifier of CCR Article the Violation Type belongs to
title String Title of the 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

Writable Attributes

Parameter Type Description Required
ccr_article_id Integer Unique identifier of CCR Article the Violation Type belongs to true
title String Title of the 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

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",
        "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",
        "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": "https://api.hoalife.com/api/violations?page=1",
    "next": "https://api.hoalife.com/api/violations",
    "prev": "https://api.hoalife.com/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
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
comment true true
upload_urls false false
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",
        },
        "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 false
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

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": "property",
        "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 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

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": "https://api.hoalife.com/api/violations?id=1"
          },
          {
            "id": 2,
            "triggered_escalation": false,
            "link": "https://api.hoalife.com/api/violations?id=2"
          },
          {
            "id": 3,
            "triggered_escalation": true,
            "link": "https://api.hoalife.com/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": "https://api.hoalife.com/api/violations?id=4"
          },
          {
            "id": 5,
            "triggered_escalation": false,
            "link": "https://api.hoalife.com/api/violations?id=5"
          },
          {
            "id": 6,
            "triggered_escalation": true,
            "link": "https://api.hoalife.com/api/violations?id=6"
          }
        ],
        "resolver": {
          "name": null,
          "email": null
        },
        "notes": []
      },
      "relationships": {}
    }
  ],
  "meta": {
    "current_page": 1,
    "total": 2,
    "total_pages": 1
  },
  "links": {
    "self": "https://api.hoalife.com/api/escalations?page=1",
    "next": "https://api.hoalife.com/api/escalations",
    "prev": "https://api.hoalife.com/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

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"
      }
    }
  }
}