{"openapi":"3.1.0","info":{"title":"Sage HR (BYOK) API","version":"0.1.0","description":"Sage HR (BYOK) lets an AI assistant read your own Sage HR data through the Sage HR API with a key you supply (Sage HR API key (API access must be enabled by an admin)). Read-only: 11 tools (list_employees, get_employee, list_terminated_employees, list_teams, list_positions, list_time_off_policies, list_time_off_requests, get_time_off_balances, list_out_of_office_today, list_recruitment_positions,...\n\nEvery operation is read-only or compute-only. The same tools are available over MCP (streamable HTTP) at https://byok-sagehr.connectorbay.com/mcp.","contact":{"name":"Unify Dynamics LLC","email":"agent@connectorbay.com","url":"https://connectorbay.com/byok-sagehr/docs"},"termsOfService":"https://connectorbay.com/byok-sagehr/terms"},"servers":[{"url":"https://byok-sagehr.connectorbay.com"}],"externalDocs":{"url":"https://connectorbay.com/byok-sagehr/docs"},"security":[{"upstreamKey":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"Optional. A Pro API key raises rate limits; no credentials are required."},"upstreamKey":{"type":"apiKey","in":"header","name":"X-Upstream-Key","description":"Your own key for the service this connector wraps (bring your own key). Used for that one call only; never stored, logged or cached."}},"schemas":{"Error":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object"}}}}},"paths":{"/v1/tools/list_employees":{"post":{"operationId":"list_employees","summary":"List active employees with name, work email, employee number, start date, team, position, manager id and employment stat","description":"List active employees with name, work email, employee number, start date, team, position, manager id and employment status. Birth date, gender, address, phone and ID or tax numbers are left out. Use for \"Who are the active employees in Sage HR\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"subdomain":{"description":"Your Sage HR account subdomain: 'acme' for acme.sage.hr.","maxLength":63,"pattern":"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$","title":"Subdomain","type":"string"},"page":{"anyOf":[{"maximum":10000,"minimum":1,"type":"integer"},{"type":"null"}],"default":1,"description":"Page number, starting at 1.","title":"Page"}},"required":["subdomain"],"title":"list_employeesArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_employee":{"post":{"operationId":"get_employee","summary":"Get one active employee by id: name, work email, employee number, start date, team, position, manager id and employment ","description":"Get one active employee by id: name, work email, employee number, start date, team, position, manager id and employment status (no personal or ID data). Use for \"Show Sage HR employee 19\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"subdomain":{"description":"Your Sage HR account subdomain: 'acme' for acme.sage.hr.","maxLength":63,"pattern":"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$","title":"Subdomain","type":"string"},"id":{"description":"Employee id from list_employees.","maximum":999999999,"minimum":1,"title":"Id","type":"integer"},"team_history":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":null,"description":"True to include the employee's team history.","title":"Team History"},"position_history":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":null,"description":"True to include the position history.","title":"Position History"}},"required":["subdomain","id"],"title":"get_employeeArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_terminated_employees":{"post":{"operationId":"list_terminated_employees","summary":"List terminated employees with name, work email, employee number, team, position and employment status. Use for \"Who has","description":"List terminated employees with name, work email, employee number, team, position and employment status. Use for \"Who has left the company according to Sage HR\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"subdomain":{"description":"Your Sage HR account subdomain: 'acme' for acme.sage.hr.","maxLength":63,"pattern":"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$","title":"Subdomain","type":"string"},"page":{"anyOf":[{"maximum":10000,"minimum":1,"type":"integer"},{"type":"null"}],"default":1,"description":"Page number, starting at 1.","title":"Page"}},"required":["subdomain"],"title":"list_terminated_employeesArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_teams":{"post":{"operationId":"list_teams","summary":"List teams with their manager employee ids and member employee ids. Use for \"Which teams exist in Sage HR and who manage","description":"List teams with their manager employee ids and member employee ids. Use for \"Which teams exist in Sage HR and who manages them\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"subdomain":{"description":"Your Sage HR account subdomain: 'acme' for acme.sage.hr.","maxLength":63,"pattern":"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$","title":"Subdomain","type":"string"},"page":{"anyOf":[{"maximum":10000,"minimum":1,"type":"integer"},{"type":"null"}],"default":1,"description":"Page number, starting at 1.","title":"Page"}},"required":["subdomain"],"title":"list_teamsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_positions":{"post":{"operationId":"list_positions","summary":"List job positions of the company with title and code. Use for \"What job positions are defined in Sage HR\".","description":"List job positions of the company with title and code. Use for \"What job positions are defined in Sage HR\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"subdomain":{"description":"Your Sage HR account subdomain: 'acme' for acme.sage.hr.","maxLength":63,"pattern":"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$","title":"Subdomain","type":"string"},"page":{"anyOf":[{"maximum":10000,"minimum":1,"type":"integer"},{"type":"null"}],"default":1,"description":"Page number, starting at 1.","title":"Page"}},"required":["subdomain"],"title":"list_positionsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_time_off_policies":{"post":{"operationId":"list_time_off_policies","summary":"List time off policies with name, unit, default allowance, maximum carry-over and accrual type. Use for \"Which time off ","description":"List time off policies with name, unit, default allowance, maximum carry-over and accrual type. Use for \"Which time off policies does my company have in Sage HR\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"subdomain":{"description":"Your Sage HR account subdomain: 'acme' for acme.sage.hr.","maxLength":63,"pattern":"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$","title":"Subdomain","type":"string"}},"required":["subdomain"],"title":"list_time_off_policiesArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_time_off_requests":{"post":{"operationId":"list_time_off_requests","summary":"List time off requests in a date range with status, policy, employee, dates and hours. Free-text details are left out. U","description":"List time off requests in a date range with status, policy, employee, dates and hours. Free-text details are left out. Use for \"Which time off requests were made in June 2026\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"subdomain":{"description":"Your Sage HR account subdomain: 'acme' for acme.sage.hr.","maxLength":63,"pattern":"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$","title":"Subdomain","type":"string"},"page":{"anyOf":[{"maximum":10000,"minimum":1,"type":"integer"},{"type":"null"}],"default":1,"description":"Page number, starting at 1.","title":"Page"},"from_date":{"anyOf":[{"maxLength":10,"type":"string"},{"type":"null"}],"default":null,"description":"Only requests from this date, yyyy-mm-dd.","title":"From Date"},"to_date":{"anyOf":[{"maxLength":10,"type":"string"},{"type":"null"}],"default":null,"description":"Only requests up to this date, yyyy-mm-dd.","title":"To Date"}},"required":["subdomain"],"title":"list_time_off_requestsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_time_off_balances":{"post":{"operationId":"get_time_off_balances","summary":"Get one employee's time off balances per policy: days or hours used and available. Use for \"How much vacation does Sage ","description":"Get one employee's time off balances per policy: days or hours used and available. Use for \"How much vacation does Sage HR employee 19 have left\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"subdomain":{"description":"Your Sage HR account subdomain: 'acme' for acme.sage.hr.","maxLength":63,"pattern":"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$","title":"Subdomain","type":"string"},"id":{"description":"Employee id from list_employees.","maximum":999999999,"minimum":1,"title":"Id","type":"integer"}},"required":["subdomain","id"],"title":"get_time_off_balancesArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_out_of_office_today":{"post":{"operationId":"list_out_of_office_today","summary":"List employees who are on approved time off today, or on a given date, with policy name and dates. Use for \"Who is out o","description":"List employees who are on approved time off today, or on a given date, with policy name and dates. Use for \"Who is out of office today\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"subdomain":{"description":"Your Sage HR account subdomain: 'acme' for acme.sage.hr.","maxLength":63,"pattern":"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$","title":"Subdomain","type":"string"},"date":{"anyOf":[{"maxLength":10,"type":"string"},{"type":"null"}],"default":null,"description":"Date to check, yyyy-mm-dd (default today).","title":"Date"}},"required":["subdomain"],"title":"list_out_of_office_todayArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_recruitment_positions":{"post":{"operationId":"list_recruitment_positions","summary":"List recruiting positions with status, team, location, applicant counts and employment type (no applicant details). Use ","description":"List recruiting positions with status, team, location, applicant counts and employment type (no applicant details). Use for \"Which positions are we recruiting for in Sage HR\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"subdomain":{"description":"Your Sage HR account subdomain: 'acme' for acme.sage.hr.","maxLength":63,"pattern":"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$","title":"Subdomain","type":"string"},"status":{"anyOf":[{"enum":["draft","published","internal","completed","cancelled"],"type":"string"},{"type":"null"}],"default":null,"description":"Position status.","title":"Status"},"page":{"anyOf":[{"maximum":10000,"minimum":1,"type":"integer"},{"type":"null"}],"default":1,"description":"Page number, starting at 1.","title":"Page"},"per_page":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":null,"description":"How many results per page (the documented default is 20 or 50 depending on the endpoint).","title":"Per Page"}},"required":["subdomain"],"title":"list_recruitment_positionsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_recruitment_position":{"post":{"operationId":"get_recruitment_position","summary":"Get one recruiting position by id with status, team, location, applicant counts, employment type and the hiring team. Us","description":"Get one recruiting position by id with status, team, location, applicant counts, employment type and the hiring team. Use for \"Show Sage HR recruiting position 1\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"subdomain":{"description":"Your Sage HR account subdomain: 'acme' for acme.sage.hr.","maxLength":63,"pattern":"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$","title":"Subdomain","type":"string"},"id":{"description":"Recruitment position id from list_recruitment_positions.","maximum":999999999,"minimum":1,"title":"Id","type":"integer"}},"required":["subdomain","id"],"title":"get_recruitment_positionArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}}}}