{
  "openapi": "3.1.0",
  "info": {
    "title": "LekhaHR API",
    "version": "v1",
    "summary": "Read people, attendance, leave and pay run totals, add people and device punches, and receive webhooks.",
    "description": "Keys are made in LekhaHR under Settings › API keys and webhooks, checked by a second admin and shown once. Call the API from a server only: it sends no browser (CORS) headers. Field types, limits and examples here are generated from the schemas the API itself answers with."
  },
  "servers": [
    {
      "url": "https://api.lekhahr.in",
      "description": "Production (keys start lkh_live_)"
    },
    {
      "url": "https://api.dev.lekhahr.in",
      "description": "Staging (keys start lkh_test_)"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "tags": [
    {
      "name": "Company"
    },
    {
      "name": "List people"
    },
    {
      "name": "One person"
    },
    {
      "name": "Add a person"
    },
    {
      "name": "Departments and locations"
    },
    {
      "name": "Attendance days"
    },
    {
      "name": "Send punches"
    },
    {
      "name": "Leave requests"
    },
    {
      "name": "Leave balances"
    },
    {
      "name": "Leave types"
    },
    {
      "name": "Pay runs"
    },
    {
      "name": "Payslip summaries"
    }
  ],
  "paths": {
    "/v1/company": {
      "get": {
        "operationId": "getCompany",
        "summary": "Company",
        "description": "The key's own company and the key's facts. Any working key may call it; use it to check a new key.\n\nNever the key owner's name or email, and never another key.\n\nAny working key.",
        "tags": [
          "Company"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "x-lekhahr-scope": null,
        "responses": {
          "200": {
            "description": "The company and the key.",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Company"
                },
                "example": {
                  "company": {
                    "id": "6a3d9c1e-2f4b-4e8a-9d7c-1b2a3c4d5e6f",
                    "name": "Example Technologies",
                    "timezone": "Asia/Kolkata"
                  },
                  "key": {
                    "id": "7QD2HX4MRT0B",
                    "name": "Staff directory",
                    "scopes": [
                      "people.read"
                    ],
                    "coverage": {
                      "kind": "company"
                    },
                    "expires_on": "2027-01-31"
                  }
                }
              }
            }
          },
          "400": {
            "description": "malformed",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "malformed": {
                    "value": {
                      "error": {
                        "code": "malformed",
                        "message": "The request is not in a form this endpoint accepts.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_key",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "WWW-Authenticate": {
                "schema": {
                  "type": "string",
                  "example": "Bearer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_key": {
                    "value": {
                      "error": {
                        "code": "invalid_key",
                        "message": "The API key is missing, not valid, revoked or expired.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "ip_not_allowed, plan_required, key_paused",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "ip_not_allowed": {
                    "value": {
                      "error": {
                        "code": "ip_not_allowed",
                        "message": "This key cannot be used from this address.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "plan_required": {
                    "value": {
                      "error": {
                        "code": "plan_required",
                        "message": "The API needs the Business plan.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "key_paused": {
                    "value": {
                      "error": {
                        "code": "key_paused",
                        "message": "This key is paused. Someone with access must take it over in Settings.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate_limited",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "value": {
                      "error": {
                        "code": "rate_limited",
                        "message": "Too many requests. Try again in a minute.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "server_error",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "server_error": {
                    "value": {
                      "error": {
                        "code": "server_error",
                        "message": "Something went wrong on our side. Quote the request id if you contact support.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/people": {
      "get": {
        "operationId": "listPeople",
        "summary": "List people",
        "description": "People inside the key's coverage, ordered by id.\n\nFilter by status, department or office, or by updated_since for a nightly sync. No email, phone or identity number is returned.\n\nNeeds the people.read scope.",
        "tags": [
          "List people"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "x-lekhahr-scope": "people.read",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "active (the default), onboarding, on_notice, exited or all",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "onboarding",
                "on_notice",
                "exited",
                "all"
              ],
              "default": "active"
            }
          },
          {
            "name": "department_id",
            "in": "query",
            "required": false,
            "description": "Only this department",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "location_id",
            "in": "query",
            "required": false,
            "description": "Only this office",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "updated_since",
            "in": "query",
            "required": false,
            "description": "Changed at or after this time, for a nightly sync",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1 to 200",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "next_cursor of the last page; lasts 24 hours",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 512
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of people.",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PersonList"
                },
                "example": {
                  "data": [
                    {
                      "id": "7c1e5a2b-9d3f-4c6e-8a1b-2c3d4e5f6a7b",
                      "employee_code": "EX-0042",
                      "full_name": "Sample Person",
                      "designation": "Engineer",
                      "department": {
                        "id": "2b4f6a8c-1d3e-4f50-8a6b-7c8d9e0f1a2b",
                        "name": "Engineering"
                      },
                      "location": {
                        "id": "9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b",
                        "name": "Bengaluru"
                      },
                      "manager_id": "3f0a1b2c-4d5e-4f6a-9b7c-8d9e0f1a2b3c",
                      "status": "active",
                      "date_of_joining": "2025-06-02",
                      "last_working_day": null,
                      "updated_at": "2026-11-03T05:10:00Z"
                    }
                  ],
                  "next_cursor": "eyJ2IjoxLCJrIjoiN1FEMkhYNE1SVDBCIn0.c_9QmTx2"
                }
              }
            }
          },
          "400": {
            "description": "malformed",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "malformed": {
                    "value": {
                      "error": {
                        "code": "malformed",
                        "message": "The request is not in a form this endpoint accepts.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_key",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "WWW-Authenticate": {
                "schema": {
                  "type": "string",
                  "example": "Bearer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_key": {
                    "value": {
                      "error": {
                        "code": "invalid_key",
                        "message": "The API key is missing, not valid, revoked or expired.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "scope_missing, ip_not_allowed, plan_required, key_paused",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "scope_missing": {
                    "value": {
                      "error": {
                        "code": "scope_missing",
                        "message": "This key does not have the scope this endpoint needs.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "ip_not_allowed": {
                    "value": {
                      "error": {
                        "code": "ip_not_allowed",
                        "message": "This key cannot be used from this address.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "plan_required": {
                    "value": {
                      "error": {
                        "code": "plan_required",
                        "message": "The API needs the Business plan.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "key_paused": {
                    "value": {
                      "error": {
                        "code": "key_paused",
                        "message": "This key is paused. Someone with access must take it over in Settings.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "410": {
            "description": "cursor_expired",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "cursor_expired": {
                    "value": {
                      "error": {
                        "code": "cursor_expired",
                        "message": "This cursor has expired. Start the list again.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate_limited",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "value": {
                      "error": {
                        "code": "rate_limited",
                        "message": "Too many requests. Try again in a minute.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "server_error",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "server_error": {
                    "value": {
                      "error": {
                        "code": "server_error",
                        "message": "Something went wrong on our side. Quote the request id if you contact support.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "addPerson",
        "summary": "Add a person",
        "description": "Adds one person, as Add people does in the app. Needs a whole-company key.\n\nBefore the date of joining the person is onboarding; from it, active. The code is the next free one unless you send one.\n\nNever sends an invite, and never sets pay, bank details, identity numbers or a role.\n\nA 422 names each field with a code: name_required, name_length, email_invalid, email_taken, contact_required, phone_invalid, department_not_found, location_not_found, manager_not_found, code_invalid, code_taken, or head_office_missing on company.\n\nNeeds the people.write scope on a whole-company key.",
        "tags": [
          "Add a person"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "x-lekhahr-scope": "people.write",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "1 to 64 letters, digits, - or _. Kept 24 hours.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PersonCreate"
              },
              "example": {
                "full_name": "Sample Person",
                "work_email": "sample.person@example.com",
                "date_of_joining": "2026-11-16",
                "department_id": "2b4f6a8c-1d3e-4f50-8a6b-7c8d9e0f1a2b",
                "location_id": "9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b",
                "designation": "Engineer",
                "manager_id": "3f0a1b2c-4d5e-4f6a-9b7c-8d9e0f1a2b3c"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The person, as GET /v1/people/{id} reads them.",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "30;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "Idempotent-Replayed": {
                "description": "true when this is the stored answer to an earlier request with the same Idempotency-Key.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Person"
                },
                "example": {
                  "id": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
                  "employee_code": "EX-0043",
                  "full_name": "Sample Person",
                  "designation": "Engineer",
                  "department": {
                    "id": "2b4f6a8c-1d3e-4f50-8a6b-7c8d9e0f1a2b",
                    "name": "Engineering"
                  },
                  "location": {
                    "id": "9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b",
                    "name": "Bengaluru"
                  },
                  "manager_id": "3f0a1b2c-4d5e-4f6a-9b7c-8d9e0f1a2b3c",
                  "status": "onboarding",
                  "date_of_joining": "2026-11-16",
                  "last_working_day": null,
                  "updated_at": "2026-11-04T06:30:00Z"
                }
              }
            }
          },
          "400": {
            "description": "malformed",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "30;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "malformed": {
                    "value": {
                      "error": {
                        "code": "malformed",
                        "message": "The request is not in a form this endpoint accepts.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_key",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "30;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "WWW-Authenticate": {
                "schema": {
                  "type": "string",
                  "example": "Bearer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_key": {
                    "value": {
                      "error": {
                        "code": "invalid_key",
                        "message": "The API key is missing, not valid, revoked or expired.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "scope_missing, ip_not_allowed, plan_required, key_paused, plan_read_only",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "30;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "scope_missing": {
                    "value": {
                      "error": {
                        "code": "scope_missing",
                        "message": "This key does not have the scope this endpoint needs.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "ip_not_allowed": {
                    "value": {
                      "error": {
                        "code": "ip_not_allowed",
                        "message": "This key cannot be used from this address.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "plan_required": {
                    "value": {
                      "error": {
                        "code": "plan_required",
                        "message": "The API needs the Business plan.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "key_paused": {
                    "value": {
                      "error": {
                        "code": "key_paused",
                        "message": "This key is paused. Someone with access must take it over in Settings.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "plan_read_only": {
                    "value": {
                      "error": {
                        "code": "plan_read_only",
                        "message": "The company's plan allows reads only.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "30;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "not_found": {
                    "value": {
                      "error": {
                        "code": "not_found",
                        "message": "Not found.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "request_in_progress",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "30;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "request_in_progress": {
                    "value": {
                      "error": {
                        "code": "request_in_progress",
                        "message": "A request with this idempotency key is still running.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "validation_failed, idempotency_key_reused",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "30;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_failed": {
                    "value": {
                      "error": {
                        "code": "validation_failed",
                        "message": "Some fields are not valid.",
                        "request_id": "4e5b6a7c",
                        "fields": [
                          {
                            "field": "work_email",
                            "code": "email_taken"
                          }
                        ]
                      }
                    }
                  },
                  "idempotency_key_reused": {
                    "value": {
                      "error": {
                        "code": "idempotency_key_reused",
                        "message": "This idempotency key was used for a different request.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate_limited",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "30;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "value": {
                      "error": {
                        "code": "rate_limited",
                        "message": "Too many requests. Try again in a minute.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "server_error",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "30;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "server_error": {
                    "value": {
                      "error": {
                        "code": "server_error",
                        "message": "Something went wrong on our side. Quote the request id if you contact support.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/people/{id}": {
      "get": {
        "operationId": "getPerson",
        "summary": "One person",
        "description": "One person, with the same fields as the list.\n\nSomeone outside the key's coverage answers 404, the same as an id that does not exist.\n\nNeeds the people.read scope.",
        "tags": [
          "One person"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "x-lekhahr-scope": "people.read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The person's id",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The person.",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Person"
                },
                "example": {
                  "id": "7c1e5a2b-9d3f-4c6e-8a1b-2c3d4e5f6a7b",
                  "employee_code": "EX-0042",
                  "full_name": "Sample Person",
                  "designation": "Engineer",
                  "department": {
                    "id": "2b4f6a8c-1d3e-4f50-8a6b-7c8d9e0f1a2b",
                    "name": "Engineering"
                  },
                  "location": {
                    "id": "9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b",
                    "name": "Bengaluru"
                  },
                  "manager_id": "3f0a1b2c-4d5e-4f6a-9b7c-8d9e0f1a2b3c",
                  "status": "active",
                  "date_of_joining": "2025-06-02",
                  "last_working_day": null,
                  "updated_at": "2026-11-03T05:10:00Z"
                }
              }
            }
          },
          "400": {
            "description": "malformed",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "malformed": {
                    "value": {
                      "error": {
                        "code": "malformed",
                        "message": "The request is not in a form this endpoint accepts.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_key",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "WWW-Authenticate": {
                "schema": {
                  "type": "string",
                  "example": "Bearer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_key": {
                    "value": {
                      "error": {
                        "code": "invalid_key",
                        "message": "The API key is missing, not valid, revoked or expired.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "scope_missing, ip_not_allowed, plan_required, key_paused",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "scope_missing": {
                    "value": {
                      "error": {
                        "code": "scope_missing",
                        "message": "This key does not have the scope this endpoint needs.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "ip_not_allowed": {
                    "value": {
                      "error": {
                        "code": "ip_not_allowed",
                        "message": "This key cannot be used from this address.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "plan_required": {
                    "value": {
                      "error": {
                        "code": "plan_required",
                        "message": "The API needs the Business plan.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "key_paused": {
                    "value": {
                      "error": {
                        "code": "key_paused",
                        "message": "This key is paused. Someone with access must take it over in Settings.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "not_found": {
                    "value": {
                      "error": {
                        "code": "not_found",
                        "message": "Not found.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate_limited",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "value": {
                      "error": {
                        "code": "rate_limited",
                        "message": "Too many requests. Try again in a minute.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "server_error",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "server_error": {
                    "value": {
                      "error": {
                        "code": "server_error",
                        "message": "Something went wrong on our side. Quote the request id if you contact support.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/departments": {
      "get": {
        "operationId": "listDepartments",
        "summary": "Departments",
        "description": "Every department of the company, by name.\n\nNot filtered by the key's coverage: names only.\n\nNeeds the people.read scope.",
        "tags": [
          "Departments and locations"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "x-lekhahr-scope": "people.read",
        "responses": {
          "200": {
            "description": "The departments.",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReferenceList"
                },
                "example": {
                  "data": [
                    {
                      "id": "2b4f6a8c-1d3e-4f50-8a6b-7c8d9e0f1a2b",
                      "name": "Engineering",
                      "active": true
                    },
                    {
                      "id": "5d7e9f1a-3b4c-4d6e-8f0a-1b2c3d4e5f6a",
                      "name": "Sales",
                      "active": true
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "malformed",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "malformed": {
                    "value": {
                      "error": {
                        "code": "malformed",
                        "message": "The request is not in a form this endpoint accepts.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_key",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "WWW-Authenticate": {
                "schema": {
                  "type": "string",
                  "example": "Bearer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_key": {
                    "value": {
                      "error": {
                        "code": "invalid_key",
                        "message": "The API key is missing, not valid, revoked or expired.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "scope_missing, ip_not_allowed, plan_required, key_paused",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "scope_missing": {
                    "value": {
                      "error": {
                        "code": "scope_missing",
                        "message": "This key does not have the scope this endpoint needs.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "ip_not_allowed": {
                    "value": {
                      "error": {
                        "code": "ip_not_allowed",
                        "message": "This key cannot be used from this address.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "plan_required": {
                    "value": {
                      "error": {
                        "code": "plan_required",
                        "message": "The API needs the Business plan.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "key_paused": {
                    "value": {
                      "error": {
                        "code": "key_paused",
                        "message": "This key is paused. Someone with access must take it over in Settings.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate_limited",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "value": {
                      "error": {
                        "code": "rate_limited",
                        "message": "Too many requests. Try again in a minute.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "server_error",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "server_error": {
                    "value": {
                      "error": {
                        "code": "server_error",
                        "message": "Something went wrong on our side. Quote the request id if you contact support.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/locations": {
      "get": {
        "operationId": "listLocations",
        "summary": "Locations",
        "description": "Every office of the company, by name.\n\nNot filtered by the key's coverage: names only.\n\nNeeds the people.read scope.",
        "tags": [
          "Departments and locations"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "x-lekhahr-scope": "people.read",
        "responses": {
          "200": {
            "description": "The offices.",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReferenceList"
                },
                "example": {
                  "data": [
                    {
                      "id": "9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b",
                      "name": "Bengaluru",
                      "active": true
                    },
                    {
                      "id": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                      "name": "Pune",
                      "active": true
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "malformed",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "malformed": {
                    "value": {
                      "error": {
                        "code": "malformed",
                        "message": "The request is not in a form this endpoint accepts.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_key",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "WWW-Authenticate": {
                "schema": {
                  "type": "string",
                  "example": "Bearer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_key": {
                    "value": {
                      "error": {
                        "code": "invalid_key",
                        "message": "The API key is missing, not valid, revoked or expired.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "scope_missing, ip_not_allowed, plan_required, key_paused",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "scope_missing": {
                    "value": {
                      "error": {
                        "code": "scope_missing",
                        "message": "This key does not have the scope this endpoint needs.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "ip_not_allowed": {
                    "value": {
                      "error": {
                        "code": "ip_not_allowed",
                        "message": "This key cannot be used from this address.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "plan_required": {
                    "value": {
                      "error": {
                        "code": "plan_required",
                        "message": "The API needs the Business plan.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "key_paused": {
                    "value": {
                      "error": {
                        "code": "key_paused",
                        "message": "This key is paused. Someone with access must take it over in Settings.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate_limited",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "value": {
                      "error": {
                        "code": "rate_limited",
                        "message": "Too many requests. Try again in a minute.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "server_error",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "server_error": {
                    "value": {
                      "error": {
                        "code": "server_error",
                        "message": "Something went wrong on our side. Quote the request id if you contact support.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/attendance/days": {
      "get": {
        "operationId": "listAttendanceDays",
        "summary": "Attendance days",
        "description": "One row per person per worked-out day, for up to 31 days.\n\nstatus is one of present, half_day, absent, leave, holiday, weekly_off, on_duty, wfh, not_decided. A day on any leave reads leave. Never a location, photo, device or note.\n\nNeeds the attendance.read scope.",
        "tags": [
          "Attendance days"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "x-lekhahr-scope": "attendance.read",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "description": "Required. First day",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "description": "Required. Last day, at most 31 days in all",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "format": "date"
            }
          },
          {
            "name": "employee_id",
            "in": "query",
            "required": false,
            "description": "Only this person",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1 to 200",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "next_cursor of the last page; lasts 24 hours",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 512
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of days.",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AttendanceDayList"
                },
                "example": {
                  "data": [
                    {
                      "employee_id": "7c1e5a2b-9d3f-4c6e-8a1b-2c3d4e5f6a7b",
                      "date": "2026-11-03",
                      "status": "present",
                      "first_in": "09:42",
                      "last_out": "18:31",
                      "worked_minutes": 489,
                      "late": true,
                      "finalized": true
                    }
                  ],
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "malformed",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "malformed": {
                    "value": {
                      "error": {
                        "code": "malformed",
                        "message": "The request is not in a form this endpoint accepts.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_key",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "WWW-Authenticate": {
                "schema": {
                  "type": "string",
                  "example": "Bearer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_key": {
                    "value": {
                      "error": {
                        "code": "invalid_key",
                        "message": "The API key is missing, not valid, revoked or expired.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "scope_missing, ip_not_allowed, plan_required, key_paused",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "scope_missing": {
                    "value": {
                      "error": {
                        "code": "scope_missing",
                        "message": "This key does not have the scope this endpoint needs.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "ip_not_allowed": {
                    "value": {
                      "error": {
                        "code": "ip_not_allowed",
                        "message": "This key cannot be used from this address.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "plan_required": {
                    "value": {
                      "error": {
                        "code": "plan_required",
                        "message": "The API needs the Business plan.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "key_paused": {
                    "value": {
                      "error": {
                        "code": "key_paused",
                        "message": "This key is paused. Someone with access must take it over in Settings.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "not_found": {
                    "value": {
                      "error": {
                        "code": "not_found",
                        "message": "Not found.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "410": {
            "description": "cursor_expired",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "cursor_expired": {
                    "value": {
                      "error": {
                        "code": "cursor_expired",
                        "message": "This cursor has expired. Start the list again.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate_limited",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "value": {
                      "error": {
                        "code": "rate_limited",
                        "message": "Too many requests. Try again in a minute.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "server_error",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "server_error": {
                    "value": {
                      "error": {
                        "code": "server_error",
                        "message": "Something went wrong on our side. Quote the request id if you contact support.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/leave/requests": {
      "get": {
        "operationId": "listLeaveRequests",
        "summary": "Leave requests",
        "description": "Leave requests that overlap the dates, for up to 366 days.\n\nNever the reason, a note, an attachment or the approver. Protected leave is never listed, and rejected requests are left out.\n\nNeeds the leave.read scope.",
        "tags": [
          "Leave requests"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "x-lekhahr-scope": "leave.read",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "description": "Required",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "description": "Required, at most 366 days in all",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "format": "date"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "approved (the default), pending, cancelled or all",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "approved",
                "cancelled",
                "all"
              ],
              "default": "approved"
            }
          },
          {
            "name": "employee_id",
            "in": "query",
            "required": false,
            "description": "Only this person",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1 to 200",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "next_cursor of the last page; lasts 24 hours",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 512
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of requests.",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeaveRequestList"
                },
                "example": {
                  "data": [
                    {
                      "id": "5c6d7e8f-9a0b-4c1d-8e2f-3a4b5c6d7e8f",
                      "employee_id": "7c1e5a2b-9d3f-4c6e-8a1b-2c3d4e5f6a7b",
                      "leave_type": {
                        "id": "4a5b6c7d-8e9f-4a0b-9c1d-2e3f4a5b6c7d",
                        "name": "Earned leave"
                      },
                      "from": "2026-11-16",
                      "to": "2026-11-18",
                      "half_days": [],
                      "days": 3,
                      "status": "approved",
                      "requested_at": "2026-11-02T04:10:00Z",
                      "decided_at": "2026-11-02T06:00:00Z"
                    }
                  ],
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "malformed",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "malformed": {
                    "value": {
                      "error": {
                        "code": "malformed",
                        "message": "The request is not in a form this endpoint accepts.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_key",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "WWW-Authenticate": {
                "schema": {
                  "type": "string",
                  "example": "Bearer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_key": {
                    "value": {
                      "error": {
                        "code": "invalid_key",
                        "message": "The API key is missing, not valid, revoked or expired.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "scope_missing, ip_not_allowed, plan_required, key_paused",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "scope_missing": {
                    "value": {
                      "error": {
                        "code": "scope_missing",
                        "message": "This key does not have the scope this endpoint needs.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "ip_not_allowed": {
                    "value": {
                      "error": {
                        "code": "ip_not_allowed",
                        "message": "This key cannot be used from this address.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "plan_required": {
                    "value": {
                      "error": {
                        "code": "plan_required",
                        "message": "The API needs the Business plan.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "key_paused": {
                    "value": {
                      "error": {
                        "code": "key_paused",
                        "message": "This key is paused. Someone with access must take it over in Settings.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "not_found": {
                    "value": {
                      "error": {
                        "code": "not_found",
                        "message": "Not found.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "410": {
            "description": "cursor_expired",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "cursor_expired": {
                    "value": {
                      "error": {
                        "code": "cursor_expired",
                        "message": "This cursor has expired. Start the list again.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate_limited",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "value": {
                      "error": {
                        "code": "rate_limited",
                        "message": "Too many requests. Try again in a minute.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "server_error",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "server_error": {
                    "value": {
                      "error": {
                        "code": "server_error",
                        "message": "Something went wrong on our side. Quote the request id if you contact support.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/leave/balances": {
      "get": {
        "operationId": "listLeaveBalances",
        "summary": "Leave balances",
        "description": "Each person's balances on a date, today by default.\n\nPeople who have left are not listed. Protected leave types are left out.\n\nNeeds the leave.read scope.",
        "tags": [
          "Leave balances"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "x-lekhahr-scope": "leave.read",
        "parameters": [
          {
            "name": "employee_id",
            "in": "query",
            "required": false,
            "description": "Only this person",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "as_of",
            "in": "query",
            "required": false,
            "description": "The date; today in the company's timezone by default",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "format": "date"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1 to 200",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "next_cursor of the last page; lasts 24 hours",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 512
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of people's balances.",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeaveBalancesList"
                },
                "example": {
                  "data": [
                    {
                      "employee_id": "7c1e5a2b-9d3f-4c6e-8a1b-2c3d4e5f6a7b",
                      "as_of": "2026-11-04",
                      "balances": [
                        {
                          "leave_type": {
                            "id": "4a5b6c7d-8e9f-4a0b-9c1d-2e3f4a5b6c7d",
                            "name": "Earned leave"
                          },
                          "available": 10,
                          "booked": 3,
                          "unit": "days"
                        },
                        {
                          "leave_type": {
                            "id": "6b7c8d9e-0f1a-4b2c-8d3e-4f5a6b7c8d9e",
                            "name": "Sick leave"
                          },
                          "available": 6,
                          "booked": 1,
                          "unit": "days"
                        }
                      ]
                    }
                  ],
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "malformed",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "malformed": {
                    "value": {
                      "error": {
                        "code": "malformed",
                        "message": "The request is not in a form this endpoint accepts.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_key",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "WWW-Authenticate": {
                "schema": {
                  "type": "string",
                  "example": "Bearer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_key": {
                    "value": {
                      "error": {
                        "code": "invalid_key",
                        "message": "The API key is missing, not valid, revoked or expired.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "scope_missing, ip_not_allowed, plan_required, key_paused",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "scope_missing": {
                    "value": {
                      "error": {
                        "code": "scope_missing",
                        "message": "This key does not have the scope this endpoint needs.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "ip_not_allowed": {
                    "value": {
                      "error": {
                        "code": "ip_not_allowed",
                        "message": "This key cannot be used from this address.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "plan_required": {
                    "value": {
                      "error": {
                        "code": "plan_required",
                        "message": "The API needs the Business plan.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "key_paused": {
                    "value": {
                      "error": {
                        "code": "key_paused",
                        "message": "This key is paused. Someone with access must take it over in Settings.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "not_found": {
                    "value": {
                      "error": {
                        "code": "not_found",
                        "message": "Not found.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "410": {
            "description": "cursor_expired",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "cursor_expired": {
                    "value": {
                      "error": {
                        "code": "cursor_expired",
                        "message": "This cursor has expired. Start the list again.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate_limited",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "value": {
                      "error": {
                        "code": "rate_limited",
                        "message": "Too many requests. Try again in a minute.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "server_error",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "server_error": {
                    "value": {
                      "error": {
                        "code": "server_error",
                        "message": "Something went wrong on our side. Quote the request id if you contact support.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/leave/types": {
      "get": {
        "operationId": "listLeaveTypes",
        "summary": "Leave types",
        "description": "Every leave type of the company, by name.\n\nProtected leave types are left out. A request's leave_type.id is one of these.\n\nNeeds the leave.read scope.",
        "tags": [
          "Leave types"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "x-lekhahr-scope": "leave.read",
        "responses": {
          "200": {
            "description": "The leave types.",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeaveTypeList"
                },
                "example": {
                  "data": [
                    {
                      "id": "4a5b6c7d-8e9f-4a0b-9c1d-2e3f4a5b6c7d",
                      "name": "Earned leave",
                      "unit": "days",
                      "active": true
                    },
                    {
                      "id": "6b7c8d9e-0f1a-4b2c-8d3e-4f5a6b7c8d9e",
                      "name": "Sick leave",
                      "unit": "days",
                      "active": true
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "malformed",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "malformed": {
                    "value": {
                      "error": {
                        "code": "malformed",
                        "message": "The request is not in a form this endpoint accepts.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_key",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "WWW-Authenticate": {
                "schema": {
                  "type": "string",
                  "example": "Bearer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_key": {
                    "value": {
                      "error": {
                        "code": "invalid_key",
                        "message": "The API key is missing, not valid, revoked or expired.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "scope_missing, ip_not_allowed, plan_required, key_paused",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "scope_missing": {
                    "value": {
                      "error": {
                        "code": "scope_missing",
                        "message": "This key does not have the scope this endpoint needs.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "ip_not_allowed": {
                    "value": {
                      "error": {
                        "code": "ip_not_allowed",
                        "message": "This key cannot be used from this address.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "plan_required": {
                    "value": {
                      "error": {
                        "code": "plan_required",
                        "message": "The API needs the Business plan.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "key_paused": {
                    "value": {
                      "error": {
                        "code": "key_paused",
                        "message": "This key is paused. Someone with access must take it over in Settings.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "not_found": {
                    "value": {
                      "error": {
                        "code": "not_found",
                        "message": "Not found.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate_limited",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "value": {
                      "error": {
                        "code": "rate_limited",
                        "message": "Too many requests. Try again in a minute.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "server_error",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "server_error": {
                    "value": {
                      "error": {
                        "code": "server_error",
                        "message": "Something went wrong on our side. Quote the request id if you contact support.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/payroll/runs": {
      "get": {
        "operationId": "listPayrollRuns",
        "summary": "Pay runs",
        "description": "Totals of locked and released pay runs. Needs a whole-company key.\n\nTotals only: never a component, a person or a bank detail. People whose pay is hidden are left out of the totals. Each run returned is recorded in the access log.\n\nNeeds the payroll.read scope on a whole-company key.",
        "tags": [
          "Pay runs"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "x-lekhahr-scope": "payroll.read",
        "parameters": [
          {
            "name": "year",
            "in": "query",
            "required": false,
            "description": "Financial year by its start: 2026 is 1 Apr 2026 to 31 Mar 2027",
            "schema": {
              "type": "string",
              "pattern": "^20\\d{2}$"
            }
          },
          {
            "name": "pay_group_id",
            "in": "query",
            "required": false,
            "description": "Only this pay group",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1 to 200",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "next_cursor of the last page; lasts 24 hours",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 512
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of runs.",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayrollRunList"
                },
                "example": {
                  "data": [
                    {
                      "id": "8f9a0b1c-2d3e-4f4a-9b5c-6d7e8f9a0b1c",
                      "period": "2026-10",
                      "pay_group": {
                        "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                        "name": "Monthly"
                      },
                      "status": "released",
                      "headcount": 41,
                      "gross_paise": 5124800000,
                      "deductions_paise": 612300000,
                      "net_paise": 4512500000,
                      "employer_contributions_paise": 301200000,
                      "currency": "INR",
                      "locked_at": "2026-10-28T09:00:00Z",
                      "released_at": "2026-10-30T06:30:00Z"
                    }
                  ],
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "malformed",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "malformed": {
                    "value": {
                      "error": {
                        "code": "malformed",
                        "message": "The request is not in a form this endpoint accepts.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_key",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "WWW-Authenticate": {
                "schema": {
                  "type": "string",
                  "example": "Bearer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_key": {
                    "value": {
                      "error": {
                        "code": "invalid_key",
                        "message": "The API key is missing, not valid, revoked or expired.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "scope_missing, ip_not_allowed, plan_required, key_paused",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "scope_missing": {
                    "value": {
                      "error": {
                        "code": "scope_missing",
                        "message": "This key does not have the scope this endpoint needs.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "ip_not_allowed": {
                    "value": {
                      "error": {
                        "code": "ip_not_allowed",
                        "message": "This key cannot be used from this address.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "plan_required": {
                    "value": {
                      "error": {
                        "code": "plan_required",
                        "message": "The API needs the Business plan.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "key_paused": {
                    "value": {
                      "error": {
                        "code": "key_paused",
                        "message": "This key is paused. Someone with access must take it over in Settings.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "not_found": {
                    "value": {
                      "error": {
                        "code": "not_found",
                        "message": "Not found.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "410": {
            "description": "cursor_expired",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "cursor_expired": {
                    "value": {
                      "error": {
                        "code": "cursor_expired",
                        "message": "This cursor has expired. Start the list again.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate_limited",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "value": {
                      "error": {
                        "code": "rate_limited",
                        "message": "Too many requests. Try again in a minute.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "server_error",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "server_error": {
                    "value": {
                      "error": {
                        "code": "server_error",
                        "message": "Something went wrong on our side. Quote the request id if you contact support.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/payroll/runs/{id}/payslips": {
      "get": {
        "operationId": "listPayslipSummaries",
        "summary": "Payslip summaries",
        "description": "One row per person of a released run. Needs a whole-company key.\n\nNever components, bank account, PAN, UAN, tax regime, loans or notes. Each person returned is recorded in the access log.\n\nNeeds the payroll.read scope on a whole-company key.",
        "tags": [
          "Payslip summaries"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "x-lekhahr-scope": "payroll.read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The run's id",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1 to 200",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "next_cursor of the last page; lasts 24 hours",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 512
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of payslip summaries.",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayslipSummaryList"
                },
                "example": {
                  "data": [
                    {
                      "employee_id": "7c1e5a2b-9d3f-4c6e-8a1b-2c3d4e5f6a7b",
                      "gross_paise": 12500000,
                      "deductions_paise": 1480000,
                      "net_paise": 11020000,
                      "paid_days": 31,
                      "lop_days": 0,
                      "currency": "INR"
                    }
                  ],
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "malformed",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "malformed": {
                    "value": {
                      "error": {
                        "code": "malformed",
                        "message": "The request is not in a form this endpoint accepts.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_key",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "WWW-Authenticate": {
                "schema": {
                  "type": "string",
                  "example": "Bearer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_key": {
                    "value": {
                      "error": {
                        "code": "invalid_key",
                        "message": "The API key is missing, not valid, revoked or expired.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "scope_missing, ip_not_allowed, plan_required, key_paused",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "scope_missing": {
                    "value": {
                      "error": {
                        "code": "scope_missing",
                        "message": "This key does not have the scope this endpoint needs.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "ip_not_allowed": {
                    "value": {
                      "error": {
                        "code": "ip_not_allowed",
                        "message": "This key cannot be used from this address.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "plan_required": {
                    "value": {
                      "error": {
                        "code": "plan_required",
                        "message": "The API needs the Business plan.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "key_paused": {
                    "value": {
                      "error": {
                        "code": "key_paused",
                        "message": "This key is paused. Someone with access must take it over in Settings.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "not_found": {
                    "value": {
                      "error": {
                        "code": "not_found",
                        "message": "Not found.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "not_released",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "not_released": {
                    "value": {
                      "error": {
                        "code": "not_released",
                        "message": "This payroll run is not released yet.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "410": {
            "description": "cursor_expired",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "cursor_expired": {
                    "value": {
                      "error": {
                        "code": "cursor_expired",
                        "message": "This cursor has expired. Start the list again.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate_limited",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "value": {
                      "error": {
                        "code": "rate_limited",
                        "message": "Too many requests. Try again in a minute.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "server_error",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "120;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "server_error": {
                    "value": {
                      "error": {
                        "code": "server_error",
                        "message": "Something went wrong on our side. Quote the request id if you contact support.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/attendance/punches": {
      "post": {
        "operationId": "sendPunches",
        "summary": "Send punches",
        "description": "Sends up to 500 device punches through an import source, as a device file import does.\n\nPunches are grouped per person and day in the source's timezone: the earliest in is the first swipe, the latest out the last. A day is imported once it has ended, and once per source.\n\n200 when every punch is accepted, 207 with the same body when any is not.\n\nCodes: unknown_person, cycle_locked, future_time, invalid, day_not_ended, too_far_back, on_leave, open_request, fixed, already_imported, not_active, own_day, day_not_ready. New codes may be added.\n\nNeeds the attendance.write scope.",
        "tags": [
          "Send punches"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "x-lekhahr-scope": "attendance.write",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "1 to 64 letters, digits, - or _. Kept 24 hours.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PunchBatch"
              },
              "example": {
                "source": "Front door device",
                "punches": [
                  {
                    "external_id": "door-1-000981",
                    "employee_code": "EX-0042",
                    "at": "2026-11-03T09:42:10+05:30",
                    "direction": "in"
                  },
                  {
                    "external_id": "door-1-001207",
                    "employee_code": "EX-0042",
                    "at": "2026-11-03T18:31:02+05:30",
                    "direction": "out"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Every punch was accepted.",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "30;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "Idempotent-Replayed": {
                "description": "true when this is the stored answer to an earlier request with the same Idempotency-Key.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PunchResults"
                },
                "example": {
                  "results": [
                    {
                      "external_id": "door-1-000981",
                      "result": "accepted"
                    },
                    {
                      "external_id": "door-1-001207",
                      "result": "accepted"
                    }
                  ]
                }
              }
            }
          },
          "207": {
            "description": "Some punches were not accepted; each result says why.",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "30;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PunchResults"
                }
              }
            }
          },
          "400": {
            "description": "malformed",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "30;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "malformed": {
                    "value": {
                      "error": {
                        "code": "malformed",
                        "message": "The request is not in a form this endpoint accepts.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_key",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "30;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "WWW-Authenticate": {
                "schema": {
                  "type": "string",
                  "example": "Bearer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_key": {
                    "value": {
                      "error": {
                        "code": "invalid_key",
                        "message": "The API key is missing, not valid, revoked or expired.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "scope_missing, ip_not_allowed, plan_required, key_paused, plan_read_only",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "30;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "scope_missing": {
                    "value": {
                      "error": {
                        "code": "scope_missing",
                        "message": "This key does not have the scope this endpoint needs.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "ip_not_allowed": {
                    "value": {
                      "error": {
                        "code": "ip_not_allowed",
                        "message": "This key cannot be used from this address.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "plan_required": {
                    "value": {
                      "error": {
                        "code": "plan_required",
                        "message": "The API needs the Business plan.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "key_paused": {
                    "value": {
                      "error": {
                        "code": "key_paused",
                        "message": "This key is paused. Someone with access must take it over in Settings.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "plan_read_only": {
                    "value": {
                      "error": {
                        "code": "plan_read_only",
                        "message": "The company's plan allows reads only.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "request_in_progress, try_again",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "30;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "request_in_progress": {
                    "value": {
                      "error": {
                        "code": "request_in_progress",
                        "message": "A request with this idempotency key is still running.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  },
                  "try_again": {
                    "value": {
                      "error": {
                        "code": "try_again",
                        "message": "Another change to the same records happened at the same moment. Nothing was saved; send the request again.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "validation_failed, idempotency_key_reused",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "30;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_failed": {
                    "value": {
                      "error": {
                        "code": "validation_failed",
                        "message": "Some fields are not valid.",
                        "request_id": "4e5b6a7c",
                        "fields": [
                          {
                            "field": "work_email",
                            "code": "email_taken"
                          }
                        ]
                      }
                    }
                  },
                  "idempotency_key_reused": {
                    "value": {
                      "error": {
                        "code": "idempotency_key_reused",
                        "message": "This idempotency key was used for a different request.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate_limited",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "30;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "value": {
                      "error": {
                        "code": "rate_limited",
                        "message": "Too many requests. Try again in a minute.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "server_error",
            "headers": {
              "RateLimit-Policy": {
                "description": "The key's limit and window, in seconds.",
                "schema": {
                  "type": "string",
                  "example": "30;w=60"
                }
              },
              "Cache-Control": {
                "description": "Always private, no-store.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "server_error": {
                    "value": {
                      "error": {
                        "code": "server_error",
                        "message": "Something went wrong on our side. Quote the request id if you contact support.",
                        "request_id": "4e5b6a7c"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {
    "employee.joined": {
      "post": {
        "operationId": "webhook_employee_joined",
        "summary": "employee.joined",
        "description": "A person's record becomes active. The webhook's key needs people.read.",
        "x-lekhahr-scope": "people.read",
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id. The same on every retry and Send again.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Seconds since 1970. Refuse one more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "v1, then the base64 HMAC-SHA256. Two, new first, for 24 hours after a rotation.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "type": {
                    "type": "string",
                    "const": "employee.joined"
                  },
                  "created_at": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"
                  },
                  "company_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "sequence": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "employee_id": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "date_of_joining": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                        "format": "date"
                      }
                    },
                    "required": [
                      "employee_id",
                      "date_of_joining"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "company_id",
                  "sequence",
                  "data"
                ],
                "additionalProperties": false
              },
              "example": {
                "id": "0b7c6f0e-5b4e-5c39-9a51-3c1d2f9e8a10",
                "type": "employee.joined",
                "created_at": "2026-10-29T18:30:00Z",
                "company_id": "6a3d9c1e-2f4b-4e8a-9d7c-1b2a3c4d5e6f",
                "sequence": 4,
                "data": {
                  "employee_id": "7c1e5a2b-9d3f-4c6e-8a1b-2c3d4e5f6a7b",
                  "date_of_joining": "2026-11-16"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Stops the retries of this delivery."
          },
          "2XX": {
            "description": "Delivered."
          },
          "default": {
            "description": "Tried again on the retry schedule."
          }
        }
      }
    },
    "employee.updated": {
      "post": {
        "operationId": "webhook_employee_updated",
        "summary": "employee.updated",
        "description": "Name, code, designation, department, location or manager changed, effective today or earlier. The webhook's key needs people.read.",
        "x-lekhahr-scope": "people.read",
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id. The same on every retry and Send again.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Seconds since 1970. Refuse one more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "v1, then the base64 HMAC-SHA256. Two, new first, for 24 hours after a rotation.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "type": {
                    "type": "string",
                    "const": "employee.updated"
                  },
                  "created_at": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"
                  },
                  "company_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "sequence": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "employee_id": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "changed": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "enum": [
                            "full_name",
                            "employee_code",
                            "designation",
                            "department",
                            "location",
                            "manager"
                          ]
                        },
                        "minItems": 1
                      }
                    },
                    "required": [
                      "employee_id",
                      "changed"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "company_id",
                  "sequence",
                  "data"
                ],
                "additionalProperties": false
              },
              "example": {
                "id": "0b7c6f0e-5b4e-5c39-9a51-3c1d2f9e8a10",
                "type": "employee.updated",
                "created_at": "2026-10-29T18:30:00Z",
                "company_id": "6a3d9c1e-2f4b-4e8a-9d7c-1b2a3c4d5e6f",
                "sequence": 4,
                "data": {
                  "employee_id": "7c1e5a2b-9d3f-4c6e-8a1b-2c3d4e5f6a7b",
                  "changed": [
                    "designation",
                    "manager"
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Stops the retries of this delivery."
          },
          "2XX": {
            "description": "Delivered."
          },
          "default": {
            "description": "Tried again on the retry schedule."
          }
        }
      }
    },
    "employee.exit_scheduled": {
      "post": {
        "operationId": "webhook_employee_exit_scheduled",
        "summary": "employee.exit_scheduled",
        "description": "An exit is approved with a last working day. The webhook's key needs people.read.",
        "x-lekhahr-scope": "people.read",
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id. The same on every retry and Send again.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Seconds since 1970. Refuse one more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "v1, then the base64 HMAC-SHA256. Two, new first, for 24 hours after a rotation.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "type": {
                    "type": "string",
                    "const": "employee.exit_scheduled"
                  },
                  "created_at": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"
                  },
                  "company_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "sequence": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "employee_id": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "last_working_day": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                        "format": "date"
                      }
                    },
                    "required": [
                      "employee_id",
                      "last_working_day"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "company_id",
                  "sequence",
                  "data"
                ],
                "additionalProperties": false
              },
              "example": {
                "id": "0b7c6f0e-5b4e-5c39-9a51-3c1d2f9e8a10",
                "type": "employee.exit_scheduled",
                "created_at": "2026-10-29T18:30:00Z",
                "company_id": "6a3d9c1e-2f4b-4e8a-9d7c-1b2a3c4d5e6f",
                "sequence": 4,
                "data": {
                  "employee_id": "7c1e5a2b-9d3f-4c6e-8a1b-2c3d4e5f6a7b",
                  "last_working_day": "2026-10-30"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Stops the retries of this delivery."
          },
          "2XX": {
            "description": "Delivered."
          },
          "default": {
            "description": "Tried again on the retry schedule."
          }
        }
      }
    },
    "employee.left": {
      "post": {
        "operationId": "webhook_employee_left",
        "summary": "employee.left",
        "description": "The record moves to exited. The webhook's key needs people.read.",
        "x-lekhahr-scope": "people.read",
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id. The same on every retry and Send again.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Seconds since 1970. Refuse one more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "v1, then the base64 HMAC-SHA256. Two, new first, for 24 hours after a rotation.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "type": {
                    "type": "string",
                    "const": "employee.left"
                  },
                  "created_at": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"
                  },
                  "company_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "sequence": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "employee_id": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "last_working_day": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                        "format": "date"
                      }
                    },
                    "required": [
                      "employee_id",
                      "last_working_day"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "company_id",
                  "sequence",
                  "data"
                ],
                "additionalProperties": false
              },
              "example": {
                "id": "0b7c6f0e-5b4e-5c39-9a51-3c1d2f9e8a10",
                "type": "employee.left",
                "created_at": "2026-10-29T18:30:00Z",
                "company_id": "6a3d9c1e-2f4b-4e8a-9d7c-1b2a3c4d5e6f",
                "sequence": 4,
                "data": {
                  "employee_id": "7c1e5a2b-9d3f-4c6e-8a1b-2c3d4e5f6a7b",
                  "last_working_day": "2026-10-30"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Stops the retries of this delivery."
          },
          "2XX": {
            "description": "Delivered."
          },
          "default": {
            "description": "Tried again on the retry schedule."
          }
        }
      }
    },
    "leave.requested": {
      "post": {
        "operationId": "webhook_leave_requested",
        "summary": "leave.requested",
        "description": "A leave request is sent. The webhook's key needs leave.read.",
        "x-lekhahr-scope": "leave.read",
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id. The same on every retry and Send again.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Seconds since 1970. Refuse one more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "v1, then the base64 HMAC-SHA256. Two, new first, for 24 hours after a rotation.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "type": {
                    "type": "string",
                    "const": "leave.requested"
                  },
                  "created_at": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"
                  },
                  "company_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "sequence": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "leave_request_id": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "employee_id": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "from": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                        "format": "date"
                      },
                      "to": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                        "format": "date"
                      }
                    },
                    "required": [
                      "leave_request_id",
                      "employee_id",
                      "from",
                      "to"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "company_id",
                  "sequence",
                  "data"
                ],
                "additionalProperties": false
              },
              "example": {
                "id": "0b7c6f0e-5b4e-5c39-9a51-3c1d2f9e8a10",
                "type": "leave.requested",
                "created_at": "2026-10-29T18:30:00Z",
                "company_id": "6a3d9c1e-2f4b-4e8a-9d7c-1b2a3c4d5e6f",
                "sequence": 4,
                "data": {
                  "leave_request_id": "5c6d7e8f-9a0b-4c1d-8e2f-3a4b5c6d7e8f",
                  "employee_id": "7c1e5a2b-9d3f-4c6e-8a1b-2c3d4e5f6a7b",
                  "from": "2026-11-16",
                  "to": "2026-11-18"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Stops the retries of this delivery."
          },
          "2XX": {
            "description": "Delivered."
          },
          "default": {
            "description": "Tried again on the retry schedule."
          }
        }
      }
    },
    "leave.approved": {
      "post": {
        "operationId": "webhook_leave_approved",
        "summary": "leave.approved",
        "description": "A request is approved. The webhook's key needs leave.read.",
        "x-lekhahr-scope": "leave.read",
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id. The same on every retry and Send again.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Seconds since 1970. Refuse one more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "v1, then the base64 HMAC-SHA256. Two, new first, for 24 hours after a rotation.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "type": {
                    "type": "string",
                    "const": "leave.approved"
                  },
                  "created_at": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"
                  },
                  "company_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "sequence": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "leave_request_id": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "employee_id": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "from": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                        "format": "date"
                      },
                      "to": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                        "format": "date"
                      }
                    },
                    "required": [
                      "leave_request_id",
                      "employee_id",
                      "from",
                      "to"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "company_id",
                  "sequence",
                  "data"
                ],
                "additionalProperties": false
              },
              "example": {
                "id": "0b7c6f0e-5b4e-5c39-9a51-3c1d2f9e8a10",
                "type": "leave.approved",
                "created_at": "2026-10-29T18:30:00Z",
                "company_id": "6a3d9c1e-2f4b-4e8a-9d7c-1b2a3c4d5e6f",
                "sequence": 4,
                "data": {
                  "leave_request_id": "5c6d7e8f-9a0b-4c1d-8e2f-3a4b5c6d7e8f",
                  "employee_id": "7c1e5a2b-9d3f-4c6e-8a1b-2c3d4e5f6a7b",
                  "from": "2026-11-16",
                  "to": "2026-11-18"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Stops the retries of this delivery."
          },
          "2XX": {
            "description": "Delivered."
          },
          "default": {
            "description": "Tried again on the retry schedule."
          }
        }
      }
    },
    "leave.cancelled": {
      "post": {
        "operationId": "webhook_leave_cancelled",
        "summary": "leave.cancelled",
        "description": "An approved or pending request is cancelled or withdrawn. The webhook's key needs leave.read.",
        "x-lekhahr-scope": "leave.read",
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id. The same on every retry and Send again.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Seconds since 1970. Refuse one more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "v1, then the base64 HMAC-SHA256. Two, new first, for 24 hours after a rotation.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "type": {
                    "type": "string",
                    "const": "leave.cancelled"
                  },
                  "created_at": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"
                  },
                  "company_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "sequence": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "leave_request_id": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "employee_id": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "from": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                        "format": "date"
                      },
                      "to": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                        "format": "date"
                      }
                    },
                    "required": [
                      "leave_request_id",
                      "employee_id",
                      "from",
                      "to"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "company_id",
                  "sequence",
                  "data"
                ],
                "additionalProperties": false
              },
              "example": {
                "id": "0b7c6f0e-5b4e-5c39-9a51-3c1d2f9e8a10",
                "type": "leave.cancelled",
                "created_at": "2026-10-29T18:30:00Z",
                "company_id": "6a3d9c1e-2f4b-4e8a-9d7c-1b2a3c4d5e6f",
                "sequence": 4,
                "data": {
                  "leave_request_id": "5c6d7e8f-9a0b-4c1d-8e2f-3a4b5c6d7e8f",
                  "employee_id": "7c1e5a2b-9d3f-4c6e-8a1b-2c3d4e5f6a7b",
                  "from": "2026-11-16",
                  "to": "2026-11-18"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Stops the retries of this delivery."
          },
          "2XX": {
            "description": "Delivered."
          },
          "default": {
            "description": "Tried again on the retry schedule."
          }
        }
      }
    },
    "attendance.day_finalized": {
      "post": {
        "operationId": "webhook_attendance_day_finalized",
        "summary": "attendance.day_finalized",
        "description": "A person's day is finalised, or finalised again after a correction. The webhook's key needs attendance.read.",
        "x-lekhahr-scope": "attendance.read",
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id. The same on every retry and Send again.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Seconds since 1970. Refuse one more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "v1, then the base64 HMAC-SHA256. Two, new first, for 24 hours after a rotation.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "type": {
                    "type": "string",
                    "const": "attendance.day_finalized"
                  },
                  "created_at": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"
                  },
                  "company_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "sequence": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "employee_id": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "date": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                        "format": "date"
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "present",
                          "half_day",
                          "absent",
                          "leave",
                          "holiday",
                          "weekly_off",
                          "on_duty",
                          "wfh",
                          "not_decided"
                        ]
                      }
                    },
                    "required": [
                      "employee_id",
                      "date",
                      "status"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "company_id",
                  "sequence",
                  "data"
                ],
                "additionalProperties": false
              },
              "example": {
                "id": "0b7c6f0e-5b4e-5c39-9a51-3c1d2f9e8a10",
                "type": "attendance.day_finalized",
                "created_at": "2026-10-29T18:30:00Z",
                "company_id": "6a3d9c1e-2f4b-4e8a-9d7c-1b2a3c4d5e6f",
                "sequence": 4,
                "data": {
                  "employee_id": "7c1e5a2b-9d3f-4c6e-8a1b-2c3d4e5f6a7b",
                  "date": "2026-11-03",
                  "status": "present"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Stops the retries of this delivery."
          },
          "2XX": {
            "description": "Delivered."
          },
          "default": {
            "description": "Tried again on the retry schedule."
          }
        }
      }
    },
    "payroll.run_locked": {
      "post": {
        "operationId": "webhook_payroll_run_locked",
        "summary": "payroll.run_locked",
        "description": "A pay run is locked. The webhook's key needs payroll.read and must cover the whole company.",
        "x-lekhahr-scope": "payroll.read",
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id. The same on every retry and Send again.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Seconds since 1970. Refuse one more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "v1, then the base64 HMAC-SHA256. Two, new first, for 24 hours after a rotation.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "type": {
                    "type": "string",
                    "const": "payroll.run_locked"
                  },
                  "created_at": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"
                  },
                  "company_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "sequence": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "payroll_run_id": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "period": {
                        "type": "string",
                        "pattern": "^\\d{4}-(0[1-9]|1[0-2])$"
                      },
                      "pay_group_id": {
                        "type": "string",
                        "format": "uuid"
                      }
                    },
                    "required": [
                      "payroll_run_id",
                      "period",
                      "pay_group_id"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "company_id",
                  "sequence",
                  "data"
                ],
                "additionalProperties": false
              },
              "example": {
                "id": "0b7c6f0e-5b4e-5c39-9a51-3c1d2f9e8a10",
                "type": "payroll.run_locked",
                "created_at": "2026-10-29T18:30:00Z",
                "company_id": "6a3d9c1e-2f4b-4e8a-9d7c-1b2a3c4d5e6f",
                "sequence": 4,
                "data": {
                  "payroll_run_id": "8f9a0b1c-2d3e-4f4a-9b5c-6d7e8f9a0b1c",
                  "period": "2026-10",
                  "pay_group_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Stops the retries of this delivery."
          },
          "2XX": {
            "description": "Delivered."
          },
          "default": {
            "description": "Tried again on the retry schedule."
          }
        }
      }
    },
    "payroll.payslips_released": {
      "post": {
        "operationId": "webhook_payroll_payslips_released",
        "summary": "payroll.payslips_released",
        "description": "A run's payslips are released to people. The webhook's key needs payroll.read and must cover the whole company.",
        "x-lekhahr-scope": "payroll.read",
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id. The same on every retry and Send again.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Seconds since 1970. Refuse one more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "v1, then the base64 HMAC-SHA256. Two, new first, for 24 hours after a rotation.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "type": {
                    "type": "string",
                    "const": "payroll.payslips_released"
                  },
                  "created_at": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"
                  },
                  "company_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "sequence": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "payroll_run_id": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "period": {
                        "type": "string",
                        "pattern": "^\\d{4}-(0[1-9]|1[0-2])$"
                      },
                      "released_count": {
                        "type": "integer",
                        "minimum": 0
                      }
                    },
                    "required": [
                      "payroll_run_id",
                      "period",
                      "released_count"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "company_id",
                  "sequence",
                  "data"
                ],
                "additionalProperties": false
              },
              "example": {
                "id": "0b7c6f0e-5b4e-5c39-9a51-3c1d2f9e8a10",
                "type": "payroll.payslips_released",
                "created_at": "2026-10-29T18:30:00Z",
                "company_id": "6a3d9c1e-2f4b-4e8a-9d7c-1b2a3c4d5e6f",
                "sequence": 4,
                "data": {
                  "payroll_run_id": "8f9a0b1c-2d3e-4f4a-9b5c-6d7e8f9a0b1c",
                  "period": "2026-10",
                  "released_count": 41
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Stops the retries of this delivery."
          },
          "2XX": {
            "description": "Delivered."
          },
          "default": {
            "description": "Tried again on the retry schedule."
          }
        }
      }
    },
    "webhook.test": {
      "post": {
        "operationId": "webhook_webhook_test",
        "summary": "webhook.test",
        "description": "Someone presses Send test in Settings.",
        "x-lekhahr-scope": null,
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event id. The same on every retry and Send again.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Seconds since 1970. Refuse one more than 5 minutes from your clock.",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "v1, then the base64 HMAC-SHA256. Two, new first, for 24 hours after a rotation.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "type": {
                    "type": "string",
                    "const": "webhook.test"
                  },
                  "created_at": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"
                  },
                  "company_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "sequence": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "data": {
                    "type": "object",
                    "properties": {},
                    "additionalProperties": false
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "company_id",
                  "sequence",
                  "data"
                ],
                "additionalProperties": false
              },
              "example": {
                "id": "0b7c6f0e-5b4e-5c39-9a51-3c1d2f9e8a10",
                "type": "webhook.test",
                "created_at": "2026-10-29T18:30:00Z",
                "company_id": "6a3d9c1e-2f4b-4e8a-9d7c-1b2a3c4d5e6f",
                "sequence": 0,
                "data": {}
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Stops the retries of this delivery."
          },
          "2XX": {
            "description": "Delivered."
          },
          "default": {
            "description": "Tried again on the retry schedule."
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Company": {
        "type": "object",
        "properties": {
          "company": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              },
              "timezone": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "name",
              "timezone"
            ],
            "additionalProperties": false
          },
          "key": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[0-9A-HJKMNP-TV-Z]{12}$"
              },
              "name": {
                "type": "string"
              },
              "scopes": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "people.read",
                    "people.write",
                    "attendance.read",
                    "attendance.write",
                    "leave.read",
                    "payroll.read"
                  ]
                }
              },
              "coverage": {
                "oneOf": [
                  {
                    "type": "object",
                    "properties": {
                      "kind": {
                        "type": "string",
                        "const": "company"
                      }
                    },
                    "required": [
                      "kind"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "kind": {
                        "type": "string",
                        "const": "groups"
                      },
                      "groups": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "kind": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "kind",
                            "name"
                          ],
                          "additionalProperties": false
                        }
                      }
                    },
                    "required": [
                      "kind",
                      "groups"
                    ],
                    "additionalProperties": false
                  }
                ]
              },
              "expires_on": {
                "type": "string",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                "format": "date"
              }
            },
            "required": [
              "id",
              "name",
              "scopes",
              "coverage",
              "expires_on"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "company",
          "key"
        ],
        "additionalProperties": false
      },
      "Person": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "employee_code": {
            "type": "string"
          },
          "full_name": {
            "type": "string"
          },
          "designation": {
            "type": [
              "string",
              "null"
            ]
          },
          "department": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "name"
            ],
            "additionalProperties": false
          },
          "location": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "name"
            ],
            "additionalProperties": false
          },
          "manager_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "onboarding",
              "on_notice",
              "exited"
            ]
          },
          "date_of_joining": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "format": "date"
          },
          "last_working_day": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "format": "date"
          },
          "updated_at": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "employee_code",
          "full_name",
          "designation",
          "department",
          "location",
          "manager_id",
          "status",
          "date_of_joining",
          "last_working_day",
          "updated_at"
        ],
        "additionalProperties": false
      },
      "PersonList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Person"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "data",
          "next_cursor"
        ],
        "additionalProperties": false
      },
      "ReferenceItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "active": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "name",
          "active"
        ],
        "additionalProperties": false
      },
      "ReferenceList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReferenceItem"
            }
          }
        },
        "required": [
          "data"
        ],
        "additionalProperties": false
      },
      "AttendanceDay": {
        "type": "object",
        "properties": {
          "employee_id": {
            "type": "string",
            "format": "uuid"
          },
          "date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "format": "date"
          },
          "status": {
            "type": "string",
            "enum": [
              "present",
              "half_day",
              "absent",
              "leave",
              "holiday",
              "weekly_off",
              "on_duty",
              "wfh",
              "not_decided"
            ]
          },
          "first_in": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
          },
          "last_out": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
          },
          "worked_minutes": {
            "type": "integer",
            "minimum": 0
          },
          "late": {
            "type": "boolean"
          },
          "finalized": {
            "type": "boolean"
          }
        },
        "required": [
          "employee_id",
          "date",
          "status",
          "first_in",
          "last_out",
          "worked_minutes",
          "late",
          "finalized"
        ],
        "additionalProperties": false
      },
      "AttendanceDayList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AttendanceDay"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "data",
          "next_cursor"
        ],
        "additionalProperties": false
      },
      "LeaveRequest": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "employee_id": {
            "type": "string",
            "format": "uuid"
          },
          "leave_type": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "name"
            ],
            "additionalProperties": false
          },
          "from": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "format": "date"
          },
          "to": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "format": "date"
          },
          "half_days": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "format": "date"
            }
          },
          "days": {
            "type": "number",
            "minimum": 0
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "approved",
              "cancelled"
            ]
          },
          "requested_at": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$",
            "format": "date-time"
          },
          "decided_at": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "employee_id",
          "leave_type",
          "from",
          "to",
          "half_days",
          "days",
          "status",
          "requested_at",
          "decided_at"
        ],
        "additionalProperties": false
      },
      "LeaveRequestList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LeaveRequest"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "data",
          "next_cursor"
        ],
        "additionalProperties": false
      },
      "LeaveBalance": {
        "type": "object",
        "properties": {
          "leave_type": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "name"
            ],
            "additionalProperties": false
          },
          "available": {
            "type": "number"
          },
          "booked": {
            "type": "number"
          },
          "unit": {
            "type": "string",
            "const": "days"
          }
        },
        "required": [
          "leave_type",
          "available",
          "booked",
          "unit"
        ],
        "additionalProperties": false
      },
      "LeaveBalances": {
        "type": "object",
        "properties": {
          "employee_id": {
            "type": "string",
            "format": "uuid"
          },
          "as_of": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "format": "date"
          },
          "balances": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LeaveBalance"
            }
          }
        },
        "required": [
          "employee_id",
          "as_of",
          "balances"
        ],
        "additionalProperties": false
      },
      "LeaveBalancesList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LeaveBalances"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "data",
          "next_cursor"
        ],
        "additionalProperties": false
      },
      "LeaveType": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "unit": {
            "type": "string",
            "const": "days"
          },
          "active": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "name",
          "unit",
          "active"
        ],
        "additionalProperties": false
      },
      "LeaveTypeList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LeaveType"
            }
          }
        },
        "required": [
          "data"
        ],
        "additionalProperties": false
      },
      "PayrollRun": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "period": {
            "type": "string",
            "pattern": "^\\d{4}-(0[1-9]|1[0-2])$"
          },
          "pay_group": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "name"
            ],
            "additionalProperties": false
          },
          "status": {
            "type": "string",
            "enum": [
              "locked",
              "released"
            ]
          },
          "headcount": {
            "type": "integer",
            "minimum": 0
          },
          "gross_paise": {
            "type": "integer"
          },
          "deductions_paise": {
            "type": "integer"
          },
          "net_paise": {
            "type": "integer"
          },
          "employer_contributions_paise": {
            "type": "integer"
          },
          "currency": {
            "type": "string",
            "const": "INR"
          },
          "locked_at": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$",
            "format": "date-time"
          },
          "released_at": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "period",
          "pay_group",
          "status",
          "headcount",
          "gross_paise",
          "deductions_paise",
          "net_paise",
          "employer_contributions_paise",
          "currency",
          "locked_at",
          "released_at"
        ],
        "additionalProperties": false
      },
      "PayrollRunList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PayrollRun"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "data",
          "next_cursor"
        ],
        "additionalProperties": false
      },
      "PayslipSummary": {
        "type": "object",
        "properties": {
          "employee_id": {
            "type": "string",
            "format": "uuid"
          },
          "gross_paise": {
            "type": "integer"
          },
          "deductions_paise": {
            "type": "integer"
          },
          "net_paise": {
            "type": "integer"
          },
          "paid_days": {
            "type": "number",
            "minimum": 0
          },
          "lop_days": {
            "type": "number",
            "minimum": 0
          },
          "currency": {
            "type": "string",
            "const": "INR"
          }
        },
        "required": [
          "employee_id",
          "gross_paise",
          "deductions_paise",
          "net_paise",
          "paid_days",
          "lop_days",
          "currency"
        ],
        "additionalProperties": false
      },
      "PayslipSummaryList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PayslipSummary"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "data",
          "next_cursor"
        ],
        "additionalProperties": false
      },
      "PersonCreate": {
        "type": "object",
        "properties": {
          "full_name": {
            "type": "string",
            "maxLength": 200
          },
          "work_email": {
            "type": "string",
            "maxLength": 200
          },
          "mobile": {
            "type": "string",
            "maxLength": 40
          },
          "date_of_joining": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "format": "date"
          },
          "department_id": {
            "type": "string",
            "format": "uuid"
          },
          "location_id": {
            "type": "string",
            "format": "uuid"
          },
          "designation": {
            "type": "string",
            "maxLength": 200
          },
          "manager_id": {
            "type": "string",
            "format": "uuid"
          },
          "employee_code": {
            "type": "string",
            "maxLength": 40
          }
        },
        "required": [
          "full_name",
          "date_of_joining",
          "department_id"
        ],
        "additionalProperties": false
      },
      "Punch": {
        "type": "object",
        "properties": {
          "external_id": {
            "type": "string",
            "pattern": "^[\\x21-\\x7E]{1,64}$"
          },
          "employee_id": {
            "type": "string",
            "format": "uuid"
          },
          "employee_code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 30
          },
          "badge_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 40
          },
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "direction": {
            "type": "string",
            "enum": [
              "in",
              "out",
              "unknown"
            ]
          }
        },
        "required": [
          "external_id",
          "at",
          "direction"
        ],
        "additionalProperties": false
      },
      "PunchBatch": {
        "type": "object",
        "properties": {
          "source": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80
          },
          "punches": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Punch"
            },
            "minItems": 1,
            "maxItems": 500
          }
        },
        "required": [
          "source",
          "punches"
        ],
        "additionalProperties": false
      },
      "PunchResult": {
        "type": "object",
        "properties": {
          "external_id": {
            "type": "string"
          },
          "result": {
            "type": "string",
            "enum": [
              "accepted",
              "duplicate",
              "rejected"
            ]
          },
          "code": {
            "type": "string",
            "enum": [
              "unknown_person",
              "cycle_locked",
              "future_time",
              "invalid",
              "day_not_ended",
              "too_far_back",
              "on_leave",
              "open_request",
              "fixed",
              "already_imported",
              "not_active",
              "own_day",
              "day_not_ready"
            ]
          }
        },
        "required": [
          "external_id",
          "result"
        ],
        "additionalProperties": false
      },
      "PunchResults": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PunchResult"
            }
          }
        },
        "required": [
          "results"
        ],
        "additionalProperties": false
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "malformed",
                  "invalid_key",
                  "scope_missing",
                  "ip_not_allowed",
                  "plan_required",
                  "plan_read_only",
                  "key_paused",
                  "not_found",
                  "request_in_progress",
                  "cursor_expired",
                  "validation_failed",
                  "idempotency_key_reused",
                  "rate_limited",
                  "not_released",
                  "server_error",
                  "try_again"
                ]
              },
              "message": {
                "type": "string",
                "minLength": 1,
                "maxLength": 300
              },
              "request_id": {
                "type": "string",
                "minLength": 1,
                "maxLength": 64
              },
              "fields": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "field": {
                      "type": "string",
                      "maxLength": 80
                    },
                    "code": {
                      "type": "string",
                      "maxLength": 60
                    }
                  },
                  "required": [
                    "field",
                    "code"
                  ],
                  "additionalProperties": false
                }
              }
            },
            "required": [
              "code",
              "message",
              "request_id"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "error"
        ],
        "additionalProperties": false
      }
    },
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "lkh_live_<key id>_<secret>",
        "description": "Send the key as Authorization: Bearer <key>."
      }
    }
  },
  "x-lekhahr-rate-limits": {
    "ipPerMinute": 300,
    "keyReadsPerMinute": 120,
    "keyWritesPerMinute": 30,
    "companyPerMinute": 600,
    "windowSeconds": 60
  },
  "x-lekhahr-idempotency": {
    "header": "Idempotency-Key",
    "pattern": "^[A-Za-z0-9_-]{1,64}$",
    "keptHours": 24,
    "replayHeader": "Idempotent-Replayed"
  },
  "x-lekhahr-webhook-signing": {
    "scheme": "Standard Webhooks v1: v1, + base64(HMAC-SHA256(base64-decoded secret after whsec_, webhook-id + \".\" + webhook-timestamp + \".\" + raw body))",
    "toleranceSeconds": 300,
    "rotationOverlapHours": 24,
    "example": {
      "secret": "whsec_TEVLSEFIUi1FWEFNUExFLVdFQkhPT0stU0VDUkVUISE=",
      "id": "0b7c6f0e-5b4e-5c39-9a51-3c1d2f9e8a10",
      "timestamp": 1793334600,
      "body": "{\"id\":\"0b7c6f0e-5b4e-5c39-9a51-3c1d2f9e8a10\",\"type\":\"employee.left\",\"created_at\":\"2026-10-29T18:30:00Z\",\"company_id\":\"6a3d9c1e-2f4b-4e8a-9d7c-1b2a3c4d5e6f\",\"sequence\":4,\"data\":{\"employee_id\":\"7c1e5a2b-9d3f-4c6e-8a1b-2c3d4e5f6a7b\",\"last_working_day\":\"2026-10-30\"}}",
      "signature": "v1,76eIkM5iRIG1J0V+2jMv+8L2f/8lH39ucpkG52wCsFc="
    },
    "rotation": {
      "name": "rotation: the new secret first, then the previous one",
      "secrets": [
        "whsec_TEVLSEFIUi1FWEFNUExFLVdFQkhPT0stUk9UQVRFRCE=",
        "whsec_TEVLSEFIUi1FWEFNUExFLVdFQkhPT0stU0VDUkVUISE="
      ],
      "id": "0b7c6f0e-5b4e-5c39-9a51-3c1d2f9e8a10",
      "timestamp": 1793334600,
      "body": "{\"id\":\"0b7c6f0e-5b4e-5c39-9a51-3c1d2f9e8a10\",\"type\":\"employee.left\",\"created_at\":\"2026-10-29T18:30:00Z\",\"company_id\":\"6a3d9c1e-2f4b-4e8a-9d7c-1b2a3c4d5e6f\",\"sequence\":4,\"data\":{\"employee_id\":\"7c1e5a2b-9d3f-4c6e-8a1b-2c3d4e5f6a7b\",\"last_working_day\":\"2026-10-30\"}}",
      "header": "v1,lw71bpEMmWiqvUQW2G5PTK5S6LuqaHvm5DKAboaszwY= v1,76eIkM5iRIG1J0V+2jMv+8L2f/8lH39ucpkG52wCsFc="
    }
  },
  "x-lekhahr-webhook-retries": {
    "delaysSeconds": [
      60,
      300,
      1800,
      7200,
      21600,
      43200,
      86400
    ],
    "tries": 8,
    "totalHours": 45,
    "timeoutSeconds": 10,
    "pauseAfterHours": 24,
    "pauseMinFailed": 3,
    "holdDays": 7,
    "resendDays": 30
  },
  "x-lekhahr-changelog": [
    {
      "date": "2026-10-21",
      "change": "v1: company, people, departments, locations, attendance days, leave requests, balances and types, pay runs and payslip summaries; add a person and send punches; ten webhook events."
    }
  ]
}
