curl -X POST "https://gachabe-staging.fly.dev/api/v1/players/sign_in" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{
    "data": {
      "type": "player",
      "attributes": {
        "email": "player@example.com",
        "password": "SecurePassword123!"
      },
      "relationships": {}
    }
  }'
{
  "data": {
    "type": "player",
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "attributes": {
      "email": "player@example.com",
      "is_anonymous": false
    },
    "relationships": {
      "chests": {
        "data": [
          {
            "type": "chest",
            "id": "chest_001"
          },
          {
            "type": "chest",
            "id": "chest_002"
          }
        ]
      }
    }
  },
  "included": [
    {
      "type": "chest",
      "id": "chest_001",
      "attributes": {
        "name": "Dragon Chest",
        "description": "Contains dragon-themed collectibles"
      }
    }
  ],
  "meta": {
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "refresh_token": "refresh_token_string_here",
    "token_type": "Bearer",
    "expires_in": 3600,
    "signed_in_at": "2024-01-15T16:00:00Z",
    "last_active": "2024-01-14T10:30:00Z",
    "session_info": {
      "ip_address": "192.168.1.1",
      "user_agent": "Mozilla/5.0...",
      "device_type": "web"
    },
    "account_status": {
      "verified": true,
      "created_at": "2024-01-10T09:00:00Z",
      "total_sessions": 15
    }
  }
}
Authenticate an existing registered player using email and password credentials. Returns access tokens for API authentication.

Query Parameters

include
string
Include related data in the response.Available includes: chests
fields
object
Limit response fields to only those specified.

Request Body

data
object
required
Player sign-in credentials
curl -X POST "https://gachabe-staging.fly.dev/api/v1/players/sign_in" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{
    "data": {
      "type": "player",
      "attributes": {
        "email": "player@example.com",
        "password": "SecurePassword123!"
      },
      "relationships": {}
    }
  }'
{
  "data": {
    "type": "player",
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "attributes": {
      "email": "player@example.com",
      "is_anonymous": false
    },
    "relationships": {
      "chests": {
        "data": [
          {
            "type": "chest",
            "id": "chest_001"
          },
          {
            "type": "chest",
            "id": "chest_002"
          }
        ]
      }
    }
  },
  "included": [
    {
      "type": "chest",
      "id": "chest_001",
      "attributes": {
        "name": "Dragon Chest",
        "description": "Contains dragon-themed collectibles"
      }
    }
  ],
  "meta": {
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "refresh_token": "refresh_token_string_here",
    "token_type": "Bearer",
    "expires_in": 3600,
    "signed_in_at": "2024-01-15T16:00:00Z",
    "last_active": "2024-01-14T10:30:00Z",
    "session_info": {
      "ip_address": "192.168.1.1",
      "user_agent": "Mozilla/5.0...",
      "device_type": "web"
    },
    "account_status": {
      "verified": true,
      "created_at": "2024-01-10T09:00:00Z",
      "total_sessions": 15
    }
  }
}

Response Fields

data
object
required
The authenticated player resource
meta
object
required
Authentication tokens and session information

Authentication Flow

1

Collect credentials

Prompt the user for their registered email and password.
Implement client-side email format validation before submission.
2

Submit sign-in request

Send the email and password to this endpoint.
Never store or log passwords in plain text.
3

Handle authentication response

Store the returned tokens securely for future API calls.
Successful authentication provides both access and refresh tokens.
4

Redirect to application

Direct the authenticated player to the main game interface.
The player’s chests and progress are now accessible via the API.

Token Management

class AuthManager {
  static storeTokens(tokens) {
    localStorage.setItem('access_token', tokens.access_token);
    localStorage.setItem('refresh_token', tokens.refresh_token);
    localStorage.setItem('token_expires', 
      new Date(Date.now() + tokens.expires_in * 1000).toISOString()
    );
  }
  
  static getAccessToken() {
    const token = localStorage.getItem('access_token');
    const expires = localStorage.getItem('token_expires');
    
    if (expires && new Date(expires) < new Date()) {
      // Token expired, need to refresh
      return null;
    }
    
    return token;
  }
  
  static makeAuthenticatedRequest(url, options = {}) {
    const token = this.getAccessToken();
    if (!token) {
      throw new Error('No valid access token');
    }
    
    return fetch(url, {
      ...options,
      headers: {
        ...options.headers,
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/vnd.api+json'
      }
    });
  }
}

Error Scenarios

Status: 401 UnauthorizedEmail doesn’t exist or password is incorrect.Solution: Show a generic “invalid credentials” message to avoid revealing which field is incorrect.

Security Best Practices

Implement rate limiting on the client side to prevent rapid-fire sign-in attempts that could lock the account.
Successful sign-in returns the player’s current state, including any chests they own and their progress in the game.
Use the include=chests parameter to immediately load the player’s inventory after sign-in, reducing subsequent API calls.