Overview
DoorStax authenticates users via NextAuth.js with JWT session tokens. When a user signs in, the server issues a signed JWT that is stored as an HTTP-only cookie. This token is automatically included in every subsequent request.
API Key authentication is coming soon. This will allow server-to-server integrations without browser-based sessions.
Obtaining a Session
To obtain a session, send a POST request to the sign-in endpoint with valid credentials.
curl -X POST https://doorstax.com/api/auth/signin \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "your-password"
}'On success, the response sets an HTTP-only session cookie and returns the user profile along with the session token.
{
"user": {
"id": "usr_abc123",
"email": "user@example.com",
"name": "Jane Doe",
"role": "PROPERTY_MANAGER"
},
"expires": "2025-02-15T00:00:00.000Z"
}Making Authenticated Requests
Once authenticated, include the session cookie in all requests. If you are working outside a browser environment, pass the session token in the Authorization header.
curl https://doorstax.com/api/properties \
-H "Authorization: Bearer <session-token>" \
-H "Content-Type: application/json"const response = await fetch("https://doorstax.com/api/properties", {
headers: {
"Authorization": `Bearer ${sessionToken}`,
"Content-Type": "application/json",
},
});
const properties = await response.json();Two-Factor Authentication
DoorStax supports optional two-factor authentication (2FA) via authenticator apps (TOTP). When 2FA is enabled for a user, the sign-in flow requires an additional verification step.
2fa_required challenge with a temporary token{
"status": "2fa_required",
"tempToken": "tmp_xyz789",
"message": "Please provide your 2FA code"
}curl -X POST https://doorstax.com/api/auth/2fa/verify \
-H "Content-Type: application/json" \
-d '{
"tempToken": "tmp_xyz789",
"code": "123456"
}'Rate Limiting
API requests are rate limited to protect the platform. Limits are applied per-user and per-IP.
| Endpoint | Limit | Window |
|---|---|---|
| POST /auth/signin | 5 requests | 15 minutes |
| POST /auth/2fa/* | 5 requests | 15 minutes |
| GET /* | 100 requests | 1 minute |
| POST/PUT/DELETE /* | 30 requests | 1 minute |
Rate limit headers are included in every response:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 97
X-RateLimit-Reset: 1708012800Error Responses
Authentication errors follow a consistent format:
| Status | Code | Description |
|---|---|---|
| 401 | UNAUTHORIZED | Missing or invalid session token |
| 403 | FORBIDDEN | Valid session but insufficient permissions |
| 429 | RATE_LIMITED | Too many requests — retry after the reset window |
{
"error": {
"code": "UNAUTHORIZED",
"message": "Session token is missing or expired.",
"status": 401
}
}