# Avrupa Rüyası — Public API architecture

## Purpose

This document describes how avruparuyasi.com.tr exposes machine-readable tour catalog data alongside the human-facing website. It supports SI Agent Readiness audits (API-first / headless readiness) and integrator onboarding.

## High-level model

| Layer | Role | Technology |
|-------|------|------------|
| Public website | Marketing, tour discovery, booking UX | Express 5, server-rendered EJS |
| Public read API | Headless catalog for agents and partners | REST JSON under `/api/public/*` |
| Agent discovery | Summaries and contracts | `llms.txt`, `llms-full.txt`, `AGENTS.md`, OpenAPI 3.1 |
| CRM / operations | Staff-only mutations | Authenticated `/api/v1/*` (not for public agents) |

The product is **hybrid**: end users book via HTML flows; **catalog and availability for automation** are API-first via the public read surface. Reservation, payment, and PII-heavy steps remain server-rendered and are out of scope for cross-origin agent APIs.

## Public API surface

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/api/public/tours` | GET | Published tour list |
| `/api/public/tours/{slug}` | GET | Tour detail and departures |
| `/api/public/tours/{slug}/client-data` | GET | Tour page client payload (same origin as site JS) |

Contract: [OpenAPI 3.1](https://www.avruparuyasi.com.tr/.well-known/openapi.yaml) (also `/.well-known/openapi.json`).

Data source: MongoDB `tour` and `tour date` collections; aligned with JSON-LD on tour pages and `llms-full.txt` generation.

## CORS policy

### Public agent and documentation endpoints

These routes are intentionally callable from browser-based agents and third-party tools:

- `/api/public/*`
- `/.well-known/openapi.yaml`
- `/.well-known/openapi.json`
- `/AGENTS.md`
- `/ARCHITECTURE.md`

Response headers:

- `Access-Control-Allow-Origin: *`
- `Access-Control-Allow-Methods: GET, HEAD, OPTIONS`
- `Access-Control-Allow-Credentials` is **not** set (wildcard origin requires credentials off)
- JSON API responses include `X-Robots-Tag: noindex`

Preflight `OPTIONS` is supported on `/api/public/*` with `Access-Control-Max-Age: 86400`.

### Authenticated CRM API

`/api/v1/*` and session/cookie flows use a **whitelist** from the `ALLOWED_ORIGINS` environment variable (CRM panel origins only), with `Access-Control-Allow-Credentials: true`. Unknown browser origins do not receive `Access-Control-Allow-Origin`.

## Rate limiting

Public tour API: 120 requests per minute per IP (same as before CORS split).

## Security boundaries

Agents **must not** call:

- `/get-total-price`, `/create-reservation`, `/documents/`
- Any `/api/v1/*` route without staff credentials

## Roadmap

| Item | Status |
|------|--------|
| Public REST + OpenAPI | Live |
| `llms-full.txt` daily refresh | Live |
| MCP server + `/.well-known/mcp` | Live (see `MCP-EVALUATION.md`) |
| In-site Rüya AI chat | Planned; UI placeholder only |
| Full headless checkout | Not planned; booking stays on-site for compliance and payment |

## Change log

- 2026-10-12: Document published; public agent CORS (`Access-Control-Allow-Origin: *`) on read API and OpenAPI.

## Contact

info@avruparuyasi.com.tr — subject: Agent/API
