Skip to main content

Authentication

Authentication endpoints for AsaHome Cloud.

Endpoints Overview

MethodEndpointDescriptionAuth
POST/auth/loginLogin and get tokensNo
POST/auth/refreshRefresh access tokenNo
POST/auth/logoutLogout and revoke tokenYes
POST/auth/sync-customerSync customer from LaravelAPI Key

Base URL: https://cloud.asahome.io/api/v1


POST Login

Authenticate a user and receive JWT tokens.

Request

POST /api/v1/auth/login

Request Body

FieldTypeRequiredDescription
emailstringYesUser email address
passwordstringYesUser password

Example

curl -X POST "https://cloud.asahome.io/api/v1/auth/login" \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "yourPassword123"
}'

Response

{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 900,
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"firstName": "John",
"lastName": "Doe",
"role": "user"
}
}

Token Specifications

TokenLifetimePurpose
accessToken15 minutesAPI authentication
refreshToken30 daysObtain new access tokens

Error Responses

Invalid Credentials (401)

{
"statusCode": 401,
"message": "Invalid email or password",
"error": "Unauthorized"
}

Account Inactive (403)

{
"statusCode": 403,
"message": "Account is inactive",
"error": "Forbidden"
}

POST Refresh Token

Exchange a refresh token for new access and refresh tokens.

Request

POST /api/v1/auth/refresh

Request Body

FieldTypeRequiredDescription
refreshTokenstringYesValid refresh token

Example

curl -X POST "https://cloud.asahome.io/api/v1/auth/refresh" \
-H "Content-Type: application/json" \
-d '{
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}'

Response

{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 900
}
Token Rotation

Each refresh invalidates the previous refresh token and issues a new one. Store the new refresh token for future refreshes.

Error Responses

Token Expired (401)

{
"statusCode": 401,
"message": "Refresh token has expired",
"error": "Unauthorized"
}

Token Revoked (401)

{
"statusCode": 401,
"message": "Refresh token has been revoked",
"error": "Unauthorized"
}

POST Logout

Invalidate the current session by revoking the refresh token.

Request

POST /api/v1/auth/logout

Headers

HeaderRequiredDescription
AuthorizationYesBearer <accessToken>

Example

curl -X POST "https://cloud.asahome.io/api/v1/auth/logout" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response

{
"message": "Successfully logged out"
}
tip

After logout, the access token remains valid until expiry (up to 15 minutes). For immediate invalidation, implement client-side token removal.


POST Sync Customer

Synchronize customer data from an external Laravel application. This endpoint creates or updates a user based on the Laravel customer data.

Authentication

This endpoint uses internal API key authentication instead of JWT.

Request

POST /api/v1/auth/sync-customer

Headers

HeaderRequiredDescription
X-Internal-Api-KeyYesInternal API key
Content-TypeYesapplication/json

Request Body

FieldTypeRequiredDescription
idintegerYesCustomer ID in Laravel
user_idintegerNoAssociated user ID
company_namestringNoCompany/organization name
first_namestringYesCustomer first name
last_namestringYesCustomer last name
emailstringYesCustomer email (unique)
user_typeintegerNoUser type identifier
mrrdecimalNoMonthly recurring revenue
activebooleanYesAccount active status
contract_languagestringNoPreferred language
created_byintegerNoAdmin who created
statusintegerNoCustomer status code

Example

curl -X POST "https://cloud.asahome.io/api/v1/auth/sync-customer" \
-H "X-Internal-Api-Key: your-internal-api-key" \
-H "Content-Type: application/json" \
-d '{
"id": 123,
"user_id": 456,
"company_name": "Acme Corp",
"first_name": "John",
"last_name": "Doe",
"email": "john@acme.com",
"user_type": 1,
"mrr": 99.99,
"active": true,
"contract_language": "en",
"created_by": 1,
"status": 1
}'

Response

{
"success": true,
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"sync_id": 123,
"email": "john@acme.com",
"firstName": "John",
"lastName": "Doe",
"isActive": true,
"createdAt": "2024-01-15T10:30:00.000Z"
},
"created": true
}
FieldDescription
successWhether the sync was successful
userThe created or updated user object
createdtrue if new user, false if updated

Error Responses

Invalid API Key (401)

{
"statusCode": 401,
"message": "Invalid API key",
"error": "Unauthorized"
}

Email Conflict (409)

{
"success": false,
"error": "Email already exists with different sync_id",
"code": "CONFLICT"
}

Validation Error (400)

{
"statusCode": 400,
"message": ["email must be an email", "first_name should not be empty"],
"error": "Bad Request"
}

JWT Token Structure

Access Token Claims

{
"sub": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"role": "user",
"iat": 1700000000,
"exp": 1700000900
}
ClaimDescription
subUser ID (UUID)
emailUser email address
roleUser role (user or admin)
iatIssued at timestamp
expExpiration timestamp

Using the Access Token

Include the token in the Authorization header for all authenticated requests:

curl -X GET "https://cloud.asahome.io/api/v1/devices" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"