{
  "openapi": "3.1.0",
  "info": {
    "title": "NannyKeeper API",
    "description": "REST API for calculating US household employer (nanny) taxes. All 50 states + DC.",
    "version": "1.0.0",
    "contact": {
      "name": "NannyKeeper",
      "url": "https://www.nannykeeper.com/developers",
      "email": "hello@nannykeeper.com"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://www.nannykeeper.com/terms"
    }
  },
  "servers": [
    {
      "url": "https://www.nannykeeper.com/api/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key (nk_live_xxx). Get one at nannykeeper.com/developers/keys"
      }
    }
  },
  "paths": {
    "/calculate": {
      "post": {
        "summary": "Calculate taxes",
        "description": "Calculate household employer taxes for a single pay period. All 50 US states + DC.",
        "tags": ["Calculator"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["state", "annual_wages"],
                "properties": {
                  "state": { "type": "string", "description": "2-letter US state code", "example": "CA" },
                  "annual_wages": { "type": "number", "description": "Annual wages (0-999,999)", "example": 35000 },
                  "pay_frequency": { "type": "string", "enum": ["weekly", "biweekly", "semimonthly", "monthly"], "default": "biweekly" },
                  "filing_status": { "type": "string", "enum": ["single", "married", "head_of_household"], "default": "single" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Tax calculation result" },
          "400": { "description": "Validation error" },
          "401": { "description": "API key required" },
          "429": { "description": "Rate limit exceeded" }
        }
      }
    },
    "/threshold": {
      "get": {
        "summary": "Check threshold",
        "description": "Check if wages cross the household employer tax threshold ($3,000 for 2026).",
        "tags": ["Calculator"],
        "parameters": [
          { "name": "state", "in": "query", "required": true, "schema": { "type": "string" } },
          { "name": "annual_wages", "in": "query", "required": true, "schema": { "type": "number" } },
          { "name": "tax_year", "in": "query", "required": false, "schema": { "type": "integer" } }
        ],
        "responses": {
          "200": { "description": "Threshold status" },
          "401": { "description": "API key required" }
        }
      }
    },
    "/payroll/run": {
      "post": {
        "summary": "Run payroll",
        "description": "Run payroll for one or more employees with YTD tracking. Requires Starter+ subscription.",
        "tags": ["Payroll"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["employer_id", "pay_period_start", "pay_period_end", "pay_date", "pay_frequency", "employees"],
                "properties": {
                  "employer_id": { "type": "string", "format": "uuid" },
                  "pay_period_start": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" },
                  "pay_period_end": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" },
                  "pay_date": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" },
                  "pay_frequency": { "type": "string", "enum": ["weekly", "biweekly", "semimonthly", "monthly"] },
                  "employees": { "type": "array", "items": { "type": "object" } }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Payroll result" },
          "403": { "description": "Subscription required" }
        }
      }
    },
    "/employers": {
      "get": {
        "summary": "List employers",
        "description": "List all employer accounts accessible to the API key. Requires Professional tier and multi_employer scope.",
        "tags": ["Employers"],
        "responses": {
          "200": {
            "description": "Employer list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": { "type": "string", "format": "uuid" },
                          "first_name": { "type": "string" },
                          "last_name": { "type": "string" },
                          "email": { "type": "string", "format": "email" },
                          "state": { "type": "string", "description": "2-letter US state code" },
                          "is_primary": { "type": "boolean", "description": "Whether this is the primary employer account" },
                          "ein_status": { "type": "string", "enum": ["none", "pending", "approved"], "description": "EIN application status" },
                          "created_at": { "type": "string", "format": "date-time" }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": { "description": "API key required" },
          "403": { "description": "Professional tier and multi_employer scope required" }
        }
      },
      "post": {
        "summary": "Create employer",
        "description": "Create a new employer account under the organization. Requires Professional tier and multi_employer scope.",
        "tags": ["Employers"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["first_name", "last_name", "email", "state"],
                "properties": {
                  "first_name": { "type": "string", "description": "Employer first name", "example": "Jane" },
                  "last_name": { "type": "string", "description": "Employer last name", "example": "Smith" },
                  "email": { "type": "string", "format": "email", "description": "Employer email address", "example": "jane.smith@example.com" },
                  "state": { "type": "string", "description": "2-letter US state code for the employer's primary state", "example": "CA" }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Employer created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": { "type": "string", "format": "uuid" },
                    "first_name": { "type": "string" },
                    "last_name": { "type": "string" },
                    "email": { "type": "string", "format": "email" },
                    "state": { "type": "string" },
                    "is_primary": { "type": "boolean" },
                    "organization_id": { "type": "string", "format": "uuid", "description": "Organization this employer belongs to" },
                    "created_at": { "type": "string", "format": "date-time" }
                  }
                }
              }
            }
          },
          "400": { "description": "Validation error" },
          "401": { "description": "API key required" },
          "403": { "description": "Professional tier and multi_employer scope required" }
        }
      }
    },
    "/employees": {
      "get": {
        "summary": "List employees",
        "description": "List employees for an employer. Cursor-based pagination.",
        "tags": ["Employees"],
        "parameters": [
          { "name": "employer_id", "in": "query", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "name": "cursor", "in": "query", "schema": { "type": "string" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100 } }
        ],
        "responses": { "200": { "description": "Employee list" } }
      },
      "post": {
        "summary": "Create employee",
        "description": "Create a new employee. SSN and bank must be entered via secure portal.",
        "tags": ["Employees"],
        "responses": { "201": { "description": "Employee created" } }
      }
    },
    "/documents/paystub": {
      "post": {
        "summary": "Generate pay stub",
        "tags": ["Documents"],
        "responses": { "200": { "description": "Pay stub PDF" } }
      }
    },
    "/documents/w2": {
      "post": {
        "summary": "Generate W-2",
        "tags": ["Documents"],
        "responses": { "200": { "description": "W-2 PDF" } }
      }
    },
    "/documents/schedule-h": {
      "post": {
        "summary": "Generate Schedule H",
        "tags": ["Documents"],
        "responses": { "200": { "description": "Schedule H PDF" } }
      }
    },
    "/ach/transfer": {
      "post": {
        "summary": "Initiate DD transfer",
        "description": "Initiate direct deposit ACH transfer. DD fee charged per tier.",
        "tags": ["ACH"],
        "responses": { "201": { "description": "Transfer initiated" } }
      }
    }
  }
}
