- Add RefreshToken model with rotation - Add POST /auth/refresh endpoint - Add POST /auth/logout that revokes refresh token - Login returns JWT (8h) + refresh_token (30 days) - Refresh rotates token (old is revoked) - Fix Carbon\Carbon::now() calls instead of now() helper - Update API docs
3.0 KiB
3.0 KiB
DriveTime Planner API
Base URL
https://api.fahrschultermin.de/api/v1
Authentication
JWT Bearer Token. Login returns a token valid for 8 hours.
Authorization: Bearer <token>
Endpoints
Auth
| Method | Path | Description |
|---|---|---|
| POST | /auth/login |
Login with email/password, returns JWT + refresh_token |
| POST | /auth/refresh |
Exchange refresh_token for new JWT + refresh_token |
| POST | /auth/logout |
Revoke refresh token (logout) |
| GET | /auth/me |
Current user info (requires auth) |
Bootstrap
| Method | Path | Description |
|---|---|---|
| GET | /bootstrap |
Full frontend data: user, tenant, students, instructors, lessonTypes, templates (requires auth) |
CRUD
| Method | Path | Description |
|---|---|---|
| GET | /students |
List students (requires auth) |
| POST | /students |
Create student (requires auth) |
| PATCH | /students/{id} |
Update student (requires auth) |
| DELETE | /students/{id} |
Delete student (requires auth) |
| GET | /instructors |
List instructors (requires auth) |
| POST | /instructors |
Create instructor (requires auth) |
| PATCH | /instructors/{id} |
Update instructor (requires auth) |
| GET | /appointments |
List appointments, optionally filter by from/to query params (requires auth) |
| POST | /appointments |
Create appointment with instructor conflict detection (requires auth) |
| PATCH | /appointments/{id} |
Update appointment with conflict check (requires auth) |
| DELETE | /appointments/{id} |
Delete appointment (requires auth) |
| GET | /lesson-types |
List lesson types (requires auth) |
| GET | /license-class-templates |
List license class templates with requirements (requires auth) |
Error Responses
| Code | Meaning |
|---|---|
| 400 | Bad Request — missing or invalid parameters |
| 401 | Unauthorized — missing or invalid JWT |
| 404 | Not Found — resource doesn't exist or wrong tenant |
| 409 | Conflict — e.g. instructor has overlapping appointment |
| 500 | Internal Server Error |
Environment Variables
| Variable | Description |
|---|---|
JWT_SECRET |
256-bit secret for JWT signing (required) |
Example
# Login
TOKEN=$(curl -s -X POST https://api.fahrschultermin.de/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin@nordring.test","password":"Tanja82"}' | jq -r '.token')
# Get bootstrap data
curl https://api.fahrschultermin.de/api/v1/bootstrap \
-H "Authorization: Bearer $TOKEN" | jq .
# Create appointment
curl -X POST https://api.fahrschultermin.de/api/v1/appointments \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"instructor_id":1,"lesson_type_id":1,"start_at":"2026-05-25 10:00","end_at":"2026-05-25 11:00","title":"Test"}'
Tech Stack
- Slim 4 (PSR-7 HTTP factory)
- Eloquent ORM (Illuminate Database)
- Firebase JWT for authentication
- PHP-DI for dependency injection
- CORS middleware (tuupola/cors-middleware)