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

HOALife supports two kinds of API credentials:

Both credential types can use the Authorization: Token ... header. Service Account API Keys also support the Basic Authentication and URL parameter methods documented below. User Access API Keys require the Token header.

Service Account API Keys 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

User Access API Keys (OAuth)

User Access API Keys are issued through OAuth Authorization Code with PKCE. The HOALife CLI is a public client: it does not have a client secret. It starts the flow over HTTPS, opens the returned authorization URL in a browser, and listens on a local loopback callback for the authorization code. The resulting credential belongs to the user, is limited to the selected account and approved access level, and expires unless refreshed.

1. Create an authorization request

Generate a cryptographically random state and PKCE code_verifier. Use an unpadded Base64URL-encoded verifier between 43 and 128 characters long. Calculate the S256 challenge as the unpadded Base64URL encoding of SHA256(code_verifier). Keep the state and verifier in the CLI process; do not put either in the browser URL.

Choose an available port and use this exact loopback callback format for both requests:

http://127.0.0.1:{port}/oauth/callback

For example, request an authorization URL with cURL:

curl --fail-with-body https://api.hoalife.com/oauth/authorization-requests \
  -H "Content-Type: application/json" \
  -d '{"client_id":"hoalife-cli","redirect_uri":"http://127.0.0.1:49152/oauth/callback","state":"STATE_FROM_CLI","code_challenge":"S256_CHALLENGE_FROM_CLI"}'

The response contains an authorization_url. Open it in the user's browser. The user signs in if needed, selects an account if they have access to more than one eligible account, and approves the requested access. When CLI access is enabled on a root account, eligible leaf accounts beneath it can be selected. A user with one eligible account skips account selection. Account eligibility depends on the user's highest eligible membership role; architectural committee members and voters cannot authorize CLI access when they are the highest eligible role. Account administrators can grant read-only, read/write, or read/write/delete access; other eligible membership roles can grant read-only access only.

2. Receive the authorization response

After approval, HOALife redirects the browser to the loopback callback with a short-lived authorization code and the original state. The CLI must compare the returned state with the value it generated before proceeding. If the user cancels, the callback contains error=access_denied and the state instead of a code. The CLI should handle that response and close its local listener.

Authorization codes expire after five minutes and can be exchanged only once. The authorization request itself expires after ten minutes if it is not completed.

3. Exchange the code for a credential

Send the code, original redirect URI, and verifier to the token endpoint:

curl --fail-with-body https://api.hoalife.com/oauth/token \
  -H "Content-Type: application/json" \
  -d '{"client_id":"hoalife-cli","redirect_uri":"http://127.0.0.1:49152/oauth/callback","code":"CODE_FROM_CALLBACK","code_verifier":"VERIFIER_FROM_CLI"}'

The response contains an access_token, a refresh_token, a signing_secret, and token_type of Token. The access token is a User Access API Key. The signing secret is used to verify the API's X-Signature HMAC header. The credential is associated with the user and selected account, with the membership recorded when access came through one. API requests are scoped to the selected account. Its permissions are limited to the selected grant: read grants allow read actions; write grants allow read, create, and update actions; delete grants additionally allow destroy actions. These values are returned only once, so store them securely and never log them.

The access token expires in 24 hours (expires_in). A refresh token expires if it is not used within seven days (refresh_token_expires_in); each successful refresh rotates it and starts a new seven-day period. The grant has a one-year absolute lifetime (grant_expires_in). Refresh the pair by sending the current refresh token and client ID:

curl --fail-with-body https://api.hoalife.com/oauth/token \
  -H "Content-Type: application/json" \
  -d '{"grant_type":"refresh_token","client_id":"hoalife-cli","refresh_token":"REFRESH_TOKEN_FROM_PREVIOUS_RESPONSE"}'

The response contains a replacement access token, refresh token, and the same signing secret. Store the replacement tokens securely, discard the previous pair, and serialize refresh attempts. Refresh tokens are single-use; reusing a consumed token revokes the grant. If a refresh token has expired or the grant has reached its one-year lifetime, complete browser authorization again.

Requests to /api/info do not count against an API credential's request limit.

After the token exchange succeeds, the CLI may redirect the browser to /authorization-issued.html on the same HOALife host. This static page confirms authorization is complete and asks the user to return to the CLI; it does not receive the authorization code or access token.

4. Make API requests

Send the credential in the Authorization header:

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

User Access API Keys are accepted with the Token header. They are not accepted with HTTP Basic authentication or the api_key URL parameter. Service Account API Keys can use the authentication methods in the section above.

To check which account and permissions a credential represents, request /api/info with the same header. The response includes the account ID and name, the credential type, its permissions, and (for User Access API Keys) its access level and access_token_expires_at. The API currently returns credential_type: "cli" for User Access API Keys and credential_type: "service_account" for Service Account API Keys.

curl https://api.hoalife.com/api/info \
  -H "Authorization: Token cli_SUPERSECRET"

Revoke access

To revoke a grant, send the current refresh token and client ID to POST /oauth/revoke:

curl --fail-with-body https://api.hoalife.com/oauth/revoke \
  -H "Content-Type: application/json" \
  -d '{"client_id":"hoalife-cli","token":"REFRESH_TOKEN"}'

The endpoint returns success for unknown tokens and tokens belonging to another client. Revoking the refresh token invalidates the entire grant, including the current access token, even when that access token has expired. DELETE /api/logout remains available when a valid access token is present. A User Access API Key stops working if the user no longer has the access required by its grant. The CLI should discard its local copy when the user signs out or revokes access.

User Access API Keys do not grant webhook access. Webhooks are reserved for Service Account API Keys and cannot be created or managed with OAuth-issued credentials.

Service Account API Keys 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=

Service Account API Keys 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 5 requests per second; requests to /api/info are excluded. 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,
        "lot_number": 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",
        "lot_number": null,
        "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
lot_number String Any string to identify the lot

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_addresses" \
  -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_addresses

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.

Close Violation

curl "https://api.hoalife.com/api/violations/42/close" \
  -X POST \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "attributes": {
          "remarks": "Repairs have been verified"
        }
      }
    }
  '

The response contains the updated Violation, including its closed and closed_at attributes when violation closing is enabled for the account. The remarks attribute is optional. Closing is available to API credentials with update permission when the Violation is open, violation closing is enabled, and it has no subsequent violations.

HTTP Request

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

URL Parameters

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

Writable Attributes

Parameter Type Description Required
remarks String Optional HTML remarks recorded when closing the Violation. The content is sanitized before it is saved. 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": "/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

ACC Request Forms

ACC Request Forms define the information collected for architectural change requests.

Get All ACC Request Forms

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

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "42",
      "type": "acc_request_form",
      "attributes": {
        "id": 42,
        "name": "Exterior Changes",
        "description": "Describe your planned changes.",
        "created_at": "2025-01-01T12:00:00.000Z",
        "updated_at": "2025-01-01T12:00:00.000Z",
        "account_id": 123
      },
      "relationships": {}
    }
  ],
  "meta": {
    "current_page": 1,
    "total": 1,
    "total_pages": 1
  },
  "links": {
    "self": "/api/acc_request_forms?page=1",
    "next": "/api/acc_request_forms",
    "prev": "/api/acc_request_forms"
  }
}

Returns enabled forms defined for the API key's account, its descendant accounts, and ancestor accounts whose forms are inherited. Requirements are available from the ACC request requirements endpoint and refer to their form with request_type_id.

The API key must have read permission for acc_request_forms.

HTTP Request

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

Attributes

Parameter Type Description
id Integer Unique identifier of the ACC Request Form
account_id Integer Unique identifier of the Account the form belongs to
name String Name of the form
description String Description of the form

Query Parameters

Parameter Query By Order By
id true true
account_id true false
name true true

Create ACC Request Form

curl "https://api.hoalife.com/api/acc_request_forms" \
  -X POST \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "acc_request_form",
        "attributes": {
          "name": "Exterior Changes",
          "description": "Describe your planned changes."
        },
        "relationships": {
          "account": {
            "data": {
              "type": "account",
              "id": 123
            }
          }
        }
      }
    }
  '

The above command returns JSON structured like this:

{
  "data": {
    "id": "42",
    "type": "acc_request_form",
    "attributes": {
      "id": 42,
      "name": "Exterior Changes",
      "description": "Describe your planned changes.",
      "created_at": "2025-01-01T12:00:00.000Z",
      "updated_at": "2025-01-01T12:00:00.000Z",
      "account_id": 123
    },
    "relationships": {}
  }
}

This endpoint creates a new ACC Request Form. The API key must have create permission for acc_request_forms. The account must be the API key's account or one of its descendants.

HTTP Request

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

ACC Request Form Writable Attributes

Parameter Type Description Required
account_id Integer Unique identifier of the Account the form belongs to. Pass it in data.relationships.account.data.id or data.attributes.account_id true
name String Name of the form true
description String Description of the form true

Update ACC Request Form

curl "https://api.hoalife.com/api/acc_request_forms/42" \
  -X PUT \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "acc_request_form",
        "attributes": {
          "name": "Exterior Changes",
          "description": "Describe your planned changes."
        }
      }
    }
  '

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

This endpoint updates an existing ACC Request Form. The API key must have update permission for acc_request_forms. The form must be owned by the API key's account or a descendant account.

HTTP Request

PUT https://api.hoalife.com/api/acc_request_forms/:id

URL Parameters

Parameter Type Description
:id Integer Unique identifier of the ACC Request Form the request is being made for

Editable Attributes

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

Destroy ACC Request Form

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

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

This endpoint destroys an existing ACC Request Form. The API key must have destroy permission for acc_request_forms. The form must be owned by the API key's account or a descendant account. Forms that already have requests are disabled to preserve their history. Otherwise, the actual deletion is performed in a background process, so the API may continue to return the form for a short time after you've requested it be deleted.

HTTP Request

DELETE https://api.hoalife.com/api/acc_request_forms/:id

URL Parameters

Parameter Type Description
:id Integer Unique identifier of the ACC Request Form the request is being made for

ACC Request Requirements

ACC Request Requirements define the fields shown on an ACC Request Form.

Get All ACC Request Requirements

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

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "84",
      "type": "acc_request_requirement",
      "attributes": {
        "id": 84,
        "title": "Project description",
        "description": "Describe the work.",
        "input_type": "plain_text",
        "options": null,
        "include_other": false,
        "optional": false,
        "order": 1,
        "request_type_id": 42
      },
      "relationships": {}
    }
  ],
  "meta": {
    "current_page": 1,
    "total": 1,
    "total_pages": 1
  },
  "links": {
    "self": "/api/acc_request_requirements?page=1",
    "next": "/api/acc_request_requirements",
    "prev": "/api/acc_request_requirements"
  }
}

Returns enabled requirements for enabled forms in the API key's account tree, including inherited ancestor forms.

The API key must have read permission for acc_request_requirements.

HTTP Request

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

Attributes

Parameter Type Description
id Integer Unique identifier of the requirement
request_type_id Integer Unique identifier of the form the requirement belongs to
title String Title of the requirement
description String Description of the requirement
input_type String Type of input
options String Newline-separated choices for dropdown, radio, or checkbox inputs
include_other Boolean Whether to include an “other” option for choice inputs
optional Boolean Whether the requester may skip this requirement
order Integer Display order

Query Parameters

Parameter Query By Order By
id true true
account_id true false
request_type_id true true
title true true
input_type true true
optional true true
order false true

Create ACC Request Requirement

curl "https://api.hoalife.com/api/acc_request_requirements" \
  -X POST \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "acc_request_requirement",
        "attributes": {
          "title": "Project description",
          "description": "Describe the work.",
          "input_type": "plain_text",
          "include_other": false,
          "optional": false,
          "order": 1
        },
        "relationships": {
          "request_type": {
            "data": {
              "type": "acc_request_form",
              "id": 42
            }
          }
        }
      }
    }
  '

The above command returns JSON structured like this:

{
  "data": {
    "id": "84",
    "type": "acc_request_requirement",
    "attributes": {
      "id": 84,
      "title": "Project description",
      "description": "Describe the work.",
      "input_type": "plain_text",
      "options": null,
      "include_other": false,
      "optional": false,
      "order": 1,
      "request_type_id": 42
    },
    "relationships": {}
  }
}

This endpoint creates a new ACC Request Requirement. The API key must have create permission for acc_request_requirements. The form must belong to the API key's account or one of its descendants.

HTTP Request

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

ACC Request Requirement Writable Attributes

Parameter Type Description Required
request_type_id Integer Unique identifier of the form the requirement belongs to. Pass it in data.relationships.request_type.data.id or data.attributes.request_type_id true
title String Title of the requirement true
description String Description of the requirement. May be an empty string true
input_type String Type of input: rich_text, plain_text, dropdown, radio, checkbox, file_upload, date, date_range, signature, or payment. Defaults to rich_text false
options String Newline-separated choices for dropdown, radio, or checkbox inputs false
include_other Boolean Whether to include an “other” option for choice inputs false
optional Boolean Whether the requester may skip this requirement false
order Integer Display order. If omitted or null, the next order is assigned false

Update ACC Request Requirement

curl "https://api.hoalife.com/api/acc_request_requirements/84" \
  -X PUT \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "acc_request_requirement",
        "attributes": {
          "title": "Work description",
          "optional": true
        }
      }
    }
  '

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

This endpoint updates an existing ACC Request Requirement. The API key must have update permission for acc_request_requirements. Its form must be owned by the API key's account or a descendant account.

HTTP Request

PUT https://api.hoalife.com/api/acc_request_requirements/:id

URL Parameters

Parameter Type Description
:id Integer Unique identifier of the ACC Request Requirement the request is being made for

Editable Attributes

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

Destroy ACC Request Requirement

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

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

This endpoint destroys an existing ACC Request Requirement. The API key must have destroy permission for acc_request_requirements. Its form must be owned by the API key's account or a descendant account. The actual deletion is performed in a background process, so the API may continue to return the requirement for a short time after you've requested it be deleted.

HTTP Request

DELETE https://api.hoalife.com/api/acc_request_requirements/:id

URL Parameters

Parameter Type Description
:id Integer Unique identifier of the ACC Request Requirement the request is being made for

ACC Requests

ACC Requests represent architectural change requests submitted for properties.

Get All ACC Requests

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

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "256",
      "type": "acc_request",
      "attributes": {
        "id": 256,
        "formatted_id": "ARC-256",
        "status": "submitted",
        "status_last_changed_at": "2025-01-01T12:00:00.000Z",
        "remarks": null,
        "tags": [],
        "created_at": "2025-01-01T12:00:00.000Z",
        "updated_at": "2025-01-01T12:00:00.000Z",
        "property_id": 456,
        "request_type_id": 42,
        "account_id": 123
      },
      "relationships": {}
    }
  ],
  "meta": {
    "current_page": 1,
    "total": 1,
    "total_pages": 1
  },
  "links": {
    "self": "/api/acc_requests?page=1",
    "next": "/api/acc_requests",
    "prev": "/api/acc_requests"
  }
}

Returns ACC requests for the API key's account and descendant accounts. Request response values are available from the ACC request responses endpoint and refer to their request and requirement with request_id and request_requirement_id.

The API key must have read permission for acc_requests.

HTTP Request

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

Attributes

Parameter Type Description
id Integer Unique identifier of the ACC Request
formatted_id String Humanized unique identifier
status String Current request status
status_last_changed_at String Date the status last changed
remarks String Remarks associated with the request
tags Array[String] Tags associated with the request
created_at String Date the request was created
updated_at String Date the request was last updated
property_id Integer Unique identifier of the Property the request belongs to
request_type_id Integer Unique identifier of the form used by the request
account_id Integer Unique identifier of the Account the request belongs to

Query Parameters

Parameter Query By Order By
id true true
account_id true false
property_id true true
request_type_id true true
formatted_id true true
status true true
status_last_changed_at false true

ACC Request Responses

ACC Request Responses contain answers submitted for ACC Request Requirements.

Get All ACC Request Responses

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

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "512",
      "type": "acc_request_response",
      "attributes": {
        "id": 512,
        "data": {"content": "The planned exterior changes are..."},
        "skipped": false,
        "request_id": 256,
        "request_requirement_id": 84,
        "created_at": "2025-01-01T12:00:00.000Z",
        "updated_at": "2025-01-01T12:00:00.000Z",
        "input_type": "plain_text"
      },
      "relationships": {}
    }
  ],
  "meta": {
    "current_page": 1,
    "total": 1,
    "total_pages": 1
  },
  "links": {
    "self": "/api/acc_request_responses?page=1",
    "next": "/api/acc_request_responses",
    "prev": "/api/acc_request_responses"
  }
}

Returns responses for ACC requests in the API key's account and descendant accounts.

The API key must have read permission for acc_request_responses.

HTTP Request

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

Attributes

Parameter Type Description
id Integer Unique identifier of the response
request_id Integer Unique identifier of the ACC Request the response belongs to
request_requirement_id Integer Unique identifier of the requirement the response answers
input_type String Type of input used for the response
data Object Response value
skipped Boolean Whether the requester skipped the requirement
created_at String Date the response was created
updated_at String Date the response was last updated

Query Parameters

Parameter Query By Order By
id true true
account_id true false
request_id true true
request_requirement_id true true
skipped true true

ACC Request Votes

ACC Request Votes represent votes and pending vote requests attached to ACC Requests.

Get All ACC Request Votes

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

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "789",
      "type": "acc_request_vote",
      "attributes": {
        "id": 789,
        "status": "requested",
        "comment": null,
        "created_at": "2025-01-01T12:00:00.000Z",
        "updated_at": "2025-01-01T12:00:00.000Z",
        "voter_type": "User",
        "voter_id": 456,
        "request_id": 256
      },
      "relationships": {}
    }
  ],
  "meta": {
    "current_page": 1,
    "total": 1,
    "total_pages": 1
  },
  "links": {
    "self": "/api/acc_request_votes?page=1",
    "next": "/api/acc_request_votes",
    "prev": "/api/acc_request_votes"
  }
}

Returns votes attached to ACC requests in the API key's account and descendant accounts. Votes for other resource types are not included.

The API key must have read permission for acc_request_votes.

HTTP Request

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

Attributes

Parameter Type Description
id Integer Unique identifier of the vote
status String Vote status
comment String Comment associated with the vote
created_at String Date the vote was created
updated_at String Date the vote was last updated
voter_type String Type of voter
voter_id Integer Unique identifier of the voter
request_id Integer Unique identifier of the ACC Request the vote belongs to

Query Parameters

Parameter Query By Order By
id true true
account_id true false
request_id true false
voter_id true true
status true true

Request an ACC Request Vote

curl "https://api.hoalife.com/api/acc_request_votes" \
  -X POST \
  -H "Authorization: Token sk_SUPERSECRET" \
  -H "Content-Type: application/vnd.api+json" \
  -d '
    {
      "data": {
        "type": "acc_request_vote",
        "attributes": {
          "request_id": 256,
          "user_id": 456,
          "status": "requested"
        }
      }
    }
  '

The above command returns JSON structured like this:

{
  "data": {
    "id": "789",
    "type": "acc_request_vote",
    "attributes": {
      "id": 789,
      "status": "requested",
      "comment": null,
      "created_at": "2025-01-01T12:00:00.000Z",
      "updated_at": "2025-01-01T12:00:00.000Z",
      "voter_type": "User",
      "voter_id": 456,
      "request_id": 256
    },
    "relationships": {}
  }
}

This endpoint creates a pending vote request. The API key must have create permission for acc_request_votes. The user must have a non-read-only authorization in the ACC request's account or an ancestor account. The request must be submitted and within the API key's account scope. The API sends the same vote-request notifications as the dashboard workflow.

HTTP Request

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

Writable Attributes

Parameter Type Description Required
request_id Integer Unique identifier of the submitted ACC Request true
user_id Integer Unique identifier of the User who should vote true
status String Vote status. Only requested is accepted; defaults to requested false

Revoke an ACC Request Vote Request

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

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

This endpoint destroys a pending vote request. The API key must have destroy permission for acc_request_votes. Cast votes cannot be revoked through this endpoint. The vote must belong to an ACC request in the API key's account or a descendant account.

HTTP Request

DELETE https://api.hoalife.com/api/acc_request_votes/:id

URL Parameters

Parameter Type Description
:id Integer Unique identifier of the ACC Request Vote the request is being made for

Notes

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

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": "acc_request",
              "id": 42
            }
          },
          "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": "acc_request",
        "attached_to_id": 42,
        "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

Use attached_to.type: "acc_request" and the ACC request's ID to attach a note to that request. The request must be within the API key's account scope.

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.