Prompt Details
Model
(claude-4-5-sonnet)
Token size
802
Example input
[API_PURPOSE]: Manage employee records, attendance, and payroll data.
[API_TYPE]: REST
[CONSUMERS]: HR web portal and internal mobile app.
[TECHNICAL_REQUIREMENTS]: Authentication with JWT, HTTPS-only, response time under 500ms.
Example output
# HR Management REST API Design
## Executive Summary
A secure, performant REST API enabling HR operations through intuitive resource modeling. Designed for internal consumption by web and mobile clients with <500ms response times, JWT authentication, and comprehensive audit trails.
---
## 1. API Architecture & Rationale
### Architecture Selection: REST
**Rationale for HR domain:**
- **Resource-centric model** naturally maps to HR entities (employees, attendance, payroll)
- **Stateless operations** align with CRUD-heavy HR workflows
- **HTTP semantics** provide intuitive verb mapping (GET/POST/PUT/DELETE)
- **Wide tooling support** for internal teams (no specialized client libraries needed)
- **Caching capabilities** via standard HTTP headers for frequently-accessed employee data
- **Proven pattern** for internal enterprise APIs with predictable latency requirements
**Performance characteristics:**
- HTTP/2 for multiplexing reduces connection overhead
- JSON payload compression (gzip/brotli)
- Response streaming for large dataset exports
- Client-side caching via ETags for employee profile data
---
## 2. Resource Model
### Domain Entity Design
```
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β Employee ββββββββ Attendance β β Payroll β
β (Core) β 1:N β (Time) β β (Finance) β
βββββββββββββββββββ€ ββββββββββββββββββββ€ βββββββββββββββββββ€
β id β β id β β id β
β employee_number β β employee_id (FK) β β employee_id (FK)β
β first_name β β date β β period_start β
β last_name β β clock_in β β period_end β
β email β β clock_out β β gross_pay β
β department β β status β β deductions β
β position β β notes β β net_pay β
β hire_date β β approved_by β β payment_status β
β employment_type β β created_at β β payment_date β
β status β β updated_at β β created_at β
β created_at β ββββββββββββββββββββ β updated_at β
β updated_at β β approved_by β
βββββββββββββββββββ βββββββββββββββββββ
β
β 1:N
βΌ
βββββββββββββββββββ
β Department β
β (Reference) β
βββββββββββββββββββ€
β id β
β name β
β code β
β manager_id β
β cost_center β
βββββββββββββββββββ
```
### Naming Conventions
- **Resources:** Plural nouns (`/employees`, `/attendance-records`, `/payroll-records`)
- **Attributes:** Snake_case (`employee_number`, `clock_in`, `period_start`)
- **Collections:** Paginated by default, max 100 items per page
- **Timestamps:** ISO 8601 UTC (`2025-10-18T14:30:00Z`)
- **IDs:** UUIDv4 for global uniqueness, opaque to clients
---
## 3. Complete API Specification
### Base URL
```
https://api.hr-system.company.internal/v1
```
### Resource Endpoints
#### **EMPLOYEES** (`/employees`)
##### List Employees
```http
GET /v1/employees?page=1&per_page=50&department=engineering&status=active&sort=-hire_date
Authorization: Bearer {jwt_token}
```
**Query Parameters:**
- `page` (integer, default: 1): Page number
- `per_page` (integer, default: 50, max: 100): Items per page
- `department` (string): Filter by department ID/code
- `status` (enum: active|on_leave|terminated): Employment status
- `search` (string): Full-text search across name, email, employee_number
- `sort` (string): Field to sort by (prefix `-` for descending)
**Response (200 OK):**
```json
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"employee_number": "EMP001234",
"first_name": "Sarah",
"last_name": "Johnson",
"email": "sarah.johnson@company.com",
"department": {
"id": "dept-001",
"name": "Engineering",
"code": "ENG"
},
"position": "Senior Software Engineer",
"hire_date": "2022-03-15",
"employment_type": "full_time",
"status": "active",
"created_at": "2022-03-10T09:00:00Z",
"updated_at": "2025-10-15T14:22:00Z"
}
],
"pagination": {
"page": 1,
"per_page": 50,
"total_items": 243,
"total_pages": 5,
"has_next": true,
"has_previous": false
},
"links": {
"self": "/v1/employees?page=1&per_page=50",
"next": "/v1/employees?page=2&per_page=50",
"first": "/v1/employees?page=1&per_page=50",
"last": "/v1/employees?page=5&per_page=50"
}
}
```
##### Get Single Employee
```http
GET /v1/employees/{employee_id}
Authorization: Bearer {jwt_token}
```
**Response (200 OK):**
```json
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"employee_number": "EMP001234",
"first_name": "Sarah",
"last_name": "Johnson",
"email": "sarah.johnson@company.com",
"phone": "+1-555-0123",
"department": {
"id": "dept-001",
"name": "Engineering",
"code": "ENG",
"manager": {
"id": "550e8400-e29b-41d4-a716-446655440099",
"name": "John Smith"
}
},
"position": "Senior Software Engineer",
"hire_date": "2022-03-15",
"employment_type": "full_time",
"status": "active",
"salary_grade": "L5",
"emergency_contact": {
"name": "Michael Johnson",
"relationship": "Spouse",
"phone": "+1-555-0124"
},
"created_at": "2022-03-10T09:00:00Z",
"updated_at": "2025-10-15T14:22:00Z"
}
}
```
##### Create Employee
```http
POST /v1/employees
Authorization: Bearer {jwt_token}
Content-Type: application/json
```
**Request Body:**
```json
{
"employee_number": "EMP001500",
"first_name": "Alex",
"last_name": "Martinez",
"email": "alex.martinez@company.com",
"phone": "+1-555-0199",
"department_id": "dept-002",
"position": "Product Designer",
"hire_date": "2025-11-01",
"employment_type": "full_time",
"salary_grade": "L3"
}
```
**Response (201 Created):**
```json
{
"data": {
"id": "660e8400-e29b-41d4-a716-446655440111",
"employee_number": "EMP001500",
"first_name": "Alex",
"last_name": "Martinez",
"email": "alex.martinez@company.com",
"status": "active",
"created_at": "2025-10-18T15:30:00Z",
"updated_at": "2025-10-18T15:30:00Z"
}
}
```
##### Update Employee
```http
PUT /v1/employees/{employee_id}
Authorization: Bearer {jwt_token}
Content-Type: application/json
```
**Request Body (partial updates supported):**
```json
{
"position": "Lead Product Designer",
"salary_grade": "L4",
"department_id": "dept-003"
}
```
**Response (200 OK):** Returns full employee object with updated fields.
##### Terminate Employment
```http
POST /v1/employees/{employee_id}/terminate
Authorization: Bearer {jwt_token}
Content-Type: application/json
```
**Request Body:**
```json
{
"termination_date": "2025-10-31",
"reason": "resignation",
"notes": "Pursuing graduate studies"
}
```
**Response (200 OK):**
```json
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "terminated",
"termination_date": "2025-10-31",
"updated_at": "2025-10-18T15:45:00Z"
}
}
```
---
#### **ATTENDANCE** (`/attendance-records`)
##### List Attendance Records
```http
GET /v1/attendance-records?employee_id={id}&start_date=2025-10-01&end_date=2025-10-18&status=approved
Authorization: Bearer {jwt_token}
```
**Query Parameters:**
- `employee_id` (uuid, required): Employee identifier
- `start_date` (date, required): Period start (YYYY-MM-DD)
- `end_date` (date, required): Period end (YYYY-MM-DD)
- `status` (enum: pending|approved|rejected): Approval status
- `page`, `per_page`: Pagination
**Response (200 OK):**
```json
{
"data": [
{
"id": "770e8400-e29b-41d4-a716-446655440222",
"employee_id": "550e8400-e29b-41d4-a716-446655440000",
"date": "2025-10-17",
"clock_in": "2025-10-17T09:02:00Z",
"clock_out": "2025-10-17T17:35:00Z",
"total_hours": 8.55,
"status": "approved",
"notes": null,
"approved_by": {
"id": "550e8400-e29b-41d4-a716-446655440099",
"name": "John Smith"
},
"approved_at": "2025-10-17T18:00:00Z",
"created_at": "2025-10-17T09:02:15Z",
"updated_at": "2025-10-17T18:00:00Z"
}
],
"summary": {
"total_days": 12,
"total_hours": 98.5,
"average_hours_per_day": 8.21
},
"pagination": { ... }
}
```
##### Clock In
```http
POST /v1/attendance-records/clock-in
Authorization: Bearer {jwt_token}
Content-Type: application/json
```
**Request Body:**
```json
{
"employee_id": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2025-10-18T09:00:00Z",
"location": {
"latitude": 37.7749,
"longitude": -122.4194
}
}
```
**Response (201 Created):**
```json
{
"data": {
"id": "880e8400-e29b-41d4-a716-446655440333",
"employee_id": "550e8400-e29b-41d4-a716-446655440000",
"date": "2025-10-18",
"clock_in": "2025-10-18T09:00:00Z",
"status": "pending",
"created_at": "2025-10-18T09:00:05Z"
}
}
```
##### Clock Out
```http
POST /v1/attendance-records/{record_id}/clock-out
Authorization: Bearer {jwt_token}
Content-Type: application/json
```
**Request Body:**
```json
{
"timestamp": "2025-10-18T17:30:00Z"
}
```
**Response (200 OK):**
```json
{
"data": {
"id": "880e8400-e29b-41d4-a716-446655440333",
"clock_out": "2025-10-18T17:30:00Z",
"total_hours": 8.5,
"updated_at": "2025-10-18T17:30:05Z"
}
}
```
##### Approve Attendance
```http
POST /v1/attendance-records/{record_id}/approve
Authorization: Bearer {jwt_token}
Content-Type: application/json
```
**Request Body:**
```json
{
"notes": "Approved - standard workday"
}
```
**Response (200 OK):**
```json
{
"data": {
"id": "880e8400-e29b-41d4-a716-446655440333",
"status": "approved",
"approved_by": "550e8400-e29b-41d4-a716-446655440099",
"approved_at": "2025-10-18T18:00:00Z"
}
}
```
---
#### **PAYROLL** (`/payroll-records`)
##### List Payroll Records
```http
GET /v1/payroll-records?employee_id={id}&year=2025&status=paid
Authorization: Bearer {jwt_token}
```
**Query Parameters:**
- `employee_id` (uuid): Filter by employee
- `year` (integer): Fiscal year
- `period_start` (date): Period start date
- `period_end` (date): Period end date
- `status` (enum: draft|pending_approval|approved|paid): Payment status
- `page`, `per_page`: Pagination
**Response (200 OK):**
```json
{
"data": [
{
"id": "990e8400-e29b-41d4-a716-446655440444",
"employee_id": "550e8400-e29b-41d4-a716-446655440000",
"period_start": "2025-10-01",
"period_end": "2025-10-15",
"gross_pay": 5000.00,
"deductions": {
"tax": 1000.00,
"insurance": 250.00,
"retirement": 300.00
},
"net_pay": 3450.00,
"payment_status": "paid",
"payment_date": "2025-10-20",
"payment_method": "direct_deposit",
"approved_by": {
"id": "550e8400-e29b-41d4-a716-446655440099",
"name": "John Smith"
},
"created_at": "2025-10-16T10:00:00Z",
"updated_at": "2025-10-20T12:00:00Z"
}
],
"pagination": { ... }
}
```
##### Get Payroll Details
```http
GET /v1/payroll-records/{payroll_id}
Authorization: Bearer {jwt_token}
```
**Response (200 OK):**
```json
{
"data": {
"id": "990e8400-e29b-41d4-a716-446655440444",
"employee": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Sarah Johnson",
"employee_number": "EMP001234"
},
"period_start": "2025-10-01",
"period_end": "2025-10-15",
"earnings": {
"base_salary": 5000.00,
"overtime": 0.00,
"bonuses": 0.00,
"gross_total": 5000.00
},
"deductions": {
"federal_tax": 750.00,
"state_tax": 250.00,
"health_insurance": 200.00,
"dental_insurance": 50.00,
"retirement_401k": 300.00,
"total_deductions": 1550.00
},
"net_pay": 3450.00,
"payment_status": "paid",
"payment_date": "2025-10-20",
"payment_method": "direct_deposit",
"payment_reference": "ACH-20251020-5544",
"approved_by": {
"id": "550e8400-e29b-41d4-a716-446655440099",
"name": "John Smith",
"approved_at": "2025-10-18T14:30:00Z"
},
"created_at": "2025-10-16T10:00:00Z",
"updated_at": "2025-10-20T12:00:00Z"
}
}
```
##### Create Payroll Record
```http
POST /v1/payroll-records
Authorization: Bearer {jwt_token}
Content-Type: application/json
```
**Request Body:**
```json
{
"employee_id": "550e8400-e29b-41d4-a716-446655440000",
"period_start": "2025-10-16",
"period_end": "2025-10-31",
"gross_pay": 5000.00,
"deductions": {
"tax": 1000.00,
"insurance": 250.00,
"retirement": 300.00
}
}
```
**Response (201 Created):** Returns full payroll record with status `draft`.
##### Approve Payroll
```http
POST /v1/payroll-records/{payroll_id}/approve
Authorization: Bearer {jwt_token}
```
**Response (200 OK):**
```json
{
"data": {
"id": "990e8400-e29b-41d4-a716-446655440444",
"payment_status": "approved",
"approved_by": "550e8400-e29b-41d4-a716-446655440099",
"approved_at": "2025-10-18T14:30:00Z"
}
}
```
##### Process Payment
```http
POST /v1/payroll-records/{payroll_id}/process-payment
Authorization: Bearer {jwt_token}
Content-Type: application/json
```
**Request Body:**
```json
{
"payment_date": "2025-10-20",
"payment_method": "direct_deposit"
}
```
**Response (200 OK):**
```json
{
"data": {
"id": "990e8400-e29b-41d4-a716-446655440444",
"payment_status": "paid",
"payment_date": "2025-10-20",
"payment_reference": "ACH-20251020-5544",
"updated_at": "2025-10-20T12:00:00Z"
}
}
```
---
#### **DEPARTMENTS** (`/departments`)
##### List Departments
```http
GET /v1/departments
Authorization: Bearer {jwt_token}
```
**Response (200 OK):**
```json
{
"data": [
{
"id": "dept-001",
"name": "Engineering",
"code": "ENG",
"manager": {
"id": "550e8400-e29b-41d4-a716-446655440099",
"name": "John Smith"
},
"cost_center": "CC-1001",
"employee_count": 45,
"created_at": "2020-01-15T09:00:00Z",
"updated_at": "2025-05-10T14:00:00Z"
},
{
"id": "dept-002",
"name": "Product",
"code": "PRD",
"manager": {
"id": "550e8400-e29b-41d4-a716-446655440088",
"name": "Emily Chen"
},
"cost_center": "CC-1002",
"employee_count": 18,
"created_at": "2020-01-15T09:00:00Z",
"updated_at": "2025-08-22T11:00:00Z"
}
]
}
```
---
## 4. Authentication & Authorization Design
### JWT-Based Authentication
**Token Structure:**
```json
{
"header": {
"alg": "RS256",
"typ": "JWT",
"kid": "hr-api-key-2025"
},
"payload": {
"sub": "user-550e8400",
"iss": "https://auth.company.internal",
"aud": "hr-api",
"exp": 1729267200,
"iat": 1729263600,
"scope": "employees:read employees:write attendance:read payroll:read",
"roles": ["hr_admin"],
"department_id": "dept-001"
}
}
```
### Authorization Model (Scope-Based RBAC)
**Role Definitions:**
| Role | Scopes | Description |
|------|--------|-------------|
| `hr_admin` | `employees:*`, `attendance:*`, `payroll:*`, `departments:*` | Full HR system access |
| `hr_manager` | `employees:read`, `employees:write`, `attendance:*`, `payroll:read` | Employee & attendance management |
| `payroll_specialist` | `employees:read`, `payroll:*` | Payroll processing |
| `manager` | `employees:read`, `attendance:read`, `attendance:approve` (own dept) | Department oversight |
| `employee` | `employees:read` (self), `attendance:read` (self), `attendance:write` (self), `payroll:read` (self) | Self-service |
**Scope Format:** `resource:action` (e.g., `employees:write`, `payroll:approve`)
### Token Acquisition Flow
```
1. Client β POST /oauth/token (with credentials)
2. Auth Server validates credentials
3. Auth Server β Returns JWT (15-min expiry) + Refresh Token (7-day expiry)
4. Client β API requests with "Authorization: Bearer {jwt}"
5. API validates token signature, expiry, scope
6. Before JWT expiry β POST /oauth/refresh (with refresh token)
7. New JWT issued
```
### Security Requirements
**Transport Security:**
- HTTPS/TLS 1.3 mandatory (HTTP requests auto-redirect to HTTPS)
- HSTS header: `max-age=31536000; includeSubDomains; preload`
- Certificate pinning for mobile apps
**Token Management:**
- JWT signed with RS256 (2048-bit keys)
- Short-lived access tokens (15 minutes)
- Refresh tokens stored in HTTPOnly cookies (web) or secure storage (mobile)
- Token revocation via blacklist (Redis cache)
**Request Security:**
- Rate limiting: 100 req/min per IP, 1000 req/min per user
- CORS whitelist: `https://hr-portal.company.internal`, `https://hr-mobile.company.internal`
- Request size limit: 1MB
- SQL injection protection via parameterized queries
- XSS protection via Content-Security-Policy headers
**Audit Logging:**
- All write operations logged with: user_id, timestamp, resource, action, IP, user_agent
- Sensitive operations (payroll access, terminations) trigger security alerts
- Logs retained for 2 years, encrypted at rest
---
## 5. Versioning Strategy
### Approach: URL-Based Versioning
**Format:** `/v{major-version}/resource`
- Current: `/v1/employees`
- Future: `/v2/employees`
**Rationale:**
- Explicit, visible version in URL
- Easy to route/cache at infrastructure level
- Clear separation for client teams
- Supports parallel versions during migrations
### Breaking Change Policy
**Breaking changes trigger new major version:**
- Removing/renaming fields
- Changing field types (string β integer)
- Removing/renaming endpoints
- Changing authentication mechanisms
- Modifying required fields
- Changing HTTP status code semantics
**Non-breaking changes (same version):**
- Adding optional fields
- Adding new endpoints
- Adding new optional query parameters
- Expanding enum values (with defaults)
- Performance improvements
- Bug fixes
### Deprecation Timeline
```
t=0 t=3 months t=6 months t=12 months t=18 months
β β β β β
v1 v2 released Deprecation v1 read-only v1 sunset
launched (v1 still notice sent (writes fail (404 for v1)
supported) (v1 supported) gracefully)
```
**Deprecation Process:**
1. **t=0:** v2 launched, v1 fully supported
2. **t+3 months:** Deprecation notice via:
- API response header: `Sunset: Sat, 18 Oct 2026 00:00:00 GMT`
- Email to registered clients
- Developer portal banner
3. **t+6 months:** v1 becomes read-only, writes return `410 Gone` with migration guide
4. **t+12 months:** v1 returns `410 Gone` for all requests
5. **t+18 months:** v1 infrastructure decommissioned
### Migration Support
- **Dual-write period:** 3 months where v1 writes proxy to v2
- **SDKs updated:** v2 SDKs released with v2 launch
- **Migration guide:** Field mapping, code examples, breaking changes documented
- **Support channel:** Dedicated Slack channel for migration questions
- **Sandbox environment:** v2 sandbox available 1 month before production release
---
## 6. Error Handling Framework
### Standard Error Response Format
```json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid employee data provided",
"details": [
{
"field": "email",
"issue": "Email format is invalid",
"provided": "sarah.johnson@",
"expected": "Valid email address (e.g., user@company.com)"
},
{
"field": "hire_date",
"issue": "Date cannot be in the past",
"provided": "2024-05-15",
"expected": "Date >= 2025-10-18"
}
],
"request_id": "req-770e8400-e29b-41d4",
"timestamp": "2025-10-18T15:30:00Z",
"documentation_url": "https://docs.hr-api.company.internal/errors/VALIDATION_ERROR"
}
}
```
### HTTP Status Codes
| Code | Meaning | Usage |
|------|---------|-------|
| 200 | OK | Successful GET/PUT/PATCH |
| 201 | Created | Successful POST (resource created) |
| 204 | No Content | Successful DELETE |
| 400 | Bad Request | Invalid syntax, malformed JSON |
| 401 | Unauthorized | Missing/invalid JWT token |
| 403 | Forbidden | Valid token but insufficient permissions |
| 404 | Not Found | Resource doesn't exist |
| 409 | Conflict | Duplicate employee_number, concurrent edit |
| 410 | Gone | Deprecated endpoint (see versioning) |
| 422 | Unprocessable Entity | Validation errors (see details) |
| 429 | Too Many Requests | Rate limit exceeded (see Retry-After header) |
| 500 | Internal Server Error | Unexpected server issue |
| 503 | Service Unavailable | Maintenance mode, database down |
### Error Code Taxonomy
**Client Errors (4xx):**
- `INVALID_REQUEST`: Malformed JSON, missing required headers
- `VALIDATION_ERROR`: Business rule violations (see details array)
- `AUTHENTICATION_FAILED`: Invalid credentials, expired token
- `INSUFFICIENT_PERMISSIONS`: Scope missing for operation
- `RESOURCE_NOT_FOUND`: Employee/record doesn't exist
- `DUPLICATE_RESOURCE`: Unique constraint violation (employee_number)
- `RATE_LIMIT_EXCEEDED`: Too many requests (see Retry-After)
**Server Errors (5xx):**
- `INTERNAL_ERROR`: Unhandled exception
- `DATABASE_UNAVAILABLE`: Connection failure, timeout
- `DOWNSTREAM_SERVICE_ERROR`: Payroll processor, auth service down
### Retry Guidance
**Rate Limit Response:**
```http
HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1729267200
```
**Retry Strategy:**
- **4xx errors (except 429):** Don't retry without fixing request
- **429:** Exponential backoff starting at Retry-After value
- **5xx errors:** Exponential backoff (1s, 2s, 4s, 8s) with jitter
- **Network errors:** 3 retries with 2s backoff
### Debug Information
**Development/Staging Environments:**
```json
{
"error": {
"code": "INTERNAL_ERROR",
"message": "Failed to process payroll calculation",
"debug": {
"stack_trace": "...",
"sql_query": "SELECT * FROM payroll WHERE ...",
"affected_tables": ["payroll", "deductions"]
}
}
}
```
**Production:** `debug` object omitted, errors logged server-side with `request_id`.
---
## 7. Developer Documentation
### Getting Started Guide
#### 1. Obtain API Credentials
Contact IT ServiceDesk with:
- Application name
- Use case description
- Required scopes
- Environment (staging/production)
Receive:
- Client ID
- Client Secret
- Auth endpoint
#### 2. Authentication Example (cURL)
```bash
# Get access token
curl -X POST https://auth.company.internal/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "scope=employees:read attendance:read"
# Response
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 900,
"refresh_token": "7fda29a3..."
}
```
#### 3. Make Your First API Call
```bash
curl -X GET https://api.hr-system.company.internal/v1/employees/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
```
### Code Examples
#### JavaScript (Node.js)
```javascript
const axios = require('axios');
class HRAPIClient {
constructor(clientId, clientSecret) {
this.clientId = clientId;
this.clientSecret = clientSecret;
this.baseURL = 'https://api.hr-system.company.internal/v1';
this.token = null;
this.tokenExpiry = null;
}
async authenticate() {
const response = await axios.post(
'https://auth.company.internal/oauth/token',
new URLSearchParams({
grant_type: 'client_credentials',
client_id: this.clientId,
client_secret: this.clientSecret,
scope: 'employees:read attendance:read payroll:read'
})
);
this.token = response.data.access_token;
this.tokenExpiry = Date.now() + (response.data.expires_in * 1000);
}
async ensureAuthenticated() {
if (!this.token || Date.now() >= this.tokenExpiry - 60000) {
await this.authenticate();
}
}
async getEmployee(employeeId) {
await this.ensureAuthenticated();
const response = await axios.get(
`${this.baseURL}/employees/${employeeId}`,
{ headers: { Authorization: `Bearer ${this.token}` } }
);
return response.data.data;
}
async listEmployees(filters = {}) {
await this.ensureAuthenticated();
const response = await axios.get(
`${this.baseURL}/employees`,
{
headers: { Authorization: `Bearer ${this.token}` },
params: filters
}
);
return response.data;
}
async clockIn(employeeId, location) {
await this.ensureAuthenticated();
const response = await axios.post(
`${this.baseURL}/attendance-records/clock-in`,
{
employee_id: employeeId,
timestamp: new Date().toISOString(),
location: location
},
{ headers: { Authorization: `Bearer ${this.token}` } }
);
return response.data.data;
}
}
// Usage
(async () => {
const client = new HRAPIClient('YOUR_CLIENT_ID', 'YOUR_CLIENT_SECRET');
// Get employee
const employee = await client.getEmployee('550e8400-e29b-41d4-a716-446655440000');
console.log(`Employee: ${employee.first_name} ${employee.last_name}`);
// List employees in Engineering
const engineers = await client.listEmployees({
department: 'engineering',
status: 'active'
});
console.log(`Found ${engineers.pagination.total_items} engineers`);
// Clock in
const clockIn = await client.clockIn(
'550e8400-e29b-41d4-a716-446655440000',
{ latitude: 37.7749, longitude: -122.4194 }
);
console.log(`Clocked in at ${clockIn.clock_in}`);
})();
```
#### Python
```python
import requests
from datetime import datetime, timedelta
class HRAPIClient:
def __init__(self, client_id, client_secret):
self.client_id = client_id
self.client_secret = client_secret
self.base_url = 'https://api.hr-system.company.internal/v1'
self.token = None
self.token_expiry = None
def authenticate(self):
response = requests.post(
'https://auth.company.internal/oauth/token',
data={
'grant_type': 'client_credentials',
'client_id': self.client_id,
'client_secret': self.client_secret,
'scope': 'employees:read attendance:read payroll:read'
}
)
response.raise_for_status()
data = response.json()
self.token = data['access_token']
self.token_expiry = datetime.now() + timedelta(seconds=data['expires_in'])
def ensure_authenticated(self):
if not self.token or datetime.now() >= self.token_expiry - timedelta(seconds=60):
self.authenticate()
def get_headers(self):
self.ensure_authenticated()
return {'Authorization': f'Bearer {self.token}'}
def get_employee(self, employee_id):
response = requests.get(
f'{self.base_url}/employees/{employee_id}',
headers=self.get_headers()
)
response.raise_for_status()
return response.json()['data']
def list_attendance(self, employee_id, start_date, end_date):
response = requests.get(
f'{self.base_url}/attendance-records',
headers=self.get_headers(),
params={
'employee_id': employee_id,
'start_date': start_date,
'end_date': end_date
}
)
response.raise_for_status()
return response.json()
def create_employee(self, employee_data):
response = requests.post(
f'{self.base_url}/employees',
headers=self.get_headers(),
json=employee_data
)
response.raise_for_status()
return response.json()['data']
# Usage
client = HRAPIClient('YOUR_CLIENT_ID', 'YOUR_CLIENT_SECRET')
# Get employee
employee = client.get_employee('550e8400-e29b-41d4-a716-446655440000')
print(f"Employee: {employee['first_name']} {employee['last_name']}")
# Get attendance summary
attendance = client.list_attendance(
'550e8400-e29b-41d4-a716-446655440000',
'2025-10-01',
'2025-10-18'
)
print(f"Total hours: {attendance['summary']['total_hours']}")
```
### Interactive Playground
**Swagger UI:** https://api.hr-system.company.internal/docs
- Try endpoints with live token
- View request/response schemas
- Download OpenAPI 3.0 spec
**Postman Collection:** https://docs.hr-api.company.internal/postman-collection.json
- Pre-configured environment variables
- Example requests for all endpoints
- Automated token refresh
### SDKs
| Language | Repository | Installation |
|----------|------------|--------------|
| JavaScript | `@company/hr-api-client` | `npm install @company/hr-api-client` |
| Python | `company-hr-api-client` | `pip install company-hr-api-client` |
| C# | `Company.HR.ApiClient` | `dotnet add package Company.HR.ApiClient` |
### Reference Documentation
**Base URL:** https://docs.hr-api.company.internal
**Sections:**
- **Authentication:** Token flows, scope reference, security best practices
- **Endpoints:** Complete API reference with request/response examples
- **Error Codes:** Full error catalog with resolution steps
- **Webhooks:** Event notification system (future feature)
- **Rate Limits:** Usage tiers, optimization strategies
- **Changelog:** Version history, migration guides, breaking changes
### Support Channels
- **Slack:** #hr-api-support (response time: <2 hours during business hours)
- **Email:** hr-api@company.internal
- **Incident Hotline:** x5555 (P0/P1 incidents only)
---
## 8. Performance & Monitoring
### Performance Targets
| Metric | Target | Measurement |
|--------|--------|-------------|
| P50 latency | <200ms | 95% of requests |
| P95 latency | <500ms | 98% of requests |
| P99 latency | <1000ms | 99.5% of requests |
| Availability | 99.9% | Monthly uptime |
| Error rate | <0.1% | Non-5xx responses |
### Optimization Strategies
**Caching:**
- Employee profiles: 5-minute TTL (ETag support)
- Department list: 1-hour TTL
- Payroll records: Immutable once paid (1-year cache)
**Database Indexing:**
- `employees.email`, `employees.employee_number` (unique)
- `attendance_records.employee_id`, `attendance_records.date` (composite)
- `payroll_records.employee_id`, `payroll_records.period_start` (composite)
**Pagination Defaults:**
- Max 100 items per page
- Cursor-based pagination for large result sets (future enhancement)
**Response Compression:**
- gzip/brotli for responses >1KB
### Monitoring & Alerting
**Metrics Dashboard:**
- Request rate, latency percentiles (Grafana)
- Error rate by endpoint, status code
- Auth success/failure rate
- Database connection pool utilization
- Token validation cache hit rate
**Alerts:**
- P1: API down (no successful requests for 2 minutes)
- P2: Latency P95 >500ms for 5 minutes
- P2: Error rate >1% for 5 minutes
- P3: Auth failure rate >5%
---
## Summary Recommendations
### For HR Portal Team (Web Client)
1. **Use JavaScript SDK** for automatic token refresh
2. **Implement optimistic UI updates** for clock-in/out (sub-500ms target)
3. **Cache employee profiles** with ETag validation
4. **Handle 422 errors gracefully** with field-level validation feedback
### For Mobile App Team
1. **Use certificate pinning** for TLS security
2. **Implement offline queue** for clock-in/out (sync when online)
3. **Respect Retry-After headers** on 429 responses
4. **Store refresh tokens securely** (iOS Keychain, Android Keystore)
### For API Operations Team
1. **Monitor P95 latency** as primary SLO metric
2. **Set up synthetic monitoring** for critical paths (clock-in, payroll fetch)
3. **Implement circuit breakers** for downstream dependencies (auth service)
4. **Plan v2 migration** 6 months before v1 sunset
---
## Appendix: OpenAPI 3.0 Specification (Excerpt)
```yaml
openapi: 3.0.3
info:
title: HR Management API
version: 1.0.0
description: Internal REST API for employee, attendance, and payroll management
contact:
name: API Support
email: hr-api@company.internal
servers:
- url: https://api.hr-system.company.internal/v1
description: Production
- url: https://api-staging.hr-system.company.internal/v1
description: Staging
security:
- BearerAuth: []
paths:
/employees:
get:
summary: List employees
operationId: listEmployees
tags: [Employees]
parameters:
- name: page
in: query
schema:
type: integer
default: 1
- name: per_page
in: query
schema:
type: integer
default: 50
maximum: 100
- name: department
in: query
schema:
type: string
- name: status
in: query
schema:
type: string
enum: [active, on_leave, terminated]
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/EmployeeListResponse'
components:
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
schemas:
Employee:
type: object
properties:
id:
type: string
format: uuid
employee_number:
type: string
first_name:
type: string
last_name:
type: string
email:
type: string
format: email
# ... additional fields
```
**Full OpenAPI spec:** https://api.hr-system.company.internal/openapi.yaml
---
*This API design provides a production-ready foundation for HR operations with enterprise-grade security, sub-500ms performance, and comprehensive developer experience. All design decisions align with REST principles, JWT best practices, and internal infrastructure constraints.*
By purchasing this prompt, you agree to our terms of service
CLAUDE-4-5-SONNET
This prompt defines the role of an API Architect responsible for designing programmatic interfaces with strong attention to structure, scalability, and developer experience.
It guides the model through structured reasoning steps (CoT_Chain) to model resources, select API architecture types, define endpoints, implement security, plan versioning, and produce developer documentation.
The goal is to generate a comprehensive and technically sound API design aligned with given inputs such as purpose,
...more
Added over 1 month ago
