Oyster HR

Global employment platform

docs.oysterhr.com/reference ↗
Version
v1
OpenAPI
3.0.1
Endpoints
17
Schemas
39
87
Quality
Updated
3 days ago
Hr hr global-employment remote-work
Use this API in your AI agent

Query structured spec data via REST or MCP. Get exactly what your agent needs.

Get API Key

Server URLs

https://api.oysterhr.com

Endpoints

Authentication 1 endpoints

POST /oauth2/token

Oyster grants access to API resources based on OAuth. This means that individual customers grant API access to Developer Apps that you create. This applies to both customers and partners. Follow these simple steps:

1. Create an Oyster account or log in to your existing account.

2. Create an Oyster Developer App in the Developer Tab (If you can’t see the developer tab please contact us to enable it for your account).
Hint: If you are a customer doing this as a one time action you don’t need to specify a functioning URL as step 3 will explain.

3. If you are a customer you can simply click on the “Authorization URL” and grant access to your own app. You will be redirected to the URL you specified when creating the Developer App. In the URL you will see that ?code=xxx has been added to the URL. This is the code you need to create an access token.
If you are a partner add “Authorization URL to your application. The redirect_url should be a URL that goes back to your app and you’re able to programmatically retrieve the URL query param of ?code=xxx to then create an access token.

4. You need to first request an authorization_code with the API request detailed below. This will provide an access_token that is used as the Bearer Token for making API requests to Oyster. Ensure that you store the refresh_token for making future API requests.

5. If your access_token has expired then request a new one using your refresh_token that you have stored earlier. Ensure you store the new refresh_token each time as the previous ones will expire.

operationId: Authentication_createAccessToken

Request Body

required
application/x-www-form-urlencoded
schema AuthenticationCreateAccessTokenRequest
Property Type Required
code string optional
client_id string optional
grant_type string optional
redirect_uri string optional
client_secret string optional
refresh_token string optional

Responses

201

Create an access token to make an API request

POST /oauth2/token

Company 1 endpoints

GET /v1/company

Returns details about the connected company

operationId: Company_detailsRetrieve

Responses

200

Successful

401

an invalid access token

GET /v1/company

Departments 1 endpoints

GET /v1/departments

Returns a list of departments

operationId: Departments_getAll

Parameters

Name In Required Type Description
per_page query optional integer
page query optional integer

Responses

200

Successful

401

an invalid access token

GET /v1/departments

Engagements 2 endpoints

GET /v1/engagements

Returns a list of engagements

operationId: Engagements_getAll

Parameters

Name In Required Type Description
per_page query optional integer
page query optional integer

Responses

200

Successful

401

an invalid access token

GET /v1/engagements
GET /v1/engagements/{id}

Returns details for an engagement with a given engagement ID.

operationId: Engagements_getById

Parameters

Name In Required Type Description
id path required string

Engagement ID

Responses

200

Successful

404

Resource does not exist, or no permission to access resource

GET /v1/engagements/{id}

Expenses 4 endpoints

POST /v1/expenses

Creates a new expense for an engagement. This is an asynchronous operation. Returns operationKey that can be used to retrieve the operation to know if it’s successfully completed

operationId: Expenses_createOperationKey

Request Body

application/json
schema ExpensesCreateOperationKeyRequest
Property Type Required
name string required
category string required
incurredOn string required
receiptUrl string required
description string optional
engagementId string required
receiptAmount object required
decimal string required
currencyCode string required

Responses

202

Successfully created async operation

400

improperly structured JSON

403

an invalid OAuth scope

422

Unprocessable entity

POST /v1/expenses
GET /v1/expenses/{id}

Returns details for an expense with a given expense ID.

operationId: Expenses_getById

Parameters

Name In Required Type Description
id path required string

Expense ID

Responses

200

Successful

404

Resource does not exist, or no permission to access resource

GET /v1/expenses/{id}
POST /v1/expenses/{id}/approve

Approves an expense.

operationId: Expenses_approveExpense

Parameters

Name In Required Type Description
id path required string

Expense ID

Responses

200

Successful

403

an invalid OAuth scope

404

Resource does not exist, or no permission to access resource

422

Operation cannot be performed

POST /v1/expenses/{id}/approve
POST /v1/expenses/{id}/decline

Declines an expense.

operationId: Expenses_declineExpense

Parameters

Name In Required Type Description
id path required string

Expense ID

Request Body

application/json
schema ExpensesDeclineExpenseRequest
Property Type Required
reason string optional

Responses

200

Successful

403

an invalid OAuth scope

404

Resource does not exist, or no permission to access resource

422

Operation cannot be performed

POST /v1/expenses/{id}/decline

Operations 1 endpoints

GET /v1/meta/operations/{operation_key}

Returns details for an operation with a given operation key.

operationId: Operations_getByOperationKey

Parameters

Name In Required Type Description
operation_key path required string

Operation key

Responses

200

Successful

404

Resource does not exist, or no permission to access resource

GET /v1/meta/operations/{operation_key}

Payroll 2 endpoints

GET /v1/payroll

Returns a list of payrolls

operationId: Payroll_getAllPayrolls

Parameters

Name In Required Type Description
per_page query optional integer
page query optional integer
from query optional string
to query optional string
include_records query optional boolean

Responses

200

Successful

401

an invalid access token

GET /v1/payroll
GET /v1/payroll/{id}

Returns details for a payroll with a given payroll ID.

operationId: Payroll_getById

Parameters

Name In Required Type Description
id path required string

Payroll ID

Responses

200

Successful

404

Resource does not exist, or no permission to access resource

GET /v1/payroll/{id}

Timeoff 5 endpoints

GET /v1/time_off/entitlements

Returns entitlements for each engagement of the company.

operationId: TimeOff_getEntitlements

Parameters

Name In Required Type Description
per_page query optional integer
page query optional integer

Responses

200

Successful

401

an invalid access token

GET /v1/time_off/entitlements
GET /v1/time_off/requests

Returns all Time Off Requests for a company.

operationId: TimeOff_getAllRequests

Parameters

Name In Required Type Description
per_page query optional integer
page query optional integer

Responses

200

Successful

401

an invalid access token

GET /v1/time_off/requests
GET /v1/time_off/requests/{id}

Returns details for a request.

operationId: TimeOff_getRequest

Parameters

Name In Required Type Description
id path required string

Time Off Request ID

Responses

200

Successful

401

an invalid access token

404

Resource does not exist, or no permission to access resource

GET /v1/time_off/requests/{id}
POST /v1/time_off/requests/{id}/approve

Approves a time off request.

operationId: TimeOff_approveRequest

Parameters

Name In Required Type Description
id path required string

Time Off Request ID

Responses

200

Successful

401

an invalid access token

403

an invalid OAuth scope

404

Resource does not exist, or no permission to access resource

422

Operation cannot be performed

POST /v1/time_off/requests/{id}/approve
POST /v1/time_off/requests/{id}/reject

Rejects a time off request.

operationId: TimeOff_rejectRequest

Parameters

Name In Required Type Description
id path required string

Time Off Request ID

Request Body

application/json
schema TimeOffRejectRequestRequest
Property Type Required
reason string required

Responses

200

Successful

401

an invalid access token

403

an invalid OAuth scope

404

Resource does not exist, or no permission to access resource

422

Operation cannot be performed

POST /v1/time_off/requests/{id}/reject

Schemas

object AuthenticationCreateAccessTokenRequest
{
  "type": "object",
  "properties": {
    "code": {
      "type": "string",
      "example": "1234ABCD",
      "description": "The code is required when requesting an `authorization_code`."
    },
    "client_id": {
      "type": "string",
      "example": "1234ABCD",
      "description": "The client_id of your Developer App. This can be found by visting https://app.oysterhr.com/developer"
    },
    "grant_type": {
      "type": "string",
      "example": "authorization_code",
      "description": "First you need to request an `authorization_code`. Afterwards you can request a `refresh_token`."
    },
    "redirect_uri": {
      "type": "string",
      "example": "https://example.com/inbound",
      "description": "The redirect_uri is required when requesting an `authorization_code`."
    },
    "client_secret": {
      "type": "string",
      "example": "1234ABCD",
      "description": "The secret of your Developer App."
    },
    "refresh_token": {
      "type": "string",
      "example": "https://example.com/inbound",
      "description": "A `refresh_token` is required when requesting a `refresh_token`. A `refresh_token` will be provided when requesting an `authorization_code`"
    }
  }
}
object CompanyDetailsRetrieveResponse
{
  "type": "object",
  "required": [
    "data"
  ],
  "properties": {
    "data": {
      "$ref": "#/components/schemas/company"
    }
  }
}
object DepartmentsGetAllResponse
{
  "type": "object",
  "required": [
    "data",
    "meta"
  ],
  "properties": {
    "data": {
      "$ref": "#/components/schemas/departments"
    },
    "meta": {
      "$ref": "#/components/schemas/meta"
    }
  }
}
object EngagementsGetAllResponse
{
  "type": "object",
  "required": [
    "data",
    "meta"
  ],
  "properties": {
    "data": {
      "$ref": "#/components/schemas/engagements"
    },
    "meta": {
      "$ref": "#/components/schemas/meta"
    }
  }
}
object EngagementsGetByIdResponse
{
  "type": "object",
  "required": [
    "data"
  ],
  "properties": {
    "data": {
      "$ref": "#/components/schemas/engagement"
    }
  }
}
object ExpensesCreateOperationKeyRequest
{
  "type": "object",
  "required": [
    "engagementId",
    "name",
    "incurredOn",
    "category",
    "receiptUrl",
    "receiptAmount"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "category": {
      "type": "string",
      "minLength": 1
    },
    "incurredOn": {
      "type": "string",
      "format": "date",
      "minLength": 1
    },
    "receiptUrl": {
      "type": "string",
      "minLength": 1
    },
    "description": {
      "type": "string"
    },
    "engagementId": {
      "type": "string",
      "minLength": 1
    },
    "receiptAmount": {
      "type": "object",
      "required": [
        "decimal",
        "currencyCode"
      ],
      "properties": {
        "decimal": {
          "type": "string",
          "minLength": 1
        },
        "currencyCode": {
          "type": "string",
          "minLength": 1
        }
      }
    }
  }
}
object ExpensesDeclineExpenseRequest
{
  "type": "object",
  "properties": {
    "reason": {
      "type": "string"
    }
  }
}
object ExpensesGetByIdResponse
{
  "type": "object",
  "required": [
    "data"
  ],
  "properties": {
    "data": {
      "$ref": "#/components/schemas/expense"
    }
  }
}
object OperationsGetByOperationKeyResponse
{
  "type": "object",
  "required": [
    "data"
  ],
  "properties": {
    "data": {
      "$ref": "#/components/schemas/operation"
    }
  }
}
object PayrollGetAllPayrollsResponse
{
  "type": "object",
  "required": [
    "data",
    "meta"
  ],
  "properties": {
    "data": {
      "$ref": "#/components/schemas/payrolls"
    },
    "meta": {
      "$ref": "#/components/schemas/meta"
    }
  }
}
object PayrollGetByIdResponse
{
  "type": "object",
  "required": [
    "data"
  ],
  "properties": {
    "data": {
      "$ref": "#/components/schemas/payroll"
    }
  }
}
object TimeOffGetAllRequestsResponse
{
  "type": "object",
  "required": [
    "data",
    "meta"
  ],
  "properties": {
    "data": {
      "$ref": "#/components/schemas/timeOffRequests"
    },
    "meta": {
      "$ref": "#/components/schemas/meta"
    }
  }
}
object TimeOffGetEntitlementsResponse
{
  "type": "object",
  "required": [
    "data",
    "meta"
  ],
  "properties": {
    "data": {
      "$ref": "#/components/schemas/timeOffEntitlements"
    },
    "meta": {
      "$ref": "#/components/schemas/meta"
    }
  }
}
object TimeOffGetRequestResponse
{
  "type": "object",
  "required": [
    "data"
  ],
  "properties": {
    "data": {
      "$ref": "#/components/schemas/timeOffRequest"
    }
  }
}
object TimeOffRejectRequestRequest
{
  "type": "object",
  "required": [
    "reason"
  ],
  "properties": {
    "reason": {
      "type": "string"
    }
  }
}
object Token
{
  "type": "object",
  "properties": {
    "scope": {
      "type": "string",
      "example": "read"
    },
    "created_at": {
      "type": "number",
      "example": 167474949830
    },
    "expires_in": {
      "type": "number",
      "example": 7200
    },
    "token_type": {
      "type": "string",
      "example": "Bearer"
    },
    "access_token": {
      "type": "string",
      "example": "1234ABCD"
    },
    "refresh_token": {
      "type": "string",
      "example": "1234ABCD"
    }
  }
}
object address
{
  "type": "object",
  "required": [
    "addressId",
    "addressLine1",
    "postalCode"
  ],
  "properties": {
    "city": {
      "type": "string",
      "nullable": true
    },
    "region": {
      "type": "string",
      "nullable": true
    },
    "addressId": {
      "type": "string"
    },
    "postalCode": {
      "type": "string",
      "nullable": true
    },
    "countryCode": {
      "type": "string",
      "nullable": true
    },
    "addressLine1": {
      "type": "string",
      "nullable": true
    },
    "addressLine2": {
      "type": "string",
      "nullable": true
    }
  }
}
object amount
{
  "type": "object",
  "required": [
    "decimal",
    "currencyCode"
  ],
  "properties": {
    "decimal": {
      "type": "string",
      "pattern": "^\\d+([.]\\d+)?$"
    },
    "currencyCode": {
      "type": "string",
      "maxLength": 3,
      "minLength": 3
    }
  }
}
object asyncResponse
{
  "type": "object",
  "properties": {
    "meta": {
      "type": "object",
      "properties": {
        "operationKey": {
          "type": "string"
        }
      }
    }
  }
}
object company
{
  "type": "object",
  "required": [
    "companyId",
    "name",
    "registrationNumber",
    "addresses"
  ],
  "properties": {
    "name": {
      "type": "string"
    },
    "addresses": {
      "type": "object",
      "properties": {
        "billingAddress": {
          "$ref": "#/components/schemas/address",
          "type": "object",
          "nullable": true
        },
        "corporateAddress": {
          "$ref": "#/components/schemas/address",
          "type": "object",
          "nullable": true
        }
      }
    },
    "companyId": {
      "type": "string"
    },
    "registrationNumber": {
      "type": "string"
    }
  }
}
object department
{
  "type": "object",
  "required": [
    "departmentId",
    "name",
    "description",
    "engagementsCount"
  ],
  "properties": {
    "name": {
      "type": "string"
    },
    "description": {
      "type": "string",
      "nullable": true
    },
    "departmentId": {
      "type": "string"
    },
    "engagementsCount": {
      "type": "integer"
    }
  }
}
array departments
{
  "type": "array",
  "items": {
    "$ref": "#/components/schemas/department"
  }
}
object engagement
{
  "type": "object",
  "required": [
    "engagementId",
    "engagementType",
    "personalDetails",
    "startDate",
    "countryCode",
    "role"
  ],
  "properties": {
    "role": {
      "type": "string"
    },
    "state": {
      "type": "string"
    },
    "contract": {
      "type": "object",
      "nullable": true
    },
    "startDate": {
      "type": "string",
      "format": "date"
    },
    "department": {
      "type": "object",
      "nullable": true,
      "properties": {
        "name": {
          "type": "string"
        },
        "description": {
          "type": "string"
        },
        "departmentId": {
          "type": "string"
        }
      }
    },
    "employment": {
      "type": "object",
      "nullable": true
    },
    "modifiedAt": {
      "type": "string",
      "format": "date-time"
    },
    "countryCode": {
      "type": "string"
    },
    "engagementId": {
      "type": "string"
    },
    "terminations": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "state": {
            "type": "string"
          },
          "proposedDate": {
            "type": "string",
            "format": "date"
          }
        }
      }
    },
    "engagementType": {
      "enum": [
        "EMPLOYMENT",
        "CONTRACT"
      ],
      "type": "string"
    },
    "personalDetails": {
      "type": "object",
      "required": [
        "name",
        "addresses"
      ],
      "properties": {
        "name": {
          "type": "string",
          "nullable": true
        },
        "addresses": {
          "type": "object",
          "properties": {
            "livingAddress": {
              "$ref": "#/components/schemas/address",
              "type": "object",
              "nullable": true
            },
            "mailingAddress": {
              "$ref": "#/components/schemas/address",
              "type": "object",
              "nullable": true
            }
          }
        },
        "dateOfBirth": {
          "type": "string",
          "nullable": true
        },
        "citizenships": {
          "type": "array",
          "items": {
            "type": "string",
            "nullable": true
          }
        },
        "phoneNumbers": {
          "type": "object",
          "properties": {
            "default": {
              "$ref": "#/components/schemas/phoneNumber",
              "type": "object",
              "nullable": true
            },
            "emergency": {
              "$ref": "#/components/schemas/phoneNumber",
              "type": "object",
              "nullable": true
            }
          }
        }
      }
    },
    "benefitEnrollments": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "plan": {
            "type": "object",
            "properties": {
              "provider": {
                "type": "string"
              },
              "descriptiveName": {
                "type": "string"
              }
            }
          },
          "state": {
            "type": "string"
          },
          "benefitEnrollmentId": {
            "type": "string"
          }
        }
      }
    }
  }
}
array engagements
{
  "type": "array",
  "items": {
    "$ref": "#/components/schemas/engagement"
  }
}
object error
{
  "type": "object",
  "properties": {
    "error": {
      "type": "object",
      "properties": {
        "message": {
          "type": "string"
        }
      }
    }
  }
}
object errors
{
  "type": "object",
  "properties": {
    "errors": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          }
        }
      }
    }
  }
}
object expense
{
  "type": "object",
  "required": [
    "expenseId",
    "name",
    "amount",
    "category",
    "receiptAmount"
  ],
  "properties": {
    "name": {
      "type": "string"
    },
    "amount": {
      "$ref": "#/components/schemas/amount",
      "type": "object"
    },
    "source": {
      "type": "string"
    },
    "category": {
      "type": "string",
      "pattern": "^[A-Z_]+$"
    },
    "expenseId": {
      "type": "string"
    },
    "engagement": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "nullable": true
        },
        "engagementId": {
          "type": "string"
        },
        "engagementType": {
          "type": "string",
          "pattern": "^[A-Z_]+$"
        }
      }
    },
    "incurredOn": {
      "type": "string",
      "format": "date"
    },
    "receiptUrl": {
      "type": "string",
      "format": "uri",
      "nullable": true
    },
    "reviewedAt": {
      "type": "string",
      "format": "date-time",
      "nullable": true
    },
    "description": {
      "type": "string",
      "nullable": true
    },
    "reviewState": {
      "type": "string"
    },
    "submittedAt": {
      "type": "string",
      "format": "date-time"
    },
    "receiptAmount": {
      "$ref": "#/components/schemas/amount",
      "type": "object"
    }
  }
}
array expenses
{
  "type": "array",
  "items": {
    "$ref": "#/components/schemas/expense"
  }
}
object fieldErrors
{
  "type": "object",
  "properties": {
    "errors": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  }
}
object meta
{
  "type": "object",
  "properties": {
    "page": {
      "type": "integer"
    },
    "count": {
      "type": "integer"
    },
    "items": {
      "type": "integer"
    },
    "pages": {
      "type": "integer"
    },
    "lastUrl": {
      "type": "string"
    },
    "nextUrl": {
      "type": "string"
    },
    "pageUrl": {
      "type": "string"
    },
    "prevUrl": {
      "type": "string"
    },
    "firstUrl": {
      "type": "string"
    }
  }
}
object operation
{
  "type": "object",
  "properties": {
    "data": {
      "type": "object"
    },
    "meta": {
      "type": "object",
      "properties": {
        "success": {
          "type": "boolean"
        },
        "completed": {
          "type": "boolean"
        }
      }
    },
    "request": {
      "type": "object",
      "properties": {
        "path": {
          "type": "string"
        },
        "method": {
          "type": "string"
        },
        "queryParams": {
          "type": "object"
        },
        "responseCode": {
          "type": "integer"
        }
      }
    }
  }
}
object payroll
{
  "type": "object",
  "required": [
    "payrollId",
    "currencyCode",
    "cutoffTimeForPayroll",
    "state",
    "payrollRecordsCount"
  ],
  "properties": {
    "state": {
      "type": "string"
    },
    "records": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/payrollRecord"
      }
    },
    "payrollId": {
      "type": "string"
    },
    "currencyCode": {
      "type": "string"
    },
    "payrollRecordsCount": {
      "type": "integer"
    },
    "cutoffTimeForPayroll": {
      "type": "string",
      "format": "date-time",
      "nullable": true
    }
  }
}
object payrollRecord
{
  "type": "object",
  "required": [
    "engagementId",
    "currencyCode",
    "monthlyPaymentsTotalAmount",
    "allowancesTotalAmount",
    "benefitsTotalAmount",
    "bonusesTotalAmount",
    "addOnsTotalAmount",
    "taxesTotalAmount",
    "trueUpsTotalAmount",
    "oysterFeesTotalAmount",
    "engagement"
  ],
  "properties": {
    "engagement": {
      "type": "object",
      "required": [
        "name",
        "cutoffMonthDay",
        "engagementType"
      ],
      "properties": {
        "name": {
          "type": "string"
        },
        "cutoffMonthDay": {
          "type": "integer"
        },
        "engagementType": {
          "type": "string"
        }
      }
    },
    "currencyCode": {
      "type": "string"
    },
    "engagementId": {
      "type": "string"
    },
    "taxesTotalAmount": {
      "$ref": "#/components/schemas/amount"
    },
    "addOnsTotalAmount": {
      "$ref": "#/components/schemas/amount"
    },
    "bonusesTotalAmount": {
      "$ref": "#/components/schemas/amount"
    },
    "trueUpsTotalAmount": {
      "$ref": "#/components/schemas/amount"
    },
    "benefitsTotalAmount": {
      "$ref": "#/components/schemas/amount"
    },
    "allowancesTotalAmount": {
      "$ref": "#/components/schemas/amount"
    },
    "oysterFeesTotalAmount": {
      "$ref": "#/components/schemas/amount"
    },
    "monthlyPaymentsTotalAmount": {
      "$ref": "#/components/schemas/amount"
    }
  }
}
array payrolls
{
  "type": "array",
  "items": {
    "$ref": "#/components/schemas/payroll"
  }
}
object phoneNumber
{
  "type": "object",
  "required": [
    "number"
  ],
  "properties": {
    "number": {
      "type": "string"
    },
    "countryCode": {
      "type": "string",
      "nullable": true
    }
  }
}
object timeOffEngagementDetails
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "type": {
      "type": "string",
      "pattern": "^[A-Z_]+$"
    },
    "countryCode": {
      "type": "string"
    },
    "engagementId": {
      "type": "string"
    }
  }
}
array timeOffEntitlements
{
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "taken": {
        "type": "number",
        "format": "float"
      },
      "units": {
        "enum": [
          "DAYS"
        ],
        "type": "string"
      },
      "accrued": {
        "type": "number",
        "format": "float"
      },
      "carried": {
        "type": "number",
        "format": "float"
      },
      "upcoming": {
        "type": "number",
        "format": "float"
      },
      "engagement": {
        "$ref": "#/components/schemas/timeOffEngagementDetails"
      },
      "adjustedAdhoc": {
        "type": "number",
        "format": "float"
      },
      "availableBalance": {
        "type": "number",
        "format": "float"
      },
      "projectedBalance": {
        "type": "number",
        "format": "float"
      },
      "annualEntitlement": {
        "type": "number",
        "format": "float"
      }
    }
  }
}
object timeOffRequest
{
  "type": "object",
  "properties": {
    "type": {
      "type": "string",
      "pattern": "^[A-Z_]+$"
    },
    "state": {
      "type": "string",
      "pattern": "^[A-Z_]+$"
    },
    "reason": {
      "type": "string",
      "pattern": "^[A-Z_]+$"
    },
    "endDate": {
      "type": "string",
      "format": "date"
    },
    "startDate": {
      "type": "string",
      "format": "date"
    },
    "engagement": {
      "$ref": "#/components/schemas/timeOffEngagementDetails"
    },
    "periodInHours": {
      "type": "number",
      "format": "float"
    },
    "lastDayDuration": {
      "type": "string",
      "pattern": "^[A-Z_]+$",
      "nullable": true
    },
    "rejectionReason": {
      "type": "string",
      "nullable": true
    },
    "firstDayDuration": {
      "type": "string",
      "pattern": "^[A-Z_]+$"
    },
    "timeOffRequestId": {
      "type": "string"
    },
    "requesterComments": {
      "type": "string",
      "nullable": true
    }
  }
}
array timeOffRequests
{
  "type": "array",
  "items": {
    "$ref": "#/components/schemas/timeOffRequest"
  }
}