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

# Create a request

> Create a leave request.

**Date/Time Format:** All dates must be in ISO 8601 format with UTC timezone (e.g., '2024-01-15T09:00:00Z').

**Day-based leave types (leave_unit: days):**
- Use start_at: 'morning' or 'afternoon' to specify when the absence starts
- Use end_at: 'lunchtime' or 'end_of_day' to specify when the absence ends
- Example full day: start='2024-01-15T00:00:00Z', end='2024-01-15T00:00:00Z', start_at='morning', end_at='end_of_day'
- Example half day (morning): start='2024-01-15T00:00:00Z', end='2024-01-15T00:00:00Z', start_at='morning', end_at='lunchtime'
- If start_at/end_at are omitted, they default to 'morning'/'end_of_day' (full day)
- For leave types with leave_unit 'days' (full days only), start_at='afternoon' or end_at='lunchtime' is rejected (each on its own) — use a 'half_days' leave type for half-day absences

**Hour-based leave types (leave_unit: hours):**
- Include the exact time in the start and end timestamps
- The start_at and end_at parameters are ignored
- Example: start='2024-01-15T09:00:00Z', end='2024-01-15T12:30:00Z' for a 9:00-12:30 UTC absence

**Representatives:** If the leave type or member requires representatives, pass representative_member_ids. Admin API keys creating for another member may instead set ignoreRepresentativeRequirement: true.

**Employment period:** The absence must fall entirely inside the member's employment period. A request starting before employment_start_date or ending after employment_end_date is rejected with 400. Both boundary dates are themselves bookable, and a null boundary means open ended on that side. A range that straddles a boundary is rejected rather than truncated.

The check compares **calendar days, not exact timestamps**. For an hour-based leave type, any time of day on employment_end_date is still inside the period (e.g. start='2024-09-30T09:00:00Z', end='2024-09-30T17:00:00Z' with employment_end_date '2024-09-30' is accepted) — midnight is not the cutoff. The same applies to employment_start_date.



## OpenAPI

````yaml https://api.absentify.com/api/v1/openapi.json post /requests
openapi: 3.1.0
info:
  title: absentify CRUD API
  description: OpenAPI compliant REST API
  version: 1.0.0
servers:
  - url: https://api.absentify.com/api/v1
security: []
tags:
  - name: Departments
  - name: Leave types
  - name: Members
  - name: Requests
  - name: Public holidays
  - name: Workspace
  - name: Absences
  - name: Allowance Management
externalDocs:
  url: https://absentify.com/docs/en/api-reference
paths:
  /requests:
    post:
      tags:
        - Requests
      summary: Create a request
      description: >-
        Create a leave request.


        **Date/Time Format:** All dates must be in ISO 8601 format with UTC
        timezone (e.g., '2024-01-15T09:00:00Z').


        **Day-based leave types (leave_unit: days):**

        - Use start_at: 'morning' or 'afternoon' to specify when the absence
        starts

        - Use end_at: 'lunchtime' or 'end_of_day' to specify when the absence
        ends

        - Example full day: start='2024-01-15T00:00:00Z',
        end='2024-01-15T00:00:00Z', start_at='morning', end_at='end_of_day'

        - Example half day (morning): start='2024-01-15T00:00:00Z',
        end='2024-01-15T00:00:00Z', start_at='morning', end_at='lunchtime'

        - If start_at/end_at are omitted, they default to 'morning'/'end_of_day'
        (full day)

        - For leave types with leave_unit 'days' (full days only),
        start_at='afternoon' or end_at='lunchtime' is rejected (each on its own)
        — use a 'half_days' leave type for half-day absences


        **Hour-based leave types (leave_unit: hours):**

        - Include the exact time in the start and end timestamps

        - The start_at and end_at parameters are ignored

        - Example: start='2024-01-15T09:00:00Z', end='2024-01-15T12:30:00Z' for
        a 9:00-12:30 UTC absence


        **Representatives:** If the leave type or member requires
        representatives, pass representative_member_ids. Admin API keys creating
        for another member may instead set ignoreRepresentativeRequirement:
        true.


        **Employment period:** The absence must fall entirely inside the
        member's employment period. A request starting before
        employment_start_date or ending after employment_end_date is rejected
        with 400. Both boundary dates are themselves bookable, and a null
        boundary means open ended on that side. A range that straddles a
        boundary is rejected rather than truncated.


        The check compares **calendar days, not exact timestamps**. For an
        hour-based leave type, any time of day on employment_end_date is still
        inside the period (e.g. start='2024-09-30T09:00:00Z',
        end='2024-09-30T17:00:00Z' with employment_end_date '2024-09-30' is
        accepted) — midnight is not the cutoff. The same applies to
        employment_start_date.
      operationId: request-createRequest
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                start:
                  description: >-
                    Start/end of the request in ISO 8601. For day-based leave
                    types (`leave_unit: days`) send the date at midnight UTC
                    (e.g. `2026-06-01T00:00:00Z`) and use `start_at` / `end_at`
                    to set half-days. For hour-based leave types include the
                    exact time of day (e.g. `2026-06-01T09:00:00Z`); `start_at`
                    / `end_at` are then ignored.
                  type: string
                end:
                  description: >-
                    Start/end of the request in ISO 8601. For day-based leave
                    types (`leave_unit: days`) send the date at midnight UTC
                    (e.g. `2026-06-01T00:00:00Z`) and use `start_at` / `end_at`
                    to set half-days. For hour-based leave types include the
                    exact time of day (e.g. `2026-06-01T09:00:00Z`); `start_at`
                    / `end_at` are then ignored.
                  type: string
                start_at:
                  type: string
                  enum:
                    - morning
                    - afternoon
                  description: >-
                    For day-based leave types: whether the absence starts in the
                    `morning` (the whole first day counts) or `afternoon` (only
                    the second half of the first day). Ignored for hour-based
                    leave types.
                end_at:
                  type: string
                  enum:
                    - lunchtime
                    - end_of_day
                  description: >-
                    For day-based leave types: whether the absence ends at
                    `lunchtime` (only the first half of the last day) or
                    `end_of_day` (the whole last day counts). Ignored for
                    hour-based leave types.
                leave_type_id:
                  type: string
                  format: uuid
                  pattern: >-
                    ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
                reason:
                  type: string
                requester_member_id:
                  type: string
                  format: uuid
                  pattern: >-
                    ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
                representative_member_ids:
                  description: >-
                    Member IDs to assign as representatives. Required for leave
                    types that mandate representatives — omitting them returns
                    REQUIRED_REPRESENTATIVES_COUNT_NOT_MET.
                  type: array
                  items:
                    type: string
                    format: uuid
                    pattern: >-
                      ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
                ignoreRepresentativeRequirement:
                  description: >-
                    Skip the representative requirement. Only honored when the
                    API key's member is an admin and the request is created for
                    another member.
                  type: boolean
              required:
                - start
                - end
                - leave_type_id
                - requester_member_id
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: string
                format: uuid
                pattern: >-
                  ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
        '400':
          description: Invalid input data
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error.BAD_REQUEST'
        '401':
          description: Authorization not provided
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error.UNAUTHORIZED'
        '403':
          description: Insufficient access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error.FORBIDDEN'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error.INTERNAL_SERVER_ERROR'
      security:
        - ApiKey: []
components:
  schemas:
    error.BAD_REQUEST:
      type: object
      properties:
        message:
          type: string
          description: The error message
          example: Invalid input data
        code:
          type: string
          description: The error code
          example: BAD_REQUEST
        issues:
          description: An array of issues that were responsible for the error
          example: []
          type: array
          items:
            type: object
            properties:
              message:
                type: string
            required:
              - message
            additionalProperties: false
      required:
        - message
        - code
      additionalProperties: false
      title: Invalid input data error (400)
      description: The error information
      example:
        code: BAD_REQUEST
        message: Invalid input data
        issues: []
    error.UNAUTHORIZED:
      type: object
      properties:
        message:
          type: string
          description: The error message
          example: Authorization not provided
        code:
          type: string
          description: The error code
          example: UNAUTHORIZED
        issues:
          description: An array of issues that were responsible for the error
          example: []
          type: array
          items:
            type: object
            properties:
              message:
                type: string
            required:
              - message
            additionalProperties: false
      required:
        - message
        - code
      additionalProperties: false
      title: Authorization not provided error (401)
      description: The error information
      example:
        code: UNAUTHORIZED
        message: Authorization not provided
        issues: []
    error.FORBIDDEN:
      type: object
      properties:
        message:
          type: string
          description: The error message
          example: Insufficient access
        code:
          type: string
          description: The error code
          example: FORBIDDEN
        issues:
          description: An array of issues that were responsible for the error
          example: []
          type: array
          items:
            type: object
            properties:
              message:
                type: string
            required:
              - message
            additionalProperties: false
      required:
        - message
        - code
      additionalProperties: false
      title: Insufficient access error (403)
      description: The error information
      example:
        code: FORBIDDEN
        message: Insufficient access
        issues: []
    error.INTERNAL_SERVER_ERROR:
      type: object
      properties:
        message:
          type: string
          description: The error message
          example: Internal server error
        code:
          type: string
          description: The error code
          example: INTERNAL_SERVER_ERROR
        issues:
          description: An array of issues that were responsible for the error
          example: []
          type: array
          items:
            type: object
            properties:
              message:
                type: string
            required:
              - message
            additionalProperties: false
      required:
        - message
        - code
      additionalProperties: false
      title: Internal server error error (500)
      description: The error information
      example:
        code: INTERNAL_SERVER_ERROR
        message: Internal server error
        issues: []
  securitySchemes:
    ApiKey:
      type: apiKey
      name: X-API-KEY
      in: header

````