> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nmbr.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Responses

> Viewing and Expanding resources on the Nmbr API

## ULID

All Nmbr entities have an `id`. These ids are based on a customized version of [ULIDs](https://github.com/ulid/spec). Nmbr ULIDs take the form of a standard `ULID` prefixed with a namespace reference.

For example, an employee may be `emp_01JAV10D4QJ3500QANBTTBW9DW`, and a company may be `cmp_01JAV11013A9V4V0F30099BVGH`.

## Response Structure

Objects across the Nmbr API follow a consistent JSON structure, either a single Entity, a Pageable List, or a Non-Pageable List.

Entities and Lists can be returned as the root response on an endpoint.

### Entities

Entity Responses will follow the structure:

```json theme={null}
{
    "id":  string (ULID),
    "object": string,
    "data": {
        // ...
    },
    "links": {
        "self": string (url)
    }
}
```

### Pageable Lists

Pageable Lists contain up to 15 objects per-page and can be paged using the associated `links` data. The `object` type will always have the value `list` .

```json theme={null}
{
    "object": "list",
    "data": [
        {
            "id": string (GUID),
            "object": string,
            "data": {
                // ...
                "created_at": string (ISO-8601),
                "updated_at":string (ISO-8601)
            },
            "links": {
                "self": string (url)
            }
        }
        // ...
    ],
    "links": {
        "first": string (url),
        "last": string (url),
        "prev": string (url)|null,
        "next": string (url)|null
    },
    "meta": {
        "current_page": int,
        "last_page": int,
        "per_page": int,
        "total": int,
        "has_more": boolean
    }
}
```

### Non-Pageable Lists

Non-Pageable Lists are returned for lists with no related endpoint to page through. In these cases the complete data set will be returned as a `list` with no paging information.

```json theme={null}
{
    "object": "list",
    "data": [
        {
            "id": string (GUID),
            "object": string,
            "data": {
                // ...
            },
            "links": {
                "self": url
            }
        }
        // ...
    ]
}
```

## Related Resources

Entities will contain references to other objects - e.g an Employee will contain a Company reference. By default, these will be "stub" entities which will have no `data` attribute. They may be an Entity, a Pageable List or a Non-Pageable List.

```json theme={null}
{
  "id": "01hfwg26zxk6bg8874nth78cgr",
  "object": "employee",
  "data": {
    "company": {
      "id": "01hfwg25dbyebq330k8c8ammpm",
      "object": "company",
      "links": {
        "self": "https://sandbox.nmbr.co/services/payroll/companies/01hfwg25dbyebq330k8c8ammpm"
      }
    },
    // ...
    "created_at": "2023-11-22T21:48:01.000000Z",
    "updated_at": "2023-11-22T21:48:01.000000Z"
  },
  "links": {
    "self": "https://sandbox.nmbr.co/services/payroll/employees/01hfwg26zxk6bg8874nth78cgr"
  }
}
```

## Expanding Resources

If you would like to retrieve the `data` of a related resource inline, you may pass the `expand` array parameter to expand its contents.

Request:

```bash theme={null}
curl 'https://sandbox.nmbr.co/services/payroll/employees/01hfwg26zxk6bg8874nth78cgr?expand[]=company' \
--header 'Authorization: Bearer Llk5NQVFt9bu2auhJBuBxFGih22VecGq8qUeDD0Q7aa0c5bf'
```

Response

```json theme={null}
{
  "id": "01hfwg26zxk6bg8874nth78cgr",
  "object": "employee",
  "data": {
    "company": {
      "id": "01hfwg25dbyebq330k8c8ammpm",
      "object": "company",
      "data": {
        "name": "Bouchard Inc.",
        "pay_day_movement_setting": "inherit",
        "status": "onboarding",
        "created_at": "2023-11-22T21:47:59.000000Z",
        "updated_at": "2023-11-22T21:47:59.000000Z"
      },
      "links": {
        "self": "https://sandbox.nmbr.co/services/payroll/companies/01hfwg25dbyebq330k8c8ammpm"
      }
    },
    // ...
    "created_at": "2023-11-22T21:48:01.000000Z",
    "updated_at": "2023-11-22T21:48:01.000000Z"
  },
  "links": {
    "self": "https://sandbox.nmbr.co/services/payroll/employees/01hfwg26zxk6bg8874nth78cgr"
  }
}
```

The API will return "stub" objects to represent related Entities and Lists of related Entities. These objects can be expanded to include their `data` by passing the `expand` parameter in your request.

You can expand multiple layers down by defining dot (`.`) notation values to the `expand` array.

In the following example, the `company` entity is expanded to a full `company` resource, and its pageable-list of `business_entities` is expanded into a list of `business_entity` resources.

Request:

```shell theme={null}
curl 'https://sandbox.nmbr.co/services/payroll/employees/01hfwg26zxk6bg8874nth78cgr?expand[]=company.business_entities' \
--header 'Authorization: Bearer Llk5NQVFt9bu2auhJBuBxFGih22VecGq8qUeDD0Q7aa0c5bf'
```

Response:

```json theme={null}
{
    "id": "01hfwg26zxk6bg8874nth78cgr",
    "object": "employee",
    "data": {
        "company": {
            "id": "01hfwg25dbyebq330k8c8ammpm",
            "object": "company",
            "data": {
                "name": "Bouchard Inc.",
                "pay_day_movement_setting": "inherit",
                "status": "onboarding",
                "business_entities": {
                    "object": "list",
                    "data": [
                        {
                            "id": "01hfwg25fz7t023he2jr3b2nas",
                            "object": "business_entity",
                            "data": {
                                "business_number": "34y6y3",
                                // ...
                                },
                                "company": {
                                    "id": "01hfwg25dbyebq330k8c8ammpm",
                                    "object": "company",
                                    "links": {
                                        "self": "https://sandbox.nmbr.co/services/payroll/companies/01hfwg25dbyebq330k8c8ammpm"
                                    }
                                },
                                "created_at": "2023-11-22T21:47:59.000000Z",
                                "updated_at": "2023-11-22T21:47:59.000000Z"
                            },
                            "links": {
                                "self": "https://sandbox.nmbr.co/services/payroll/business_entities/01hfwg25fz7t023he2jr3b2nas"
                            }
                        }
                    ],
                    "links": {
                        "first": "https://sandbox.nmbr.co/services/payroll/business_entities?page=1",
                        "last": "https://sandbox.nmbr.co/services/payroll/business_entities?page=1",
                        "prev": null,
                        "next": null
                    },
                    "meta": {
                        "current_page": 1,
                        "last_page": 1,
                        "per_page": 15,
                        "total": 1,
                        "has_more": false
                    }
                },
                "created_at": "2023-11-22T21:47:59.000000Z",
                "updated_at": "2023-11-22T21:47:59.000000Z"
            },
            "links": {
                "self": "https://sandbox.nmbr.co/services/payroll/companies/01hfwg25dbyebq330k8c8ammpm"
            }
        },
        // ...
        "created_at": "2023-11-22T21:48:01.000000Z",
        "updated_at": "2023-11-22T21:48:01.000000Z"
    },
    "links": {
        "self": "https://sandbox.nmbr.co/services/payroll/employees/01hfwg26zxk6bg8874nth78cgr"
    }
}
```

### Using the `expand` array

Multiple objects can be expanded by passing multiple values to the `expand` parameter.

Some objects have properties which are arrays of data - if there is an expandable property in such an array, you must pass the dot-property of the `array.property`. For example, to expand the `recurring_allowance` in a `allowance_line_item`, you must pass the parameter `expand[]=allowance.recurring_allowance`.

The `expand` parameter can also accept a comma separated list of expandable attributes: `expand=company,allowance.recurring_allowance`.

Request

```bash theme={null}
curl 'https://sandbox.nmbr.co/services/payroll/allowance_line_items/01hfym068emnp93zxz94822ec5?expand[]=allowance.recurring_allowance' \
--header 'Authorization: Bearer Llk5NQVFt9bu2auhJBuBxFGih22VecGq8qUeDD0Q7aa0c5bf'
```

Response

```json theme={null}
{
  "id": "01hfym068emnp93zxz94822ec5",
  "object": "allowance_line_item",
  "data": {
    "pay_stub": {
      "id": "01hfwg2784vc1408yhmjp4x81q",
      "object": "pay_stub",
      "links": {
        "self": "https://sandbox.nmbr.co/services/payroll/pay_stubs/01hfwg2784vc1408yhmjp4x81q"
      }
    },
    "line_item_type": "allowance",
    "amount": 10,
    "allowance": {
      "allowance_type": "automobile_and_motor_vehicle",
      "recurring_allowance": {
        "id": "01hfykqhej130bzjfryem64wjv",
        "object": "recurring_allowance",
        "data": {
          "employee": {
            "id": "01hfwg26zxk6bg8874nth78cgr",
            "object": "work_assignment",
            "links": {
              "self": "https://sandbox.nmbr.co/services/payroll/work_assignments/01hfwg26zxk6bg8874nth78cgr"
            }
          },
          "allowance_type": "automobile_and_motor_vehicle",
          "amount": 10,
          "effective_from": "2023-01-01T00:00:00.000000Z",
          "effective_to": null,
          "created_at": "2023-11-23T17:30:34.000000Z",
          "updated_at": "2023-11-23T17:30:34.000000Z"
        },
        "links": {
          "self": "https://sandbox.nmbr.co/services/payroll/allowances/01hfykqhej130bzjfryem64wjv"
        }
      }
    },
    "created_at": "2023-11-23T17:35:18.000000Z",
    "updated_at": "2023-11-23T17:35:18.000000Z"
  },
  "links": {
    "self": "https://sandbox.nmbr.co/services/payroll/allowance_line_items/01hfym068emnp93zxz94822ec5"
  }
}
```

### Maximum expansion depth

`expand` parameters using dot-properties for deep expanding may go up to **4 layers deep**. For example, the following is a valid `expand` argument on a `pay_stub`: `work_assignment.pay_rate.expense_accounting_code.business_entity`. However, no property on the `business_entity` may be expanded.

### Expanding optional properties

Some resources will have expandable properties that are not returned by default (i.e no "stub" entity will be returned by default). These optional properties will be documented as available, but must be requested in the `expand` argument to be returned.

The `expand` parameter can be used to reduce the total number of requests required to use the Nmbr API, however it should be used only when required, as there may be a noticeable performance difference when querying for a single entity with no `expand` argument, vs a query with multiple `expand` arguments - especially when expanding attributes in a list.

## Error Response Structure

When a client error (4xx) occurs, the Nmbr API returns a standardized error response.

### Bad Request (400)

A `400` status code indicates that the request was invalid.
The response message explains why the request could not be processed.

```json theme={null}
{
  "message": "The action is not allowed after a payroll has been run."
}
```

### Unauthorized (401)

A `401` status code indicates that authentication has failed.

```json theme={null}
{
  "message": "Unauthorized"
}
```

### Forbidden (403)

A `403` status code indicates that the client does not have permission to perform the requested action.

```json theme={null}
{
  "message": "Forbidden"
}
```

### Not Found (404)

A `404` status code indicates that the requested resource does not exist.

```json theme={null}
{
  "message": "Entity not found"
}
```

### Unprocessable Entity (422)

A `422` status code is returned when validation errors occur.
The response includes a summary message and an `errors` object detailing validation issues for each field.

```json theme={null}
{
  "message": "The selected province code is invalid. (and 2 more errors)",
  "errors": {
    "province_code": ["The selected province code is invalid."],
    "country_code": ["The selected country code is invalid."],
    "sin": ["Not a valid sin number. Must be a string in format ^[0-9]{9}$"]
  }
}
```
