{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://developer.paycaptain.com/schemas/employee.schema.json",
  "title": "PayCaptain Employee",
  "description": "Single-record rules for POST /employee. Cross-field and cross-record rules are at https://developer.paycaptain.com/rules.",
  "type": "object",
  "properties": {
    "company": {
      "type": "string",
      "description": "Company code issued by the PayCaptain team. Must match your PayCaptain company code exactly.",
      "examples": [
        "ABC"
      ]
    },
    "hrEmployeeId": {
      "type": "string",
      "description": "Your system's identifier for the person. PayCaptain upserts on this value. Unique per person. Never changes, and is the same across all of that person's employments.",
      "examples": [
        "9876543210"
      ]
    },
    "payrollCode": {
      "type": "string",
      "description": "Identifier for one employment period. HMRC uses this code. Unique per employment. Never changed once assigned, never reused. A returning employee gets a new code.",
      "examples": [
        "123"
      ]
    },
    "firstName": {
      "type": "string",
      "minLength": 1,
      "description": "First name. Must not be empty.",
      "examples": [
        "Jason"
      ]
    },
    "middleName": {
      "type": "string",
      "description": "Middle name.",
      "examples": [
        "Z"
      ]
    },
    "lastName": {
      "type": "string",
      "minLength": 1,
      "description": "Last name. Must not be empty.",
      "examples": [
        "Smith"
      ]
    },
    "dateOfBirth": {
      "type": "string",
      "format": "date",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Date of birth. A valid date in the past.",
      "examples": [
        "2000-01-01"
      ]
    },
    "gender": {
      "type": "string",
      "enum": [
        "Male",
        "Female"
      ],
      "description": "Gender as reported to HMRC. Exactly one of the allowed values. This is an HMRC requirement.",
      "examples": [
        "Male"
      ]
    },
    "email": {
      "type": "string",
      "format": "email",
      "description": "Home email address. Valid email format.",
      "examples": [
        "jason@example.com"
      ]
    },
    "phone": {
      "type": "string",
      "description": "Phone number. Mobile preferred.",
      "examples": [
        "08000885262"
      ]
    },
    "photoUrl": {
      "type": "string",
      "format": "uri",
      "description": "URL of a photo of the employee.",
      "examples": [
        "https://example.com/jason.jpg"
      ]
    },
    "niNumber": {
      "type": "string",
      "pattern": "^(?!BG|GB|KN|NK|NT|TN|ZZ)[A-CEGHJ-PR-TW-Z][A-CEGHJ-NPR-TW-Z][0-9]{6}[A-D]$",
      "description": "National Insurance number. A valid UK National Insurance number, no spaces. If unknown, omit the field. Never send a placeholder.",
      "examples": [
        "AB123456C"
      ]
    },
    "mailingStreet": {
      "type": "string",
      "minLength": 1,
      "description": "Street. Must not be empty.",
      "examples": [
        "1 Main Street"
      ]
    },
    "mailingCity": {
      "type": "string",
      "minLength": 1,
      "description": "Town or city. Must not be empty.",
      "examples": [
        "Green City"
      ]
    },
    "mailingStateProvince": {
      "type": "string",
      "minLength": 1,
      "description": "County. Must not be empty.",
      "examples": [
        "Happy County"
      ]
    },
    "mailingPostalCode": {
      "type": "string",
      "pattern": "^(?:[Gg][Ii][Rr] 0[Aa]{2}|(?:[A-Za-z][0-9]{1,2}|[A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2}|[A-Za-z][0-9][A-Za-z]|[A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]) [0-9][A-Za-z]{2})$",
      "description": "Postcode. A valid UK postcode, with the single space between outward and inward parts. Trim before testing.",
      "examples": [
        "SW1A 1AA"
      ]
    },
    "mailingCountry": {
      "type": "string",
      "enum": [
        "United Kingdom"
      ],
      "description": "Country. Must be exactly \"United Kingdom\".",
      "examples": [
        "United Kingdom"
      ]
    },
    "startDate": {
      "type": "string",
      "format": "date",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Date this employment started. Employment periods for the same hrEmployeeId must not overlap.",
      "examples": [
        "2023-12-01"
      ]
    },
    "leaveDate": {
      "type": [
        "string",
        "null"
      ],
      "format": "date",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Date this employment ended. Omit or send null while employed. If set, must be on or after startDate."
    },
    "payBasis": {
      "type": "string",
      "enum": [
        "Hourly",
        "Salaried"
      ],
      "description": "How the employee is paid. Exactly one of the allowed values. Decides whether salary or rateOfPay is required.",
      "examples": [
        "Salaried"
      ]
    },
    "salary": {
      "type": "number",
      "description": "Annual salary. Annual figure.",
      "examples": [
        12000
      ]
    },
    "rateOfPay": {
      "type": "number",
      "description": "Hourly rate of pay. Rate per hour.",
      "examples": [
        15.25
      ]
    },
    "payEffectiveDate": {
      "type": "string",
      "format": "date",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Date the current salary or rate took effect. Between startDate and leaveDate inclusive. Must equal startDate when the employee is first created.",
      "examples": [
        "2023-12-01"
      ]
    },
    "payGroup": {
      "type": "string",
      "description": "Pay Group the employee is paid in. Must match the name of a Pay Group configured in PayCaptain.",
      "examples": [
        "Monthly"
      ]
    },
    "location": {
      "type": "string",
      "description": "Work location.",
      "examples": [
        "Baker Street"
      ]
    },
    "department": {
      "type": "string",
      "description": "Department.",
      "examples": [
        "Marketing"
      ]
    },
    "team": {
      "type": "string",
      "description": "Team.",
      "examples": [
        "Content"
      ]
    },
    "jobGrade": {
      "type": "string",
      "description": "Job grade.",
      "examples": [
        "A1"
      ]
    },
    "jobTitle": {
      "type": "string",
      "description": "Job title.",
      "examples": [
        "Content Marketing"
      ]
    },
    "jobEffectiveDate": {
      "type": "string",
      "format": "date",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Date the job title took effect.",
      "examples": [
        "2023-12-01"
      ]
    },
    "probationEndDate": {
      "type": "string",
      "format": "date",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Date the probation period ends.",
      "examples": [
        "2024-02-01"
      ]
    },
    "contractType": {
      "type": "string",
      "enum": [
        "Full Time",
        "Part Time"
      ],
      "description": "Contract type.",
      "examples": [
        "Full Time"
      ]
    },
    "normalWeeklyHours": {
      "type": "number",
      "minimum": 0,
      "description": "Normal weekly hours. Hours as a whole or decimal number (40 or 37.5). If your source system stores hundredths (4000), divide by 100 first.",
      "examples": [
        40
      ]
    },
    "daysWorkedPerWeek": {
      "type": "number",
      "minimum": 0,
      "maximum": 7,
      "description": "Working days per week.",
      "examples": [
        5
      ]
    },
    "monday": {
      "type": "boolean",
      "description": "Works on a Monday.",
      "examples": [
        true
      ]
    },
    "tuesday": {
      "type": "boolean",
      "description": "Works on a Tuesday.",
      "examples": [
        true
      ]
    },
    "wednesday": {
      "type": "boolean",
      "description": "Works on a Wednesday.",
      "examples": [
        true
      ]
    },
    "thrursday": {
      "type": "boolean",
      "description": "Works on a Thursday. The field name is spelled this way in API v1.0.1. Send it exactly as shown.",
      "examples": [
        true
      ]
    },
    "friday": {
      "type": "boolean",
      "description": "Works on a Friday.",
      "examples": [
        true
      ]
    },
    "saturday": {
      "type": "boolean",
      "description": "Works on a Saturday.",
      "examples": [
        false
      ]
    },
    "sunday": {
      "type": "boolean",
      "description": "Works on a Sunday.",
      "examples": [
        false
      ]
    },
    "bankName": {
      "type": "string",
      "description": "Name of the bank.",
      "examples": [
        "Monzo"
      ]
    },
    "bankAccountName": {
      "type": "string",
      "description": "Name on the account.",
      "examples": [
        "Jason Smith"
      ]
    },
    "bankAccountNumber": {
      "type": "string",
      "pattern": "^[0-9]{8}$",
      "description": "UK bank account number. Exactly 8 digits, sent as a string so leading zeros survive.",
      "examples": [
        "87654321"
      ]
    },
    "bankAccountSortCode": {
      "type": "string",
      "pattern": "^[0-9]{6}$",
      "description": "UK sort code. Exactly 6 digits, no hyphens, sent as a string so leading zeros survive.",
      "examples": [
        "123456"
      ]
    },
    "starterDeclaration": {
      "type": "string",
      "enum": [
        "A",
        "B",
        "C"
      ],
      "description": "HMRC starter declaration. Exactly one of the allowed values, per the HMRC starter checklist.",
      "examples": [
        "A"
      ]
    },
    "studentLoanPlanOne": {
      "type": "boolean",
      "default": false,
      "description": "Repays Student Loan Plan 1.",
      "examples": [
        false
      ]
    },
    "studentLoanPlanTwo": {
      "type": "boolean",
      "default": false,
      "description": "Repays Student Loan Plan 2.",
      "examples": [
        false
      ]
    },
    "studentLoanPlanFour": {
      "type": "boolean",
      "default": false,
      "description": "Repays Student Loan Plan 4.",
      "examples": [
        false
      ]
    },
    "studentLoanPostGraduate": {
      "type": "boolean",
      "default": false,
      "description": "Repays a Postgraduate Loan.",
      "examples": [
        false
      ]
    }
  },
  "required": [
    "company",
    "hrEmployeeId",
    "payrollCode",
    "firstName",
    "lastName",
    "dateOfBirth",
    "gender",
    "email",
    "mailingStreet",
    "mailingCity",
    "mailingStateProvince",
    "mailingPostalCode",
    "mailingCountry",
    "startDate",
    "payBasis",
    "payEffectiveDate",
    "payGroup"
  ],
  "allOf": [
    {
      "if": {
        "properties": {
          "payBasis": {
            "const": "Salaried"
          }
        },
        "required": [
          "payBasis"
        ]
      },
      "then": {
        "required": [
          "salary"
        ]
      }
    },
    {
      "if": {
        "properties": {
          "payBasis": {
            "const": "Hourly"
          }
        },
        "required": [
          "payBasis"
        ]
      },
      "then": {
        "required": [
          "rateOfPay"
        ]
      }
    }
  ]
}
