User Endpoints (/me)

The /api/v1/me/* namespace covers everything an authenticated user can do for themselves — read their profile, update it, manage their own API tokens. All endpoints require a Sanctum bearer token; rate limited at 120 req/min per user.

GET /api/v1/me

Current user profile.

curl https://your-site.com/api/v1/me \
  -H "Authorization: Bearer USER_TOKEN" \
  -H "Accept: application/json"

Response:

{
  "success": true,
  "message": "Profile retrieved successfully",
  "data": {
    "id": 8,
    "name": "Hamed Pakdaman",
    "email": "[email protected]",
    "avatar": "https://...",
    "locale": "en",
    "email_verified": true,
    "two_factor_enabled": false,
    "created_at": "2026-05-26T00:32:16+00:00"
  }
}

Never returned: password, remember_token, two_factor_secret, two_factor_recovery_codes, raw token values. These are explicitly excluded by the user transformer — there's a security test that guards against accidental leakage.

PATCH /api/v1/me

Update profile. All fields optional — send only what you want to change.

curl -X PATCH https://your-site.com/api/v1/me \
  -H "Authorization: Bearer USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "New Name",
    "locale": "fa"
  }'

Updatable fields: name, email, locale, password.

Changing Password

Requires current_password to be present and correct:

{
  "current_password": "old-password",
  "password": "new-password-min-8-chars",
  "password_confirmation": "new-password-min-8-chars"
}

If current_password is wrong, returns 422 with errors.code: "INVALID_PASSWORD".

Changing Email

If you change email, the email_verified_at is reset to null. The new address needs re-verification before email-gated features work again.

Token Management

Users can issue, list, and revoke their own API tokens. This is how mobile apps register additional devices, and how integrations get long-lived credentials.

GET /api/v1/me/tokens

List all tokens belonging to the current user.

curl https://your-site.com/api/v1/me/tokens \
  -H "Authorization: Bearer USER_TOKEN"

Response:

{
  "success": true,
  "message": "Tokens retrieved successfully",
  "data": [
    {
      "id": 5,
      "name": "iPhone app",
      "abilities": ["user", "comments:write"],
      "last_used_at": "2026-05-26T15:00:00+00:00",
      "expires_at": null,
      "created_at": "2026-05-20T10:00:00+00:00"
    }
  ]
}

The actual token string is never in the list response — only the hashed value is stored server-side. You can only see the plaintext token at creation time.

POST /api/v1/me/tokens

Create a new scoped token.

curl -X POST https://your-site.com/api/v1/me/tokens \
  -H "Authorization: Bearer USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Android app v2",
    "abilities": ["user", "comments:write"]
  }'

Allowed abilities (via API):

  • user
  • comments:write
  • tickets:write
  • newsletter:manage

NOT allowed via API: admin. You can't grant yourself admin via the user endpoint — that requires server-side issuance via php artisan tinker.

Response:

{
  "success": true,
  "message": "Token created successfully",
  "data": {
    "token": "5|abc123XYZ...",
    "token_type": "Bearer",
    "id": 5,
    "name": "Android app v2",
    "abilities": ["user", "comments:write"]
  }
}

Save the token value immediately. It's the only time you'll see it.

DELETE /api/v1/me/tokens/{id}

Revoke a token.

curl -X DELETE https://your-site.com/api/v1/me/tokens/5 \
  -H "Authorization: Bearer USER_TOKEN"

Returns 404 if the token belongs to a different user (this is the only protection against ID enumeration — the response is identical for "doesn't exist" and "not yours").

Auth Flow Endpoints

These live at /api/v1/auth/* (no /me prefix) but are part of the user surface:

Endpoint Method Description
/api/v1/auth/register POST Create account, return token
/api/v1/auth/login POST Email + password → token
/api/v1/auth/logout POST Revoke current token

See Authentication for the full flow.