A clean, RESTful Task Management API built with Laravel 13
Taskify is a production-ready task management API with token-based authentication, per-user task isolation, filtering, and rate limiting — fully documented with interactive OpenAPI docs.
- 🔐 Sanctum token auth — 24-hour token expiry, revocable via logout
- 📝 Full CRUD with soft delete & restore
- 🔍 Smart filtering — exact
status/priorityfilters + case-insensitive search - 👤 Per-user isolation — tasks are private to their owner
- 🚦 Rate limiting — auth (5/min) & API (60/min)
- 📚 Interactive docs via Scramble
- 🗃️ PostgreSQL + Docker setup included
- Requirements
- Installation
- Running Tests
- Project Structure
- API Reference
- Authentication
- Tasks
- Status Codes
- Rate Limits
- Documentation
- Deployment
- License
- Developed By
| Tool | Version |
|---|---|
| PHP | 8.3+ |
| Composer | latest |
| PostgreSQL | 16 (or any Laravel-supported DB) |
| Node.js | optional (frontend assets only) |
git clone https://github.com/MahdiiMax/taskify.git taskify
cd taskify
composer install
cp .env.example .env
php artisan key:generate
php artisan migrate
php artisan serve💡 Tip: run
composer run setupto do all of the above automatically.
A docker-compose.yaml spins up PostgreSQL (db taskify, user/password admin/admin) and pgAdmin at http://localhost:5050 (login: admin@admin.com / admin):
docker compose up -dThen configure .env:
DB_CONNECTION=pgsqlDB_DATABASE=taskifyDB_USERNAME=adminDB_PASSWORD=adminAUTH_GUARD=sanctumSANCTUM_EXPIRATION=1440| Key | Purpose |
|---|---|
AUTH_GUARD=sanctum | Makes $request->user() resolve API tokens |
SANCTUM_EXPIRATION=1440 | Token lifetime in minutes (24h) |
composer test# or: php artisan testThe suite runs on in-memory SQLite — no DB server needed.
If you want to run tests in your own PostgreSQL server:
php artisan test --env=pgsqlapp/
├── Enums/ # TaskPriority, TaskStatus
├── Http/
│ ├── Controllers/Api/V1/ # AuthController, TaskController
│ ├── Middleware/Api/V1/ # GuestMiddleware
│ ├── Requests/Api/V1/ # Auth/ & Task/ Form Requests
│ └── Resources/Api/V1/ # TaskResource, UserResource
├── Models/ # Task, User
├── Policies/ # TaskPolicy
└── Providers/ # AppServiceProvider
routes/
└── api.php # v1 API routes
tests/
├── Feature/Api/V1/ # AuthTest, TaskTest
| Base URL | http://localhost:8000/api/v1 |
|---|---|
| Interactive docs | http://localhost:8000/docs/api |
All task endpoints require a Bearer token:
Authorization: Bearer {token}
Tokens are issued by login, live 24 hours, and are revoked by logout.
{
"name": "Jane Doe",
"email": "jane@example.com",
"password": "password123",
"password_confirmation": "password123"
}
201→{ "message", "user": { "id", "name", "email", "created_at" } }
{
"email": "jane@example.com",
"password": "password123"
}
200→{ "message", "user": {...}, "token": "<plain token>" }
200→{ "message": "logged out successfully" }(revokes the current token)
| Method | Endpoint | Description |
|---|---|---|
| GET | /tasks | List own tasks (paginated, 10/page) |
| POST | /tasks | Create a task |
| GET | /tasks/{task} | Show a task |
| PUT/PATCH | /tasks/{task} | Update a task |
| DELETE | /tasks/{task} | Soft delete a task |
| GET | /tasks/trashed | List soft-deleted tasks |
| POST | /tasks/{task}/restore | Restore a soft-deleted task |
| Field | Rules |
|---|---|
title | required · string · max 255 |
description | nullable · string |
status | nullable — pending · in_progress · done |
priority | nullable — low · medium · high |
due_date | nullable · date · today or later |
| Query | Example | Behavior |
|---|---|---|
status | ?status=pending | exact match |
priority | ?priority=high | exact match |
search | ?search=buy milk | case-insensitive partial match on title/description |
Invalid status/priority values → 422.
| Code | Meaning |
|---|---|
200 | Success |
201 | Created |
400 | Already authenticated (on login/register) |
401 | Unauthenticated / expired or revoked token |
403 | Forbidden (another user's resource) |
422 | Validation error |
429 | Rate limit exceeded |
| Scope | Limit |
|---|---|
| Auth routes (login/register) | 5/min per email + IP |
| All API routes | 60/min per user (or IP) |
Interactive API docs rendered with Stoplight Elements (dark theme):
| Docs UI | http://localhost:8000/docs/api |
|---|---|
| OpenAPI spec | http://localhost:8000/docs/api.json(OpenAPI 3.1, served live) |
Export the spec to a file:
php artisan scramble:export # writes api.jsonapi.json is a standard OpenAPI document — import it into Insomnia or Postman to explore and test the API.
- Run
php artisan config:cache/route:cacheonly in production — in development a stale config cache can serve outdated settings. - Warm the docs cache with
php artisan scramble:cache. - Expired tokens stay in the DB until pruned — schedule
php artisan sanctum:prune-expired(daily viaroutes/console.php+ theschedule:runcron) to keep the table clean.
This project is open-sourced under the MIT License — © 2026 Mahdi Sadeghi.
Mahdi Sadeghi
Full-Stack Developer
Built with ❤️ and ☕ using Laravel