# API Requirements

## Purpose
Define the non-CalDAV HTTP API contract for calendar, user-access workflow, and operational endpoints used by the plugin UI and tests.

## Scope
This document covers:

- API base path and versioning
- Event CRUD endpoints
- CalDAV-user workflow endpoints
- Standard request/response and error contracts
- Authn/Authz expectations for API calls

## Normative Boundaries
- API authentication and token/session behavior are defined in `requirements/authentication.md`.
- Authorization matrix and role constraints are defined in `requirements/authorization.md`.
- Error payload/status normalization is defined in `requirements/error_model.md`.
- Recurrence exception behavior is defined in `requirements/recurrence_exceptions.md`.
- Data persistence schema is defined in `requirements/data_schema.md`.

## API Baseline
- Base path: `/wp-json/calendar/v1`
- If `url_slug` is configured in setup, canonical API paths are prefixed: `/<url_slug>/wp-json/calendar/v1`.
- Content type: `application/json; charset=utf-8`
- Time format: ISO 8601 with timezone offset
- All endpoints must be deterministic under `Europe/London` default timezone assumptions unless a timezone is explicitly supplied.

## Versioning
- Breaking changes require a new version namespace (`v2`, etc.).
- Non-breaking additions are permitted in the current version.
- Deprecated fields/endpoints must remain for at least one release cycle with documentation notice.

## Event Endpoints

### Create Event
- `POST /events`
- Requires calendar write capability.
- Request body supports fields in `requirements/editor.md`, including `visibility` (`public`/`private`).
- Response: `201` with created event payload and identifiers.

### List Events
- `GET /events`
- Supports query params:
  - `from` (optional)
  - `to` (optional)
  - `view` (optional: `list`, `day`, `week`, `month`, `year`)
  - `page` and `per_page` (optional)
- Response: `200` with array plus pagination metadata if paged.

### Get Event
- `GET /events/{event_id}`
- Response: `200` with event payload or `404`.

### Update Event
- `PUT /events/{event_id}` or `PATCH /events/{event_id}`
- Requires calendar write capability.
- Must enforce optimistic concurrency via version/etag precondition checks.
- Response: `200` with updated event payload.

### Delete Event
- `DELETE /events/{event_id}`
- Requires calendar write capability.
- Response: `204` on success.

### Delete Single Occurrence
- `DELETE /events/{event_id}/occurrences/{occurrence_key}`
- Requires calendar write capability.
- Deletes only one occurrence in a recurring series by creating an exception.
- Must not split the underlying recurring series.
- Response: `204` on success.


## Public Read Endpoints and Privacy Redaction

Public-read endpoints (for example `/public/events`, `/public/sidebar-events`, and ICS feed generation paths) must apply privacy masking for `private` events:

- Event date/time placement remains unchanged.
- Title is replaced with `Private Event`.
- Description/location/category and other non-time content are omitted from public responses.
- Logged-in write-capable UI and authenticated CalDAV/API reads continue to receive full event details.

## CalDAV User Workflow Endpoints

### Register
- `POST /users/register`
- Public endpoint with abuse controls.
- Creates account in `pending_approval`.
- Registration is implicitly a write-access request; no separate request endpoint exists.

### Verify Email
- `POST /users/verify`
- Consumes single-use verification token.
- Marks email as verified while account remains `pending_approval` until admin approval.

### Forgot Password
- `POST /users/forgot-password`
- Issues password reset token by email.

### Reset Password
- `POST /users/reset-password`
- Consumes single-use reset token.

### Admin User List/Update/Delete
- `GET /admin/users`
- `PATCH /admin/users/{user_id}`
- `DELETE /admin/users/{user_id}`
- Admin-only endpoints for approval state transitions and user removal.

### Admin Diagnostics
- `GET /admin/diagnostics?limit=20`
- Admin-only endpoint.
- Returns recent request/response trace entries for operational troubleshooting.
- Sensitive fields must remain redacted per `requirements/observability.md`.

## Response Contract
Success responses should include:

- `data`: endpoint payload
- `meta`: optional metadata (pagination, timestamps, version)

Error responses should include:

- `error.code` (stable machine-readable code)
- `error.message` (human-readable summary)
- `error.details` (optional field-level/context details)

## Validation and Error Statuses
- `400` malformed request
- `401` unauthenticated
- `403` unauthorized
- `404` not found
- `409` conflict (state transition conflict)
- `412` precondition failed (etag/version mismatch)
- `422` semantic validation failure
- `429` rate-limited
- `500` internal server error

## Security Requirements
- HTTPS required for all authenticated API operations.
- CSRF/nonce protections for cookie-authenticated endpoints.
- Rate limiting for register/verify/reset/login-like flows.
- Error responses must avoid user enumeration leakage.

## Verification Requirements
Acceptance should verify:

- Endpoint paths and methods behave as documented.
- Validation and error payloads are consistent.
- Single-occurrence delete creates recurrence exception rather than split series.
- Authz rules enforce role/access constraints.
- Privacy redaction rules are enforced consistently across public API payloads and ICS output.
