I had recently taken the Human Services Data Specification (HSDS) and exposed it as a set of API paths that provide access to about 95% of the schema, which we are calling the Human Services Data API (HSDA). When you make a call to the /organizations/ path, you receive an array collection of organizations that each match the HSDA organization schema. The same applies when you make a call to the /locations, /contacts, and /services, opening up access to the entire schema–minus three objects I pushed off until future releases.
After the core set of API paths /organization, /service, /location, /contact, there are a set of sub-resources available across those as it makes sense–including /phone, /programs, /physical_address, /postal_address, /regular_schedule, /holiday_schedule, /funding, /eligibility, /service_area, /required_document, /payment_accepted, /language, /accessiblity_for_disabilities, and /service_at_location_id. I took the HSDA schema, and published API paths for each sub-resource so that it exactly returned, and accepted HSDA compliant schema–making all aspects of the schema accessible via an API, with POST and PUT requests accepting compliant schema, and GET returning compliant schema.
One of the “stoppers” we received from several folks in the HSDS community during the feedback cycle going from version 1.0 of the API to version 1.1, was that the design was overly complex, and that it would serve any of the human services use cases on the table currently, unless you could get at all the sub resources directly with each core API path, eliminating the need for making additional call(s) to each sub-resource. You could get at everything about an /organization, /service, /location, and /contact in a single API URL.
Currently the core four API paths accept and return the following schema:
Organization
Field Name | Type (Format) | Description | Required? | Unique? |
---|---|---|---|---|
id | string (uuid) | Each organization must have a unique identifier. | True | True |
name | string | The official or public name of the organization. | True | False |
alternate_name | string | Alternative or commonly used name for the organization. | False | False |
description | string | A brief summary about the organization. It can contain markup such as HTML or Markdown. | True | False |
string (email) | The contact e-mail address for the organization. | False | False | |
url | string (url) | The URL (website address) of the organization. | False | False |
tax_status | string | Government assigned tax designation for for tax-exempt organizations. | False | False |
tax_id | string | A government issued identifier used for the purpose of tax administration. | False | False |
year_incorporated | date (%Y) | The year in which the organization was legally formed. | False | False |
legal_status | string | The legal status defines the conditions that an organization is operating under; e.g. non-profit, private corporation or a government organization. | False | False |
Service
Field Name | Type (Format) | Description | Required? | Unique? |
---|---|---|---|---|
id | string | Each service must have a unique identifier. | True | True |
organization_id | string | The identifier of the organization that provides this service. | True | False |
program_id | string | The identifier of the program this service is delivered under. | False | False |
name | string | The official or public name of the service. | True | False |
alternate_name | string | Alternative or commonly used name for a service. | False | False |
description | string | A description of the service. | False | False |
url | string (url) | URL of the service | False | False |
string (email) | Email address for the service | False | False | |
status | string | The current status of the service. | True | False |
interpretation_services | string | A description of any interpretation services available for accessing this service. | False | False |
application_process | string | The steps needed to access the service. | False | False |
wait_time | string | Time a client may expect to wait before receiving a service. | False | False |
fees | string | Details of any charges for service users to access this service. | False | False |
accreditations | string | Details of any accreditations. Accreditation is the formal evaluation of an organization or program against best practice standards set by an accrediting organization. | False | False |
licenses | string | An organization may have a license issued by a government entity to operate legally. A list of any such licenses can be provided here. | False | False |
taxonomy_ids | string | (Deprecated) A comma separated list of identifiers from the taxonomy table. This field is deprecated in favour of using the service_taxonomy table. | False | False |
Location
Field Name | Type (Format) | Description | Required? | Unique? |
---|---|---|---|---|
id | string | Each location must have a unique identifier | True | False |
organization_id | string | Each location entry should be linked to a single organization. This is the organization that is responsible for maintaining information about this location. The identifier of the organization should be given here. Details of the services the organisation delivers at this location should be provided in the services_at_location table. | False | False |
name | string | The name of the location | False | False |
alternate_name | string | An alternative name for the location | False | False |
description | string | A description of this location. | False | False |
transportation | string | A description of the access to public or private transportation to and from the location. | False | False |
latitude | number | Y coordinate of location expressed in decimal degrees in WGS84 datum. | False | False |
longitude | number | X coordinate of location expressed in decimal degrees in WGS84 datum. | False | False |
Contact
Field Name | Type (Format) | Description | Required? | Unique? |
---|---|---|---|---|
id | string | Each contact must have a unique identifier | True | False |
organization_id | string | The identifier of the organization for which this is a contact | False | False |
service_id | string | The identifier of the service for which this is a contact | False | False |
service_at_location_id | string | The identifier of the ‘service at location’ table entry, when this contact is specific to a service in a particular location. | False | False |
name | string | The name of the person | False | False |
title | string | The job title of the person | False | False |
department | string | The department that the person is part of | False | False |
string (email) | The email address of the person | False | False |
To ensure that all sub-resource area available as part of each of the requests and responses for all core API paths, we are going to have to evolve the HSDS schema to be:
Organization
Field Name | Type (Format) | Description | Required? | Unique? |
---|---|---|---|---|
id | string (uuid) | Each organization must have a unique identifier. | True | True |
name | string | The official or public name of the organization. | True | False |
alternate_name | string | Alternative or commonly used name for the organization. | False | False |
description | string | A brief summary about the organization. It can contain markup such as HTML or Markdown. | True | False |
string (email) | The contact e-mail address for the organization. | False | False | |
url | string (url) | The URL (website address) of the organization. | False | False |
tax_status | string | Government assigned tax designation for for tax-exempt organizations. | False | False |
tax_id | string | A government issued identifier used for the purpose of tax administration. | False | False |
year_incorporated | date (%Y) | The year in which the organization was legally formed. | False | False |
legal_status | string | The legal status defines the conditions that an organization is operating under; e.g. non-profit, private corporation or a government organization. | False | False |
services | array | Returns a collection of services for each organization | False | False |
locations | array | Returns a collection of locations for each organization | False | False |
contacts | array | Returns a collection of contacts for each organization | False | False |
phones | array | Returns a collection of phones for each organization | False | False |
programs | array | Returns a collection of programs for each organization | False | False |
fundings | array | Returns a collection of fundings for each organization | False | False |
Service
Field Name | Type (Format) | Description | Required? | Unique? |
---|---|---|---|---|
id | string | Each service must have a unique identifier. | True | True |
organization_id | string | The identifier of the organization that provides this service. | True | False |
program_id | string | The identifier of the program this service is delivered under. | False | False |
name | string | The official or public name of the service. | True | False |
alternate_name | string | Alternative or commonly used name for a service. | False | False |
description | string | A description of the service. | False | False |
url | string (url) | URL of the service | False | False |
string (email) | Email address for the service | False | False | |
status | string | The current status of the service. | True | False |
interpretation_services | string | A description of any interpretation services available for accessing this service. | False | False |
application_process | string | The steps needed to access the service. | False | False |
wait_time | string | Time a client may expect to wait before receiving a service. | False | False |
fees | string | Details of any charges for service users to access this service. | False | False |
accreditations | string | Details of any accreditations. Accreditation is the formal evaluation of an organization or program against best practice standards set by an accrediting organization. | False | False |
licenses | string | An organization may have a license issued by a government entity to operate legally. A list of any such licenses can be provided here. | False | False |
taxonomy_ids | string | (Deprecated) A comma separated list of identifiers from the taxonomy table. This field is deprecated in favour of using the service_taxonomy table. | False | False |
contacts | array | Returns a collection of contacts for each service. | False | False |
phones | array | Returns a collection of phones for each service. | False | False |
regular_schedules | array | Returns a collection of regular schedules for each service. | False | False |
holiday_schedules | array | Returns a collection of holiday schedules for each service. | False | False |
fundings | array | Returns a collection of fundings for each service. | False | False |
eligibilities | array | Returns a collection of eligibilities for each service. | False | False |
service_areas | array | Returns a collection of service areas for each service. | False | False |
required_documents | array | Returns a collection of required documents for each service. | False | False |
payments_accepted | array | Returns a collection of payments accepted for each service. | False | False |
languages | array | Returns a collection of languages for each service. | False | False |
Location
Field Name | Type (Format) | Description | Required? | Unique? |
---|---|---|---|---|
id | string | Each location must have a unique identifier | True | False |
organization_id | string | Each location entry should be linked to a single organization. This is the organization that is responsible for maintaining information about this location. The identifier of the organization should be given here. Details of the services the organisation delivers at this location should be provided in the services_at_location table. | False | False |
name | string | The name of the location | False | False |
alternate_name | string | An alternative name for the location | False | False |
description | string | A description of this location. | False | False |
transportation | string | A description of the access to public or private transportation to and from the location. | False | False |
latitude | number | Y coordinate of location expressed in decimal degrees in WGS84 datum. | False | False |
longitude | number | X coordinate of location expressed in decimal degrees in WGS84 datum. | False | False |
phones | array | Returns a collection of phones for each location. | False | False |
physical_addresses | array | Returns a collection of physical addresses for each location. | False | False |
postal_addresses | array | Returns a collection of postal addresses for each location. | False | False |
regular_schedules | array | Returns a collection of regular schedules for each location. | False | False |
holiday_schedules | array | Returns a collection of holiday schedules for each location. | False | False |
languages | array | Returns a collection of languages for each location. | False | False |
accessiblity_for_disabilities | array | Returns a collection of accessiblity_for_disabilities for each location. | False | False |
Contact
Field Name | Type (Format) | Description | Required? | Unique? |
---|---|---|---|---|
id | string | Each contact must have a unique identifier | True | False |
organization_id | string | The identifier of the organization for which this is a contact | False | False |
service_id | string | The identifier of the service for which this is a contact | False | False |
service_at_location_id | string | The identifier of the ‘service at location’ table entry, when this contact is specific to a service in a particular location. | False | False |
name | string | The name of the person | False | False |
title | string | The job title of the person | False | False |
department | string | The department that the person is part of | False | False |
string (email) | The email address of the person | False | False | |
phones | array | Returns a collection of phones for each contact | False | False |
Once we add all relevant sub-resources added as arrays to the HSDS schema, we can allow API consumers to POST and PUT, or GET using as little, or as much of the schema using the path, header, or parameter. Allowing for reading and writing HSDS at the granular level, or everything at once using a single path.
Next we need to consider this updated schema as part of the 1.2 release of HSDS. If we update HSDA to allow for filtering the schema across /organization, /service, /location, and /contact, and return each sub-resource as part of the API request or response, it will be out of sync with HSDS. Ideally, both HSDS, and HSDA move forward in sync with each version. I’m curious why this expanded schema became such an issue once we got to the API phase–it seems like it should have been part of v1.1 of HSDS, making the schema drive the API instead of the other way around.
I’m guessing that these concerns about schema don’t come into focus until we start talking about access to the schema, and data. Making the separation and relationships between HSDS and HSDA all the more important, providing a framework to move the schema forward in a way that is rooted in how it will actually be accessed. Which is why we do APIs…