# OpenAPI Contracts — Service Interfaces

## Architecture Overview

```
Gateway (BFF)  ──────►  Router  ──────►  Memory API
    │                      │                 │
    │                      ▼                 ▼
    │               Control Plane      (Qdrant/Neo4j/PG)
    │                      │
    └──────►  Ingest  ────►  Parser (async via NATS)
```

---

## 1. Gateway → Router Contract

### POST /v1/agents/{agent_id}/infer

Request:
```json
{
  "prompt": "...",
  "model": "optional-model-override",
  "system_prompt": "optional override",
  "temperature": 0.3,
  "max_tokens": 700,
  "images": ["data:image/png;base64,<...>"],
  "metadata": {
    "user_id": "tg:123456",
    "chat_id": "-5289219705",
    "trace_id": "uuid",
    "agent_id": "helion"
  }
}
```

Response:
```json
{
  "response": "...",
  "model": "deepseek-chat",
  "backend": "deepseek-cloud",
  "tokens_used": 1234,
  "image_base64": null,
  "file_base64": null,
  "file_name": null,
  "file_mime": null
}
```

---

## 2. Router → Memory API Contract

### POST /retrieve

Request:
```json
{
  "queries": [
    {
      "query": "text query",
      "vector": [0.1, 0.2, ...],
      "top_k": 10,
      "agent_id": "helion",
      "user_id": "tg:123456",
      "filters": {
        "scope": ["personal", "team"],
        "date_from": "2026-01-01"
      }
    }
  ]
}
```

Response:
```json
{
  "results": [
    {
      "id": "uuid",
      "content": "...",
      "score": 0.95,
      "source": "message|document|artifact",
      "metadata": {...}
    }
  ],
  "query_time_ms": 45
}
```

### POST /store

Request:
```json
{
  "agent_id": "helion",
  "user_id": "tg:123456",
  "content": "...",
  "content_type": "message|document|fact",
  "vector": [0.1, 0.2, ...],
  "metadata": {
    "chat_id": "...",
    "role": "user|assistant"
  }
}
```

Response:
```json
{
  "id": "uuid",
  "indexed": true,
  "collections": ["helion_messages"]
}
```

---

## 3. Router → Control Plane Contract

### GET /prompts/{agent_id}

Response:
```json
{
  "agent_id": "helion",
  "version": "latest",
  "content": "system prompt...",
  "hash": "abc123",
  "updated_at": "2026-01-19T12:00:00Z"
}
```

### GET /policy/{agent_id}

Response:
```json
{
  "agent_id": "helion",
  "allowed_modes": ["public", "team", "private"],
  "allowed_tools": ["web_search", "memory_search"],
  "max_tokens": 8000,
  "rate_limit_per_minute": 60,
  "confidential_allowed": true
}
```

### GET /config/{key}

Response:
```json
{
  "key": "routing.default_model",
  "value": "deepseek-chat",
  "version": "1.0"
}
```

---

## 4. Gateway → Ingest Contract

### POST /ingest

Request: multipart/form-data
- file: binary
- user_id: string
- chat_id: string  
- agent_id: string

Response:
```json
{
  "file_id": "uuid",
  "file_type": "image|audio|document",
  "size_bytes": 12345,
  "status": "pending",
  "message": "File accepted for processing"
}
```

---

## 5. NATS Event Contracts

### attachment.created.{type}

```json
{
  "event_id": "uuid",
  "event_type": "attachment.created.image",
  "timestamp": "2026-01-19T12:00:00Z",
  "trace_id": "correlation-id",
  "file_id": "uuid",
  "file_type": "image",
  "storage_path": "/data/uploads/...",
  "agent_id": "helion",
  "user_id": "tg:123456"
}
```

### agent.run.requested

```json
{
  "event_id": "uuid",
  "task_id": "uuid",
  "workflow_type": "simple|research|multi_agent",
  "agent_id": "helion",
  "payload": {
    "prompt": "...",
    "context": {...}
  },
  "priority": 1,
  "timeout": 300
}
```

### agent.run.completed

```json
{
  "event_id": "uuid",
  "task_id": "uuid",
  "agent_id": "helion",
  "success": true,
  "result": {...},
  "duration_ms": 5000
}
```

---

## 6. Error Response Contract

All services return errors in unified format:

```json
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Too many requests",
    "details": {
      "limit": 60,
      "reset_at": "2026-01-19T12:01:00Z"
    }
  },
  "trace_id": "uuid"
}
```

Error codes:
- `VALIDATION_ERROR` - Invalid request
- `NOT_FOUND` - Resource not found
- `RATE_LIMIT_EXCEEDED` - Quota exceeded
- `UNAUTHORIZED` - Auth required
- `FORBIDDEN` - Access denied
- `INTERNAL_ERROR` - Server error
- `TIMEOUT` - Request timeout
- `SERVICE_UNAVAILABLE` - Dependency down

---

## 7. Headers Contract

Required headers:
```
X-Trace-ID: uuid          # Correlation ID
X-Agent-ID: helion        # Target agent
X-User-ID: tg:123456      # User identifier
```

Optional:
```
X-Mode: confidential      # Privacy mode
X-Cache-Hash: abc123      # For prompt caching
```

---

## 8. Idempotency & Versioning Headers

### Idempotency (required for POST/PUT)
```
X-Idempotency-Key: {source}:{entity}:{action}:{hour}
```
Example: `gateway:msg-123:infer:2026011912`

Server MUST:
- Store key for 1 hour
- Return cached response if key exists
- Return 409 Conflict if processing

### Version Headers (in response)
```
X-Policy-Version: helion:policy:abc123:20260119
X-Prompt-Version: helion:prompt:def456:20260119
X-Config-Version: routing:config:ghi789:20260119
```

### Rate Limit Headers
```
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1705669200
Retry-After: 60             # Only on 429 response
```
