# API Documentation — go-first / URPI Base URL: `https://www.urpi.be/api/v1` Local: `http://localhost:8080/api/v1` All responses follow a consistent envelope format. --- ## Response Format ### Success ```json { "success": true, "data": {}, "meta": { "page": 1, "page_size": 20, "total": 100, "total_pages": 5 } } ``` ### Error ```json { "success": false, "error": { "code": "ERROR_CODE", "message": "Human readable message", "details": "Optional technical details" } } ``` --- ## Common Error Codes | Code | HTTP Status | Description | |------|-------------|-------------| | `VALIDATION_ERROR` | 400 | Request body validation failed | | `INVALID_ID` | 400 | UUID format invalid | | `NOT_FOUND` | 404 | Resource not found | | `UNAUTHORIZED` | 401 | Authentication required | | `FORBIDDEN` | 403 | Insufficient permissions | | `CONFLICT` | 409 | Resource conflict | | `RATE_LIMITED` | 429 | Too many requests | | `INTERNAL_ERROR` | 500 | Server error | | `SERVICE_UNAVAILABLE` | 503 | Service temporarily unavailable | --- ## Endpoints ### Health Check **GET** `/health` No authentication required. #### Response ```json { "success": true, "data": { "status": "ok", "service": "go-first", "version": "1.0.0" } } ``` --- ### Skills #### List Skills **GET** `/skills` | Query Param | Type | Description | |-------------|------|-------------| | `category` | string | Filter by category (Backend, Frontend, Architecture, DevOps, Database, API) | #### Response ```json { "success": true, "data": [ { "id": "uuid", "name": "Go", "category": "Backend", "proficiency": 5, "icon": "go", "order": 1, "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z" } ] } ``` #### Get Skill **GET** `/skills/:id` | Path Param | Type | Description | |------------|------|-------------| | `id` | uuid | Skill UUID | #### Response ```json { "success": true, "data": { "id": "uuid", "name": "Go", "category": "Backend", "proficiency": 5, "icon": "go", "order": 1, "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z" } } ``` --- ### Projects #### List Projects **GET** `/projects` | Query Param | Type | Description | |-------------|------|-------------| | `category` | string | Filter by category | | `featured` | boolean | Filter featured projects only | #### Response ```json { "success": true, "data": [ { "id": "uuid", "title": "E-Commerce Platform", "description": "Full description...", "short_desc": "Scalable e-commerce platform...", "tech_stack": ["Go", "React", "PostgreSQL", "Redis", "Kubernetes"], "image_url": "/images/projects/ecommerce.jpg", "demo_url": "https://demo.urpi.be/ecommerce", "repo_url": "https://github.com/urpi/ecommerce-platform", "category": "Full Stack", "featured": true, "order": 1, "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z" } ] } ``` #### Get Featured Projects **GET** `/projects/featured` Returns only projects with `featured: true`. #### Get Project **GET** `/projects/:id` | Path Param | Type | Description | |------------|------|-------------| | `id` | uuid | Project UUID | --- ### Experience #### List Experience **GET** `/experience` Returns all work experience entries ordered by `order` field. #### Response ```json { "success": true, "data": [ { "id": "uuid", "company": "URPI", "role": "Founder & Lead Developer", "location": "Belgium", "start_date": "2020-01-01T00:00:00Z", "end_date": null, "current": true, "description": "Founded URPI to provide web application...", "tech_stack": ["Go", "Java", "React", "Kubernetes", "AWS"], "order": 1, "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z" } ] } ``` --- ### Services #### List Services **GET** `/services` Returns all active services offered. #### Response ```json { "success": true, "data": [ { "id": "uuid", "title": "Web Application Development", "description": "Custom web applications built with modern technologies...", "icon": "code", "features": [ "React/Next.js Frontend", "Go/Java Backend", "REST/GraphQL APIs" ], "order": 1, "active": true, "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z" } ] } ``` --- ### Contact #### Submit Contact Form **POST** `/contact` Content-Type: `application/json` | Field | Type | Required | Validation | |-------|------|----------|------------| | `name` | string | Yes | 2-100 chars | | `email` | string | Yes | Valid email format | | `subject` | string | Yes | 5-200 chars | | `message` | string | Yes | 10-5000 chars | #### Request ```json { "name": "John Doe", "email": "john@example.com", "subject": "Project Inquiry", "message": "Hello, I'd like to discuss a potential project..." } ``` #### Response (201 Created) ```json { "success": true, "data": { "id": "uuid", "name": "John Doe", "email": "john@example.com", "subject": "Project Inquiry", "message": "Hello, I'd like to discuss a potential project...", "status": "new", "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-15T10:30:00Z" } } ``` #### Validation Error (400) ```json { "success": false, "error": { "code": "VALIDATION_ERROR", "message": "Invalid request body", "details": "Key: 'ContactForm.Email' Error:Field validation for 'Email' failed on the 'email' tag" } } ``` --- ## Rate Limiting | Endpoint | Limit | |----------|-------| | `/api/v1/*` (general) | 10 req/s per IP | | `/api/v1/contact` | 5 req/min per IP | | `/api/v1/health` | No limit | Headers returned: - `X-RateLimit-Limit` - `X-RateLimit-Remaining` - `X-RateLimit-Reset` --- ## CORS Allowed origins (configured in `config.yaml`): - `https://www.urpi.be` - `https://urpi.be` - `http://localhost:3000` - `http://localhost:5173` Allowed methods: `GET, POST, PUT, PATCH, DELETE, OPTIONS` Allowed headers: `Origin, Content-Type, Accept, Authorization, X-Requested-With` Credentials: `true` --- ## Versioning API version in URL path: `/api/v1/` Breaking changes will result in `/api/v2/` etc. Non-breaking additions (new fields, new endpoints) may be added to v1. --- ## Authentication Currently **no authentication required** for public endpoints. Future plans: - JWT-based auth for admin endpoints - API keys for programmatic access - OAuth2 for third-party integrations --- ## SDKs / Clients ### JavaScript/TypeScript ```typescript const API_BASE = '/api/v1'; async function fetchAPI(endpoint: string, options: RequestInit = {}): Promise { const res = await fetch(`${API_BASE}${endpoint}`, { headers: { 'Content-Type': 'application/json', ...options.headers }, ...options, }); const data = await res.json(); if (!res.ok || !data.success) throw new Error(data.error?.message || 'Error'); return data.data; } // Usage const skills = await fetchAPI('/skills'); const project = await fetchAPI('/projects/uuid'); await fetchAPI('/contact', { method: 'POST', body: JSON.stringify({ name, email, subject, message }) }); ``` ### Go ```go type APIResponse struct { Success bool `json:"success"` Data interface{} `json:"data,omitempty"` Error *APIError `json:"error,omitempty"` } func GetSkills(ctx context.Context) ([]Skill, error) { req, _ := http.NewRequestWithContext(ctx, "GET", "https://www.urpi.be/api/v1/skills", nil) resp, err := http.DefaultClient.Do(req) // ... parse response } ``` --- ## Changelog ### v1.0.0 (2024-01-15) - Initial API release - Skills, Projects, Experience, Services, Contact endpoints - Rate limiting and CORS configuration - Health check endpoint