{
  "info": {
    "_postman_id": "nannykeeper-api-v1",
    "name": "NannyKeeper API v1",
    "description": "Household employer tax compliance API. All 50 US states + DC. Covers federal income tax, Social Security, Medicare, FUTA, state income tax, SUTA, SDI, PFL, and local taxes.\n\nBase URL: {{base_url}}/api/v1\nAuth: Bearer {{api_key}}\n\nGet a free API key at https://www.nannykeeper.com/developers/keys",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "variable": [
    {
      "key": "base_url",
      "value": "https://www.nannykeeper.com",
      "type": "string"
    },
    {
      "key": "api_key",
      "value": "nk_live_your_api_key_here",
      "type": "string"
    },
    {
      "key": "employer_id",
      "value": "00000000-0000-0000-0000-000000000000",
      "type": "string"
    },
    {
      "key": "employee_id",
      "value": "00000000-0000-0000-0000-000000000000",
      "type": "string"
    },
    {
      "key": "payroll_id",
      "value": "00000000-0000-0000-0000-000000000000",
      "type": "string"
    }
  ],
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{api_key}}",
        "type": "string"
      }
    ]
  },
  "item": [
    {
      "name": "Calculator",
      "description": "Tax calculation and threshold checks. Free tier: 50 req/day. No subscription required.",
      "item": [
        {
          "name": "Calculate taxes",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{api_key}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/calculate",
              "host": ["{{base_url}}"],
              "path": ["api", "v1", "calculate"]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"state\": \"CA\",\n  \"annual_wages\": 35000,\n  \"pay_frequency\": \"biweekly\",\n  \"filing_status\": \"single\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Calculate household employer taxes for a single pay period. Returns full federal and state tax breakdown, per-paycheck amounts, and threshold status. Covers all 50 US states + DC.\n\n**Required fields:**\n- `state` — 2-letter US state code (e.g. `CA`, `NY`, `TX`)\n- `annual_wages` — annual gross wages in USD (0–999,999)\n\n**Optional fields:**\n- `pay_frequency` — `weekly`, `biweekly` (default), `semimonthly`, `monthly`\n- `filing_status` — `single` (default), `married`, `head_of_household`"
          },
          "response": []
        },
        {
          "name": "Check threshold",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{api_key}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/threshold?state=CA&annual_wages=35000&tax_year=2026",
              "host": ["{{base_url}}"],
              "path": ["api", "v1", "threshold"],
              "query": [
                {
                  "key": "state",
                  "value": "CA",
                  "description": "2-letter US state code (required)"
                },
                {
                  "key": "annual_wages",
                  "value": "35000",
                  "description": "Annual gross wages in USD (required)"
                },
                {
                  "key": "tax_year",
                  "value": "2026",
                  "description": "Tax year to check thresholds for (optional, defaults to current year)"
                }
              ]
            },
            "description": "Check whether wages cross the household employer tax threshold. Returns FICA threshold status ($3,000/year in 2026) and FUTA threshold status ($1,000/quarter aggregate). Also includes any applicable state-level thresholds.\n\nFICA threshold triggers Social Security (6.2%) and Medicare (1.45%) obligations for both employer and employee."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Employers",
      "description": "List and create employer accounts under your organization. Requires Professional tier and multi_employer scope.",
      "item": [
        {
          "name": "List employers",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{api_key}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/employers",
              "host": ["{{base_url}}"],
              "path": ["api", "v1", "employers"]
            },
            "description": "List all employer accounts accessible to the API key. Returns id, first_name, last_name, email, state, is_primary, ein_status, and created_at for each employer.\n\nScope required: `multi_employer`\nTier required: Professional"
          },
          "response": []
        },
        {
          "name": "Create employer",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{api_key}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/employers",
              "host": ["{{base_url}}"],
              "path": ["api", "v1", "employers"]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"first_name\": \"Jane\",\n  \"last_name\": \"Smith\",\n  \"email\": \"jane.smith@example.com\",\n  \"state\": \"CA\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Create a new employer account under the organization. The new employer is linked to the same organization as the API key holder.\n\n**Required fields:**\n- `first_name` — Employer first name\n- `last_name` — Employer last name\n- `email` — Employer email address\n- `state` — 2-letter US state code for the employer's primary state\n\n**Response includes:** id, first_name, last_name, email, state, is_primary, organization_id, created_at\n\nScope required: `multi_employer`\nTier required: Professional"
          },
          "response": []
        }
      ]
    },
    {
      "name": "Employees",
      "description": "Create and manage household employees. SSN and bank details must be entered through the secure employee portal (use the invite endpoint to send a magic link). Requires Starter+ subscription.",
      "item": [
        {
          "name": "List employees",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{api_key}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/employees?employer_id={{employer_id}}&limit=25",
              "host": ["{{base_url}}"],
              "path": ["api", "v1", "employees"],
              "query": [
                {
                  "key": "employer_id",
                  "value": "{{employer_id}}",
                  "description": "Employer UUID (required)"
                },
                {
                  "key": "cursor",
                  "value": "",
                  "description": "Pagination cursor from previous response (optional)",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "25",
                  "description": "Results per page, 1–100 (optional, default 25)"
                }
              ]
            },
            "description": "List all employees for an employer. Uses cursor-based pagination. Returns PII-safe fields — no raw SSN or bank numbers.\n\nScope required: `employees`"
          },
          "response": []
        },
        {
          "name": "Create employee",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{api_key}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/employees",
              "host": ["{{base_url}}"],
              "path": ["api", "v1", "employees"]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"employer_id\": \"{{employer_id}}\",\n  \"first_name\": \"Maria\",\n  \"last_name\": \"Garcia\",\n  \"email\": \"maria.garcia@example.com\",\n  \"start_date\": \"2026-01-06\",\n  \"pay_type\": \"hourly\",\n  \"pay_rate\": 25.00,\n  \"pay_frequency\": \"biweekly\",\n  \"work_state\": \"CA\",\n  \"resident_state\": \"CA\",\n  \"overtime_eligible\": true\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Create a new household employee. SSN and bank account details cannot be set through the API — use `POST /employees/:id/invite` to send the employee a secure magic link to enter that information themselves.\n\n**Required fields:** `employer_id`, `first_name`, `last_name`, `start_date`, `pay_type`, `pay_rate`, `pay_frequency`, `work_state`\n\n**Optional fields:** `middle_name`, `email`, `phone`, `resident_state`, `relationship` (`none`, `spouse`, `child_under_21`, `parent`), `overtime_eligible`\n\nScope required: `employees`"
          },
          "response": []
        },
        {
          "name": "Get employee",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{api_key}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/employees/{{employee_id}}",
              "host": ["{{base_url}}"],
              "path": ["api", "v1", "employees", "{{employee_id}}"]
            },
            "description": "Retrieve a specific employee by ID. Returns PII-safe fields — no raw SSN or bank numbers.\n\nScope required: `employees`"
          },
          "response": []
        },
        {
          "name": "Get employee setup status",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{api_key}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/employees/{{employee_id}}/setup-status",
              "host": ["{{base_url}}"],
              "path": ["api", "v1", "employees", "{{employee_id}}", "setup-status"]
            },
            "description": "Get the onboarding completeness status for an employee. Shows which steps are complete (SSN on file, W-4 elections, home address, bank account) and what is still missing. Use this to know when an employee is ready for direct deposit.\n\nScope required: `employees`"
          },
          "response": []
        },
        {
          "name": "Update employee address",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{api_key}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/employees/{{employee_id}}/address",
              "host": ["{{base_url}}"],
              "path": ["api", "v1", "employees", "{{employee_id}}", "address"]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"line1\": \"123 Main St\",\n  \"line2\": \"Apt 4B\",\n  \"city\": \"Los Angeles\",\n  \"state\": \"CA\",\n  \"zip\": \"90001\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Update the home address for an employee. Employer-side entry — allows CPAs and integrators to set address directly via API without requiring the employee to use the portal.\n\n**Required fields:** `line1`, `city`, `state`, `zip` (5-digit or ZIP+4 format)\n**Optional fields:** `line2`\n\nScope required: `employees`"
          },
          "response": []
        },
        {
          "name": "Update employee W-4",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{api_key}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/employees/{{employee_id}}/w4",
              "host": ["{{base_url}}"],
              "path": ["api", "v1", "employees", "{{employee_id}}", "w4"]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"filing_status\": \"single\",\n  \"multiple_jobs\": false,\n  \"dependents_amount\": 0,\n  \"other_income\": 0,\n  \"deductions\": 0,\n  \"extra_withholding\": 0,\n  \"exempt\": false\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Update W-4 federal withholding elections for an employee. Employer-side entry — allows CPAs and integrators to set W-4 data directly without the employee portal. SSN and bank details still require the secure employee portal.\n\n**Required fields:** `filing_status` (`single`, `married`, `head_of_household`)\n**Optional fields:** `multiple_jobs`, `dependents_amount`, `other_income`, `deductions`, `extra_withholding`, `exempt`\n\nScope required: `employees`"
          },
          "response": []
        },
        {
          "name": "Send employee portal invite",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{api_key}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/employees/{{employee_id}}/invite",
              "host": ["{{base_url}}"],
              "path": ["api", "v1", "employees", "{{employee_id}}", "invite"]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"tax_info\",\n  \"send_email\": true\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Send an employee a secure magic link to enter sensitive information through the employee portal. Used to collect SSN (required for W-2) or bank account details (required for direct deposit). The link is single-use and expires after 7 days.\n\n**`type`:** `tax_info` (SSN, W-4, address) or `bank_account`\n**`send_email`:** Send the invite email to the employee (default `true`). Set to `false` to get the portal URL without emailing.\n\nScope required: `employees`"
          },
          "response": []
        }
      ]
    },
    {
      "name": "Payroll",
      "description": "Run payroll, list payroll history, and retrieve payroll details. Requires Starter+ subscription and payroll scope.",
      "item": [
        {
          "name": "Run payroll",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{api_key}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/payroll/run",
              "host": ["{{base_url}}"],
              "path": ["api", "v1", "payroll", "run"]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"employer_id\": \"{{employer_id}}\",\n  \"pay_period_start\": \"2026-03-16\",\n  \"pay_period_end\": \"2026-03-29\",\n  \"pay_date\": \"2026-04-03\",\n  \"pay_frequency\": \"biweekly\",\n  \"employees\": [\n    {\n      \"employee_id\": \"{{employee_id}}\",\n      \"regular_hours\": 80,\n      \"overtime_hours\": 0,\n      \"bonus\": 0,\n      \"payment_method\": \"direct_deposit\"\n    }\n  ],\n  \"notes\": \"Regular biweekly pay\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Run payroll for one or more employees with YTD tracking. Calculates all federal and state taxes based on employee W-4 elections and YTD wages. Returns a payroll record with per-employee tax breakdowns.\n\n**Required fields:** `employer_id`, `pay_period_start`, `pay_period_end`, `pay_date`, `pay_frequency`, `employees`\n\n**Per-employee fields:**\n- `employee_id` (required)\n- `regular_hours`, `overtime_hours`, `bonus`, `other_earnings` (optional)\n- `payment_method`: `direct_deposit`, `check`, `cash` (optional)\n- `reimbursements`: array of `{type, amount, description}` (optional)\n\nScope required: `payroll`"
          },
          "response": []
        },
        {
          "name": "List payrolls",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{api_key}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/payrolls?employer_id={{employer_id}}&limit=25",
              "host": ["{{base_url}}"],
              "path": ["api", "v1", "payrolls"],
              "query": [
                {
                  "key": "employer_id",
                  "value": "{{employer_id}}",
                  "description": "Employer UUID (required)"
                },
                {
                  "key": "cursor",
                  "value": "",
                  "description": "Pagination cursor from previous response (optional)",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "25",
                  "description": "Results per page, 1–100 (optional, default 25)"
                }
              ]
            },
            "description": "List payroll records for an employer, ordered by pay date descending. Uses cursor-based pagination.\n\nScope required: `payroll`"
          },
          "response": []
        },
        {
          "name": "Get payroll",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{api_key}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/payroll/{{payroll_id}}",
              "host": ["{{base_url}}"],
              "path": ["api", "v1", "payroll", "{{payroll_id}}"]
            },
            "description": "Retrieve a specific payroll by ID including all employee line items with full tax breakdowns.\n\nScope required: `payroll`"
          },
          "response": []
        }
      ]
    },
    {
      "name": "Documents",
      "description": "Generate PDF documents: pay stubs, W-2s, and Schedule H. Returns PDF binary. Requires Starter+ subscription.",
      "item": [
        {
          "name": "Generate pay stub",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{api_key}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/documents/paystub",
              "host": ["{{base_url}}"],
              "path": ["api", "v1", "documents", "paystub"]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"employer_id\": \"{{employer_id}}\",\n  \"payroll_id\": \"{{payroll_id}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Generate a PDF pay stub for a completed payroll. Returns the PDF binary with `Content-Type: application/pdf`.\n\n**Required fields:** `employer_id`, `payroll_id`\n\nScope required: `documents`"
          },
          "response": []
        },
        {
          "name": "Generate W-2",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{api_key}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/documents/w2",
              "host": ["{{base_url}}"],
              "path": ["api", "v1", "documents", "w2"]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"employer_id\": \"{{employer_id}}\",\n  \"employee_id\": \"{{employee_id}}\",\n  \"tax_year\": 2025\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Generate a W-2 PDF for an employee for a given tax year. Employee must have SSN on file (entered via the employee portal). Returns the PDF binary with `Content-Type: application/pdf`.\n\n**Required fields:** `employer_id`, `employee_id`, `tax_year` (2024–2030)\n\nNote: NannyKeeper generates W-2 PDFs for employer filing. E-filing to SSA is not supported — employers upload to the SSA Business Services Online (BSO) portal.\n\nScope required: `documents`"
          },
          "response": []
        },
        {
          "name": "Generate Schedule H",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{api_key}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/documents/schedule-h",
              "host": ["{{base_url}}"],
              "path": ["api", "v1", "documents", "schedule-h"]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"employer_id\": \"{{employer_id}}\",\n  \"tax_year\": 2025\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Generate a Schedule H (Household Employment Taxes) PDF for filing with the employer's personal Form 1040. Aggregates all household employees for the tax year. Returns the PDF binary with `Content-Type: application/pdf`.\n\n**Required fields:** `employer_id`, `tax_year` (2024–2030)\n\nScope required: `documents`"
          },
          "response": []
        }
      ]
    },
    {
      "name": "ACH",
      "description": "Direct deposit via Stripe ACH. Requires Plus+ subscription and ach scope. Fee: $6/transfer (Plus), $8/transfer (Starter with DD add-on). Use an Idempotency-Key header to prevent duplicate transfers.",
      "item": [
        {
          "name": "Initiate ACH transfer",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{api_key}}"
              },
              {
                "key": "Idempotency-Key",
                "value": "payroll-{{payroll_id}}-transfer-v1",
                "description": "Recommended: prevents duplicate transfers on retry"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/ach/transfer",
              "host": ["{{base_url}}"],
              "path": ["api", "v1", "ach", "transfer"]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"employer_id\": \"{{employer_id}}\",\n  \"payroll_id\": \"{{payroll_id}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Initiate a direct deposit ACH transfer for a completed payroll run. The employer must have a connected bank account and all employees receiving direct deposit must have bank accounts on file (set up via the employee portal).\n\n**Required fields:** `employer_id`, `payroll_id`\n\n**Idempotency:** Include an `Idempotency-Key` header to safely retry on network failures without risk of double-sending.\n\n**Fees:** $6/transfer on Plus plan, $8/transfer on Starter plan.\n\nScope required: `ach`"
          },
          "response": []
        }
      ]
    },
    {
      "name": "Setup",
      "description": "Employer onboarding helpers. Generate hosted URLs for bank connection and check direct deposit readiness.",
      "item": [
        {
          "name": "Generate bank setup URL",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{api_key}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/setup/bank",
              "host": ["{{base_url}}"],
              "path": ["api", "v1", "setup", "bank"]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"employer_id\": \"{{employer_id}}\",\n  \"return_url\": \"https://your-app.example.com/onboarding/complete\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Generate a hosted bank connection URL for an employer. The employer visits this URL to connect their bank account via Stripe Financial Connections. After completion, the user is redirected to `return_url`.\n\nRequired for direct deposit. Only needs to be done once per employer.\n\n**Required fields:** `employer_id`\n**Optional fields:** `return_url` — where to redirect after bank connection is complete\n\nScope required: `payroll`"
          },
          "response": []
        },
        {
          "name": "Get direct deposit status",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{api_key}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/v1/employers/{{employer_id}}/dd-status",
              "host": ["{{base_url}}"],
              "path": ["api", "v1", "employers", "{{employer_id}}", "dd-status"]
            },
            "description": "Check direct deposit readiness for an employer and all their employees. Returns what is blocking DD for each party: employer bank account, employee bank account, employee SSN, and employee W-4 elections.\n\nUse this to show users exactly what steps remain before their first direct deposit can be processed.\n\nScope required: `payroll`"
          },
          "response": []
        }
      ]
    }
  ]
}
