HAL-JSON

Hypertext Application Language, or HAL, is a format that allows for consistent output and gives the ability for HTTP clients to more easily discover additional capabilities of an API.

HAL itself is a set of conventions that can then be applied to any output. At Vonage, our APIs return JSON so we use an implementation of HAL called HAL-JSON.

This is a short description of the standard

  • HAL-JSON provides a consistent format supported by consumer and provider tooling.
  • Allows resources to be embedded using an _embedded property (with a distinguishing key).
  • Collections are resources that embed a set of resources of the same type.
  • Collections are not limited to a fixed set of properties (can create collection specific properties like queued_calls to provide a count of a subset).
  • Related resources will be referenced under a _links property.
  • There will always be a _links.self to the current resource.
  • Paging will use _links.

Important: The base URL in the _links section must reflect the host used for the incoming request. If the user calls https://api-eu-1.nexmo.com then the base URL for any href fields in _links must be the same (unless there are technical limitations why we must use https://api.nexmo.com)

Examples

Return a Single Resource

{
   "_links": {
      "self": {
         "href": "/calls/63f61863-4a51-4f6b-86e1-46edebcf9356"
      }
   },
   "uuid": "63f61863-4a51-4f6b-86e1-46edebcf9356",
   "conversation_uuid": "CON-f972836a-550f-45fa-956c-12a2ab5b7d22",
   "to": {
      "type": "phone",
      "number": "14155550100",
      "dtmfAnswer": "p*123#"
   },
   "from": {
      "type": "phone",
      "number": "447700900001"
   },
   "status": "completed",
   "direction": "outbound",
   "rate": "0.39",
   "price": "23.40",
   "duration": "60",
   "start_time": "2020-01-01 12:00:00",
   "end_time": "2020-01-01 12:00:00",
   "network": "65512"
}

Paged Collection

{
  "page_size": 100,
  "page": 3,
  "_embedded": {
    "calls": [
      {
        "uuid": "63f61863-4a51-4f6b-86e1-46edebcf9356",
        "conversation_uuid": "CON-f972836a-550f-45fa-956c-12a2ab5b7d22",
        "to": {
            "type": "phone",
            "number": "14155550100",
            "dtmfAnswer": "p*123#"
        },
        "from": {
            "type": "phone",
            "number": "447700900001"
        },
        "_links": {
            "self": {
              "href": "/calls/63f61863-4a51-4f6b-86e1-46edebcf9356"
            }
        },
      },
      {
        "uuid": "64c442da-a8dc-4b98-948a-1dc674686ac3",
        "conversation_uuid": "CON-12c54ff0-7c28-4d5e-99c0-15b1439ba746",
        "to": {
            "type": "phone",
            "number": "14155550100",
        },
        "from": {
            "type": "phone",
            "number": "447700900001"
        },
        "_links": {
            "self": {
              "href": "/calls/64c442da-a8dc-4b98-948a-1dc674686ac3"
            }
        },
      }
    ]
  },
  "_links": {
    "self": {
      "href": "https://api.nexmo.com/v1/calls/?page_size=100&order=asc&record_index=30"
    },
    "prev": {
      "href": "https://api.nexmo.com/v1/calls/?page_size=100&order=asc&record_index=20"
    }
  }
}

Why did we choose this?

Pre-existing standard