Documentation Index Fetch the complete documentation index at: https://mintlify.com/astrxnomo/tourify/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Tourify authenticates API requests using Laravel Sanctum bearer tokens . There are no session cookies — every protected request must include a token in the Authorization header. On the mobile client the token is persisted securely using Expo SecureStore (or localStorage on web), so it survives app restarts without requiring the user to log in again.
All protected endpoints require the Authorization: Bearer {your-token} header. Requests made without a valid token will receive a 401 Unauthenticated response.
Endpoints
POST /api/auth/register
Create a new user account. On success the API returns the new user object and a Sanctum plain-text token that can be used immediately.
Required fields
The user’s display name. Maximum 255 characters.
A unique, valid e-mail address.
Must match password exactly.
curl -s -X POST http://localhost:8000/api/auth/register \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"name": "María García",
"email": "maria@example.com",
"password": "secret123",
"password_confirmation": "secret123"
}'
POST /api/auth/login
Authenticate an existing user and receive a new Sanctum token.
Required fields
The user’s registered e-mail address.
cURL
Response (200)
Response (422 — wrong credentials)
curl -s -X POST http://localhost:8000/api/auth/login \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"email": "maria@example.com",
"password": "secret123"
}'
GET /api/auth/me
Returns the currently authenticated user with their role loaded. Requires authentication.
curl -s http://localhost:8000/api/auth/me \
-H "Accept: application/json" \
-H "Authorization: Bearer 15|xYzAbCdEfGhIjKlMnOpQrStUvWx0987654321"
POST /api/auth/logout
Deletes the current access token, effectively invalidating it on the server. Requires authentication.
curl -s -X POST http://localhost:8000/api/auth/logout \
-H "Accept: application/json" \
-H "Authorization: Bearer 15|xYzAbCdEfGhIjKlMnOpQrStUvWx0987654321"
POST /api/auth/forgot-password
Initiates a password-reset flow for the given e-mail address.
The e-mail address associated with the account.
This endpoint always returns a success message regardless of whether the e-mail exists in the database. This is intentional — it prevents attackers from enumerating which e-mail addresses are registered with Tourify.
curl -s -X POST http://localhost:8000/api/auth/forgot-password \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"email": "maria@example.com"}'
Token storage on the client
After a successful login or registration the frontend persists the token using a thin wrapper around Expo SecureStore (native) and localStorage (web). The token is keyed as "auth_token".
import * as SecureStore from "expo-secure-store" ;
import { Platform } from "react-native" ;
const isWeb = Platform . OS === "web" ;
export const storage = {
getItem : ( key ) =>
isWeb
? Promise . resolve ( localStorage . getItem ( key ))
: SecureStore . getItemAsync ( key ),
setItem : ( key , value ) =>
isWeb
? Promise . resolve ( localStorage . setItem ( key , value ))
: SecureStore . setItemAsync ( key , value ),
deleteItem : ( key ) =>
isWeb
? Promise . resolve ( localStorage . removeItem ( key ))
: SecureStore . deleteItemAsync ( key ),
};
Every API call reads the stored token and injects it into the Authorization header automatically:
import { storage } from "./storage" ;
const API_URL = "http://localhost:8000/api" ;
async function getAuthHeaders () {
const token = await storage . getItem ( "auth_token" );
return {
"Content-Type" : "application/json" ,
Accept: "application/json" ,
... ( token ? { Authorization: `Bearer ${ token } ` } : {}),
};
}
async function request ( endpoint , method , data ) {
const headers = await getAuthHeaders ();
const options = { method , headers };
if ( data !== undefined ) options . body = JSON . stringify ( data );
const response = await fetch ( ` ${ API_URL }${ endpoint } ` , options );
const json = await response . json ();
if ( ! response . ok ) {
const message =
json . message ||
Object . values ( json . errors || {})[ 0 ]?.[ 0 ] ||
"Error en la solicitud" ;
throw new Error ( message );
}
return json ;
}
export const post = ( endpoint , data ) => request ( endpoint , "POST" , data );
export const get = ( endpoint ) => request ( endpoint , "GET" );
export const patch = ( endpoint , data = {}) => request ( endpoint , "PATCH" , data );
export const del = ( endpoint , data ) => request ( endpoint , "DELETE" , data );
The useLogin and useRegister hooks call storage.setItem("auth_token", data.token) immediately after a successful API response:
import { useCallback , useState } from "react" ;
import { Alert } from "react-native" ;
import { post } from "../services/post" ;
import { storage } from "../services/storage" ;
export function useLogin () {
const [ email , setEmail ] = useState ( "" );
const [ password , setPassword ] = useState ( "" );
const [ loading , setLoading ] = useState ( false );
const [ error , setError ] = useState ( null );
const handleLogin = useCallback (
async ( onSuccess ) => {
if ( ! email . trim () || ! password . trim ()) {
Alert . alert ( "Error" , "Por favor completa todos los campos." );
return ;
}
setLoading ( true );
setError ( null );
try {
const data = await post ( "/auth/login" , { email , password });
await storage . setItem ( "auth_token" , data . token ); // ← persisted here
onSuccess ?.( data );
} catch ( err ) {
setError ( err . message );
Alert . alert ( "Error" , err . message || "No se pudo iniciar sesión." );
} finally {
setLoading ( false );
}
},
[ email , password ],
);
return { email , setEmail , password , setPassword , loading , error , handleLogin };
}
Authentication flow summary
Register or log in
Call POST /api/auth/register or POST /api/auth/login. Both return { user, token }.
Persist the token
Store the token with storage.setItem("auth_token", token). On native devices this writes to Expo SecureStore; on web it writes to localStorage.
Attach the token to every request
getAuthHeaders() reads the token from storage and adds Authorization: Bearer {token} to each fetch call automatically.
Access protected endpoints
Any route inside the auth:sanctum middleware group — favorites, reviews, notifications, event registrations — will accept the request.
Log out
Call POST /api/auth/logout. The server deletes the token; remove it from local storage as well.