diff --git a/app/Http/Controllers/BikeController.php b/app/Http/Controllers/BikeController.php
new file mode 100644
index 0000000000000000000000000000000000000000..1baf9862bfffe2c5685a21302b16083fdec473cf
--- /dev/null
+++ b/app/Http/Controllers/BikeController.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Models\Bike;
+use Illuminate\Http\Request;
+
+class BikeController extends Controller
+{
+    public function unlockBike(Bike $bike){
+        return true;
+    }
+
+    public function reserveBike(Bike $bike){
+        return true;
+    }
+}
diff --git a/app/Http/Controllers/ElectricBikeController.php b/app/Http/Controllers/ElectricBikeController.php
new file mode 100644
index 0000000000000000000000000000000000000000..cc434340db9af7627ecbc476cce0273dfb2ae7c0
--- /dev/null
+++ b/app/Http/Controllers/ElectricBikeController.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use Illuminate\Http\Request;
+
+class ElectricBikeController extends Controller
+{
+    //
+}
diff --git a/app/Http/Controllers/MapboxApiClient.php b/app/Http/Controllers/MapboxApiClient.php
new file mode 100644
index 0000000000000000000000000000000000000000..a519e37bfb03ade25b0d4cd3aea2dc964f44c73c
--- /dev/null
+++ b/app/Http/Controllers/MapboxApiClient.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Models\Stop;
+use Illuminate\Support\Facades\Http;
+
+class MapboxApiClient extends Http
+{
+    private String $url;
+    public function __construct(Stop $init, Stop $end)
+    {
+        $lng1 = $init->lng;
+        $lng2 = $end->lng;
+        $lat1 = $init->lat;
+        $lat2 = $end->lat;
+        $coordinates = $lng1.",".$lat1.";".$lng2.",".$lat2;
+        $token = env('MAPBOX_TOKEN', null);
+        $this->url = "https://api.mapbox.com/directions/v5/mapbox/cycling/${coordinates}?alternatives=false&geometries=geojson&overview=full&steps=false&access_token=".$token;
+    }
+    public function buildRequest(){
+        return $this->url;
+    }
+}
\ No newline at end of file
diff --git a/app/Http/Controllers/ReservationController.php b/app/Http/Controllers/ReservationController.php
new file mode 100644
index 0000000000000000000000000000000000000000..f7b61325184be61949f2f4648b0a9f98b37dca86
--- /dev/null
+++ b/app/Http/Controllers/ReservationController.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use Illuminate\Http\Request;
+
+class ReservationController extends Controller
+{
+    //
+}
diff --git a/app/Http/Controllers/RewardController.php b/app/Http/Controllers/RewardController.php
new file mode 100644
index 0000000000000000000000000000000000000000..2385698eb53522d7c3c3921b434671023af9d632
--- /dev/null
+++ b/app/Http/Controllers/RewardController.php
@@ -0,0 +1,53 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Http\Resources\RewardResource;
+use App\Http\Resources\RewardResourceObtained;
+use App\Models\Reward;
+use App\Models\User;
+use Illuminate\Http\Request;
+
+class RewardController extends Controller
+{
+    public function getAllRewards(){
+        return RewardResource::collection(Reward::all());
+    }
+
+    public function getNotRedeemedRewards(Request $request){
+        $user = UserController::getUserByToken($request);
+        $userR = $user->rewards()->get(['user_reward.reward_id AS result'])->pluck('result');
+        return RewardResource::collection(Reward::all()->whereNotIn('id',$userR));
+    }
+
+    public function getUserRewards(Request $request){
+        $user = UserController::getUserByToken($request);
+        return RewardResourceObtained::collection($user->rewards()->orderByPivot('created_at', 'desc')->get());
+    }
+
+    public function obtainReward(Request $request, Reward $reward){
+        $user = UserController::getUserByToken($request);
+        if ($this->checkReward($user,$reward)){
+            $reward->redeemed += 1;
+            $reward->users()->attach($user);
+            $user->points -= $reward->points;
+            $reward->save();
+            $user->save();
+            return new RewardResourceObtained($reward);
+        }
+        return response()->json("Unable to redeem the reward", 500);
+    }
+
+    private function checkReward(User $user, Reward $reward){
+        if ($reward->total_available <= $reward->redeemed){
+            return false;
+        }
+        if ($user->rewards()->find($reward)){
+            return false;
+        }
+        if ($user->points < $reward->points){
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/app/Http/Controllers/RouteController.php b/app/Http/Controllers/RouteController.php
new file mode 100644
index 0000000000000000000000000000000000000000..7ac0e9ad6c44053ac631f317647649a411f3272a
--- /dev/null
+++ b/app/Http/Controllers/RouteController.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Http\Resources\RouteResource;
+use App\Models\Bike;
+use App\Models\ElectricBike;
+use App\Models\Route;
+use App\Models\Stop;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Http;
+use PhpParser\Node\Expr\Cast\Int_;
+
+class RouteController extends Controller
+{
+    public function createRoute(Request $request, Bike $bike){
+        $user = UserController::getUserByToken($request);
+        $route = new Route;
+        $route->user_id = $user->id;
+        $route->initial_stop_id = $bike->stop()->first()->id;
+        $route->bike_id = $bike->id;
+        $route->save();
+        //Remove any user reservation
+        $reservation = $user->reservations()->first();
+        $reservation?->delete();
+        //Free the bike from the Stop
+        $bike->stop_id = null;
+        $bike->save();
+
+        return new RouteResource($route);
+    }
+
+    public function finishRoute(Request $request){
+        $route = Route::find($request->id);
+        if($request->missing(['duration', 'final_stop'])){
+            //TODO manage Errors
+            return false;
+        }
+
+        $initial_stop = Stop::find($route->initial_stop_id);
+        $final_stop = Stop::find($request->final_stop);
+        $mapboxClient = new MapboxApiClient($initial_stop,$final_stop);
+        $url = $mapboxClient->buildRequest();
+        $response = Http::get($url);
+        $mapbox_response = $response->json();
+        $distance = $response->json('routes')[0]['distance'];
+        $estimated_duration = $response->json('routes')[0]['duration'];
+
+        $route->final_stop_id = intval($request->final_stop);
+        $route->duration = intval($request->duration);
+        $route->mapbox_response = $mapbox_response;
+        $route->distance = intval($distance);
+        $route->estimated_duration = intval($estimated_duration);
+        $route->points = $this->calculatePoints($route);
+        $route->save();
+
+        $user = UserController::getUserByToken($request);
+        $user->points += $route->points;
+        $user->save();
+
+        $bike = $route->bike()->first();
+        $bike->stop_id = $route->final_stop_id;
+        $bike->save();
+
+        return new RouteResource($route);
+    }
+
+    private function calculatePoints($route): Int{
+        return 50;
+    }
+}
diff --git a/app/Http/Controllers/StopController.php b/app/Http/Controllers/StopController.php
new file mode 100644
index 0000000000000000000000000000000000000000..1d8f149a401a7e40cbd5f31977e192a6599b20a5
--- /dev/null
+++ b/app/Http/Controllers/StopController.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Http\Resources\BikeResource;
+use App\Http\Resources\StopResource;
+use App\Models\Bike;
+use App\Models\ElectricBike;
+use App\Models\Reservation;
+use App\Models\Stop;
+use Illuminate\Http\JsonResponse;
+use Illuminate\Http\Request;
+
+class StopController extends Controller
+{
+    public function getAllStops(){
+        return StopResource::collection(Stop::all());
+    }
+
+    public function unlockBike(Request $request, Bike $bike){
+        $user = UserController::getUserByToken($request);
+        $stop = $bike->stop()->first();
+        $type = $bike->bikeable_type;
+        $bikes = $stop->bikes()->get()->where('bikeable_type', '=', $type);
+        $reservation = $user->reservations()->first();
+        if ($type=='App\Models\ElectricBike'){
+            $typable = 'electric';
+        }else{
+            $typable = 'pedal';
+        }
+        if (($reservation!=null && $reservation->bike_type==$typable) || $stop->check_availability_bikes($type)){
+            return new BikeResource($bikes->first());
+        }else{
+            return response()->json("No bikes available", 500);
+        }
+    }
+
+    public function lockBike(Stop $stop){
+        if ($stop->total_spaces>0){
+            return new StopResource($stop);
+        }
+        else{
+            return "No space available";
+        }
+    }
+
+    public function reserveBike(Request $request, Stop $stop, String $type){
+        if ($stop->check_availability_bikes($type)){
+            $user = UserController::getUserByToken($request);
+            $reservation = new Reservation();
+            $reservation->user_id = $user->id;
+            $reservation->stop_id = $stop->id;
+            $reservation->bike_type = $type;
+            $reservation->save();
+            return new StopResource($stop);
+        }
+        else{
+            return response()->json("No bikes available for reservation", 500);
+        }
+    }
+}
diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php
new file mode 100644
index 0000000000000000000000000000000000000000..90d8a6f49dfa494a14bea477d25564758077830e
--- /dev/null
+++ b/app/Http/Controllers/UserController.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Models\User;
+use Illuminate\Http\Request;
+use Laravel\Sanctum\PersonalAccessToken;
+
+class UserController extends Controller
+{
+    public static function getUserByToken(Request $request):User|null
+    {
+        $token = PersonalAccessToken::findToken($request->bearerToken());
+        return ($token != null) ? $token->tokenable : null;
+    }
+}
diff --git a/app/Http/Resources/BikeResource.php b/app/Http/Resources/BikeResource.php
new file mode 100644
index 0000000000000000000000000000000000000000..ac1068f3bbace1a8409f796fa5a773b0f55d516a
--- /dev/null
+++ b/app/Http/Resources/BikeResource.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace App\Http\Resources;
+
+use Illuminate\Http\Resources\Json\JsonResource;
+
+class BikeResource extends JsonResource
+{
+    /**
+     * Transform the resource into an array.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
+     */
+    public function toArray($request)
+    {
+        if ($this->bikeable_type == "App\\Models\\ElectricBike"){
+            $battery = $this->bikeable->battery;
+            $resource = [
+                'bike_id' => $this->id,
+                'unlocked' => $this->unlocked,
+                'battery' => $battery
+            ];
+        }
+        else{
+            $resource = [
+                'bike_id' => $this->id,
+                'unlocked' => $this->unlocked,
+            ];
+        }
+
+        return $resource;
+    }
+}
diff --git a/app/Http/Resources/ElectricBikeResource.php b/app/Http/Resources/ElectricBikeResource.php
new file mode 100644
index 0000000000000000000000000000000000000000..56a6caf63e8c71f5fac0e083e0988c71dca22dbb
--- /dev/null
+++ b/app/Http/Resources/ElectricBikeResource.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace App\Http\Resources;
+
+use Illuminate\Http\Resources\Json\JsonResource;
+
+class ElectricBikeResource extends JsonResource
+{
+    /**
+     * Transform the resource into an array.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
+     */
+    public function toArray($request)
+    {
+        return parent::toArray($request);
+    }
+}
diff --git a/app/Http/Resources/RewardResource.php b/app/Http/Resources/RewardResource.php
new file mode 100644
index 0000000000000000000000000000000000000000..0b5c2eca7b3a447b8826a814dddd498940b919b1
--- /dev/null
+++ b/app/Http/Resources/RewardResource.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace App\Http\Resources;
+
+use Illuminate\Http\Resources\Json\JsonResource;
+
+class RewardResource extends JsonResource
+{
+    /**
+     * Transform the resource into an array.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
+     */
+    public function toArray($request)
+    {
+        return [
+            "id"=> $this->id,
+            "title"=> $this->name,
+            "description"=> $this->description,
+            "points"=> $this->points,
+            "image" => $this->image,
+        ];
+    }
+}
diff --git a/app/Http/Resources/RewardResourceObtained.php b/app/Http/Resources/RewardResourceObtained.php
new file mode 100644
index 0000000000000000000000000000000000000000..4beaa7fd82495d758bc013f4b4ad2a0cc6be6306
--- /dev/null
+++ b/app/Http/Resources/RewardResourceObtained.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace App\Http\Resources;
+
+use Illuminate\Http\Resources\Json\JsonResource;
+
+class RewardResourceObtained extends JsonResource
+{
+    /**
+     * Transform the resource into an array.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
+     */
+    public function toArray($request)
+    {
+        return [
+            "id"=> $this->id,
+            "title"=> $this->name,
+            "description"=> $this->description,
+            "points"=> $this->points,
+            "image" => $this->image,
+            "obtained" => true,
+        ];
+    }
+}
diff --git a/app/Http/Resources/RouteResource.php b/app/Http/Resources/RouteResource.php
new file mode 100644
index 0000000000000000000000000000000000000000..ab74d0556540e4b18db48d3137df387da810063d
--- /dev/null
+++ b/app/Http/Resources/RouteResource.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace App\Http\Resources;
+
+use Illuminate\Http\Resources\Json\JsonResource;
+
+class RouteResource extends JsonResource
+{
+    /**
+     * Transform the resource into an array.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
+     */
+    public function toArray($request)
+    {
+        return [
+            'id' => $this->id,
+            'user_id' => $this->user_id,
+            'bike' => new BikeResource($this->bike()->first()),
+            'initial_stop_id' => $this->initial_stop_id,
+            'final_stop_id' => $this->final_stop_id,
+            'distance' => $this->distance,
+            'duration' => $this->duration,
+            'points' => $this->points,
+        ];
+    }
+}
diff --git a/app/Http/Resources/StopResource.php b/app/Http/Resources/StopResource.php
new file mode 100644
index 0000000000000000000000000000000000000000..22311eafd43c4684032bd9e02db6526f5bbb82aa
--- /dev/null
+++ b/app/Http/Resources/StopResource.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace App\Http\Resources;
+
+use Illuminate\Http\Resources\Json\JsonResource;
+
+class StopResource extends JsonResource
+{
+    /**
+     * Transform the resource into an array.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
+     */
+    public function toArray($request)
+    {
+        return [
+            'id' => $this->id,
+            'lng' => $this->lng,
+            'lat' => $this->lat,
+            'address' => $this->address,
+            'totalSpaces' => $this->total_spaces,
+            'reserved_pedal_bikes' => $this->reserved_pedal_bikes(),
+            'reserved_electric_bikes' => $this->reserved_electric_bikes(),
+            'bikes' => BikeResource::collection($this->bikes()->get()),
+        ];
+    }
+}
diff --git a/app/Models/Reservation.php b/app/Models/Reservation.php
new file mode 100644
index 0000000000000000000000000000000000000000..f74a1b508f74766b25bb2dc216feffa59551232c
--- /dev/null
+++ b/app/Models/Reservation.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+/**
+ * @property mixed $user_id
+ * @property mixed $stop_id
+ * @property mixed|String $bike_type
+ */
+class Reservation extends Model
+{
+    use HasFactory;
+
+    public function user(): BelongsTo{
+        return $this->belongsTo(Route::class);
+    }
+
+    public function stop(): BelongsTo{
+        return $this->belongsTo(Stop::class);
+    }
+}
diff --git a/database/migrations/2022_06_20_140941_add_points_field_on_users_table.php b/database/migrations/2022_06_20_140941_add_points_field_on_users_table.php
new file mode 100644
index 0000000000000000000000000000000000000000..49618aff91441215939f905f83595377f39e1734
--- /dev/null
+++ b/database/migrations/2022_06_20_140941_add_points_field_on_users_table.php
@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('users', function (Blueprint $table){
+           $table->integer('points')->after('password')->default(0);
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('users', function (Blueprint $table){
+            $table->dropColumn('points');
+        });
+    }
+};
diff --git a/database/migrations/2022_06_26_185339_create_reservations_table.php b/database/migrations/2022_06_26_185339_create_reservations_table.php
new file mode 100644
index 0000000000000000000000000000000000000000..e34ab1bce27cdc032d69804ee0ee8f278960ee5e
--- /dev/null
+++ b/database/migrations/2022_06_26_185339_create_reservations_table.php
@@ -0,0 +1,34 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('reservations', function (Blueprint $table) {
+            $table->id();
+            $table->foreignId('user_id');
+            $table->foreignId('stop_id');
+            $table->string('bike_type');
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('reservations');
+    }
+};
diff --git a/routes/api.php b/routes/api.php
index 0276c009f2c0703dbd916195c7847262a4aad3d1..cbac4b3daef2729496acd31cd742db9465b4f5dd 100644
--- a/routes/api.php
+++ b/routes/api.php
@@ -1,13 +1,9 @@
 <?php
 
 use App\Http\Controllers\AuthController;
-use App\Http\Controllers\BikeController;
 use App\Http\Controllers\RewardController;
 use App\Http\Controllers\RouteController;
 use App\Http\Controllers\StopController;
-use App\Http\Resources\BikeResource;
-use App\Http\Resources\RewardColletion;
-use App\Models\Bike;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Route;