# Production Agentic RAG Course API Endpoints and Their Schemas: Complete Reference

> Explore the production Agentic RAG Course API endpoints and schemas. This reference details six REST endpoints with strict Pydantic validation for your development needs.

- Repository: [jamwithai/production-agentic-rag-course](https://github.com/jamwithai/production-agentic-rag-course)
- Tags: api-reference
- Published: 2026-03-23

---

**The `production-agentic-rag-course` FastAPI service exposes six REST endpoints under the base path `/api/v1`, each using strict Pydantic schemas for request validation and typed responses.**

The **production-agentic-rag-course** repository provides a production-ready FastAPI application for agentic retrieval-augmented generation over arXiv papers. Mastering the **API endpoints and their schemas** enables you to integrate hybrid search, streaming LLM generation, and autonomous agentic reasoning into your own systems.

## API Endpoints Overview

All routes are mounted in [`src/main.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/main.py) via `app.include_router()` and share the prefix `/api/v1`. The following table summarizes the available endpoints, their HTTP methods, and primary purposes:

- **Health Check** – `GET /api/v1/health` – Liveness probe for load balancers
- **Hybrid Search** – `POST /api/v1/hybrid-search/` – BM25 and vector search over indexed chunks
- **Ask (RAG)** – `POST /api/v1/ask` – Standard RAG with synchronous LLM response
- **Ask (Streaming)** – `POST /api/v1/stream` – Server-sent events for real-time token streaming
- **Agentic Ask** – `POST /api/v1/ask-agentic` – Autonomous agent with reasoning steps and retrieval grading
- **Feedback** – `POST /api/v1/feedback` – Submit user ratings to Langfuse for observability

## Detailed Endpoint Specifications and Schemas

### Health Check Endpoint

Located in [`src/routers/ping.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/routers/ping.py), this endpoint returns service status and dependency health.

```python
@router.get("/health", response_model=HealthResponse, tags=["Health"])
async def health_check(...):

```

- **Request Schema**: None
- **Response Schema**: `HealthResponse` (defined in [`src/schemas/api/health.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/schemas/api/health.py))
- **Fields**: `status`, `version`, `environment`, `service_name`, and nested `services` object tracking `database`, `opensearch`, and `ollama` health

### Hybrid Search Endpoint

Defined in [`src/routers/hybrid_search.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/routers/hybrid_search.py), this endpoint executes BM25, dense vector, or hybrid search.

```python
@router.post("/", response_model=SearchResponse)
async def hybrid_search(request: HybridSearchRequest, ...):

```

- **Request Schema**: `HybridSearchRequest` ([`src/schemas/api/search.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/schemas/api/search.py))
- **Response Schema**: `SearchResponse` ([`src/schemas/api/search.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/schemas/api/search.py))
- **Key Fields**: `query` (string), `size` (int), `use_hybrid` (boolean), `filters` (optional); response contains `hits` array with `title`, `authors`, `pdf_url`, and `text` chunks

### Standard RAG (Ask) Endpoint

Implemented in [`src/routers/ask.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/routers/ask.py), this performs retrieval followed by LLM generation.

```python
@ask_router.post("/ask", response_model=AskResponse)
async def ask_question(request: AskRequest, ...):

```

- **Request Schema**: `AskRequest` ([`src/schemas/api/ask.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/schemas/api/ask.py))
- **Response Schema**: `AskResponse` ([`src/schemas/api/ask.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/schemas/api/ask.py))
- **Fields**: Input accepts `query`, `top_k`, `use_hybrid`, and `model` (e.g., `"llama3.2:1b"`); output returns `answer`, `sources` (PDF URLs), and `chunks_used`

### Streaming RAG Endpoint

Also in [`src/routers/ask.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/routers/ask.py), this variant streams partial tokens via Server-Sent Events (SSE).

```python
@stream_router.post("/stream")
async def ask_question_stream(request: AskRequest, ...):

```

- **Request Schema**: `AskRequest` ([`src/schemas/api/ask.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/schemas/api/ask.py))
- **Response Format**: `StreamingResponse` with `text/plain` content type
- **Event Structure**: JSON payloads containing initial `metadata` (`sources`, `chunks_used`, `search_mode`), intermediate `chunk` strings, and a final `answer` object with `done: true`

### Agentic RAG Endpoint

Located in [`src/routers/agentic_ask.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/routers/agentic_ask.py), this endpoint implements an autonomous agent that decides whether to retrieve, grade documents, and rewrite queries.

```python
@router.post("/ask-agentic", response_model=AgenticAskResponse)
async def ask_agentic(request: AskRequest, agentic_rag: AgenticRAGDep):

```

- **Request Schema**: `AskRequest` ([`src/schemas/api/ask.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/schemas/api/ask.py))
- **Response Schema**: `AgenticAskResponse` ([`src/schemas/api/ask.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/schemas/api/ask.py))
- **Extended Fields**: Includes all `AskResponse` fields plus `reasoning_steps` (list of strings), `retrieval_attempts` (integer), and optional `trace_id` for Langfuse tracing

### Feedback Endpoint

Also in [`src/routers/agentic_ask.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/routers/agentic_ask.py), this submits user feedback to the observability layer.

```python
@router.post("/feedback", response_model=FeedbackResponse)
async def submit_feedback(request: FeedbackRequest, langfuse_tracer: LangfuseDep):

```

- **Request Schema**: `FeedbackRequest` ([`src/schemas/api/ask.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/schemas/api/ask.py))
- **Response Schema**: `FeedbackResponse` ([`src/schemas/api/ask.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/schemas/api/ask.py))
- **Fields**: Accepts `trace_id` (string), `score` (float), and optional `comment` (string); returns `success` boolean

## Practical Integration Examples

### Health Check

```bash
curl -X GET https://<host>/api/v1/health

```

```python
import requests

resp = requests.get("https://<host>/api/v1/health")
print(resp.json())

```

### Hybrid Search

```bash
curl -X POST https://<host>/api/v1/hybrid-search/ \
  -H "Content-Type: application/json" \
  -d '{"query":"transformer architecture", "size":5, "use_hybrid":true}'

```

```python
import requests

payload = {
    "query": "transformer architecture",
    "size": 5,
    "use_hybrid": True
}
r = requests.post("https://<host>/api/v1/hybrid-search/", json=payload)
print(r.json())

```

### Standard Ask

```bash
curl -X POST https://<host>/api/v1/ask \
  -H "Content-Type: application/json" \
  -d '{"query":"What are transformers?", "top_k":3, "use_hybrid":true}'

```

```python
import requests

payload = {
    "query": "What are transformers?",
    "top_k": 3,
    "use_hybrid": True,
    "model": "llama3.2:1b"
}
r = requests.post("https://<host>/api/v1/ask", json=payload)
print(r.json())

```

### Streaming Response

```bash
curl -N -X POST https://<host>/api/v1/stream \
  -H "Content-Type: application/json" \
  -d '{"query":"Explain attention mechanism", "top_k":2}'

```

```python
import requests

payload = {"query": "Explain attention mechanism", "top_k": 2}
with requests.post("https://<host>/api/v1/stream", json=payload, stream=True) as r:
    for line in r.iter_lines():
        if line:
            print(line.decode())

```

### Agentic Ask

```bash
curl -X POST https://<host>/api/v1/ask-agentic \
  -H "Content-Type: application/json" \
  -d '{"query":"Can LLMs reason about causality?", "top_k":4}'

```

```python
import requests

payload = {"query": "Can LLMs reason about causality?", "top_k": 4}
r = requests.post("https://<host>/api/v1/ask-agentic", json=payload)
print(r.json())

```

### Submitting Feedback

```bash
curl -X POST https://<host>/api/v1/feedback \
  -H "Content-Type: application/json" \
  -d '{"trace_id":"abc123-def456","score":1,"comment":"Great answer!"}'

```

```python
import requests

payload = {"trace_id": "abc123-def456", "score": 1.0, "comment": "Great answer!"}
r = requests.post("https://<host>/api/v1/feedback", json=payload)
print(r.json())

```

## Summary

- **Base Path**: All endpoints are prefixed with `/api/v1` as configured in [`src/main.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/main.py)
- **Schema Location**: Pydantic models reside in [`src/schemas/api/health.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/schemas/api/health.py), [`src/schemas/api/search.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/schemas/api/search.py), and [`src/schemas/api/ask.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/schemas/api/ask.py)
- **Streaming Protocol**: The `/api/v1/stream` endpoint uses Server-Sent Events (SSE) with `text/plain` content type rather than standard JSON
- **Agentic Extensions**: `AgenticAskResponse` enriches the standard response with `reasoning_steps`, `retrieval_attempts`, and `trace_id` for full observability
- **Dependency Injection**: Routers leverage FastAPI dependencies (`AgenticRAGDep`, `LangfuseDep`) to inject service layers defined in `src/services/`

## Frequently Asked Questions

### What is the base path for all API endpoints?

All endpoints are mounted under `/api/v1` as defined in [`src/main.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/main.py). The health check is accessible at `/api/v1/health`, while search and generation endpoints follow the pattern `/api/v1/<resource>`.

### Which schema defines the streaming response structure?

Unlike the standard endpoints that return `AskResponse`, the `/api/v1/stream` endpoint does not use a Pydantic response model. Instead, it yields `text/plain` Server-Sent Events where each line is a JSON object containing either `metadata`, `chunk`, or the final `answer` field.

### How does the agentic endpoint differ from the standard ask endpoint?

**The agentic endpoint** (`/api/v1/ask-agentic`) uses `AgenticAskResponse`, which extends the base `AskResponse` with `reasoning_steps` (a list of agent decisions), `retrieval_attempts` (count of retrieval cycles), and an optional `trace_id` for Langfuse integration. **The standard endpoint** (`/api/v1/ask`) returns only the final `answer`, `sources`, and `chunks_used` without exposing intermediate reasoning.

### Where are the Pydantic request and response models defined?

Schema definitions are centralized in three files: [`src/schemas/api/health.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/schemas/api/health.py) contains `HealthResponse`; [`src/schemas/api/search.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/schemas/api/search.py) contains `HybridSearchRequest` and `SearchResponse`; and [`src/schemas/api/ask.py`](https://github.com/jamwithai/production-agentic-rag-course/blob/main/src/schemas/api/ask.py) contains `AskRequest`, `AskResponse`, `AgenticAskResponse`, `FeedbackRequest`, and `FeedbackResponse`.