API Authentication
Learn how to authenticate with the ARSAKA PUGUH API.
Authentication Methods
PUGUH supports two authentication methods:
- API Keys: For server-to-server integrations (use
X-API-Keyheader) - JWT Tokens: For user-context operations (use
Authorization: Bearerheader)
API Keys
Obtaining an API Key
- Go to your profile settings
- Click "API Keys"
- Click "Create New Key"
- Copy the key (shown only once!)
Or create a service account for production use.
Using API Keys
Include the key in the X-API-Key header:
curl -X GET https://api-puguh.arsaka.io/api/v1/organizations \
-H "X-API-Key: YOUR_API_KEY" \
-H "X-Organization-ID: YOUR_ORGANIZATION_ID" Required Headers
| Header | Required | Description |
|---|---|---|
X-API-Key | Yes | Your API key |
X-Organization-ID | Yes | Your organization UUID |
X-Application-ID | Sometimes | Required for application-scoped operations |
Content-Type | For POST/PUT | Usually application/json |
JWT Tokens
Login
Authenticate with email and password to get a JWT token pair:
curl -X POST https://api-puguh.arsaka.io/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "your_password"
}' Response (returned directly, no wrapper):
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "dGhpcyBpcyBhIHJlZnJl..."
} JWT tokens are signed with RS256 (asymmetric). You can verify tokens locally using the public key from the JWKS endpoint:
curl -X GET https://api-puguh.arsaka.io/.well-known/jwks.json Register
Create a new user account:
curl -X POST https://api-puguh.arsaka.io/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "newuser@example.com",
"password": "secure_password",
"full_name": "Jane Doe"
}' Response:
{
"user_id": "550e8400-e29b-41d4-a716-446655440000",
"email": "newuser@example.com",
"organization_id": "660e8400-e29b-41d4-a716-446655440000"
} Using JWT Tokens
Include the access token in the Authorization header:
curl -X GET https://api-puguh.arsaka.io/api/v1/organizations \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." Refreshing Tokens
Before the access token expires, use the refresh token to get a new one:
curl -X POST https://api-puguh.arsaka.io/api/v1/auth/refresh \
-H "Content-Type: application/json" \
-d '{
"refresh_token": "dGhpcyBpcyBhIHJlZnJl..."
}' Response:
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600
} SDK Authentication
JavaScript / TypeScript
import { PuguhClient } from '@arsaka/puguh-sdk';
// Using API Key
const client = new PuguhClient({
apiKey: process.env.PUGUH_API_KEY,
organizationId: process.env.PUGUH_ORGANIZATION_ID,
});
// Using JWT
const client = new PuguhClient({
accessToken: userToken,
onTokenExpired: async () => {
const newToken = await refreshToken();
return newToken;
},
}); Python
from puguh_sdk import PuguhClient
# Using API Key
client = PuguhClient(
api_key=os.environ['PUGUH_API_KEY'],
organization_id=os.environ['PUGUH_ORGANIZATION_ID']
)
# Using JWT
client = PuguhClient(
access_token=user_token,
on_token_expired=refresh_token_callback
) Security Best Practices
API Key Security
- Never commit keys to source control bash
# .gitignore .env *.key - Use environment variables bash
export PUGUH_API_KEY=your_key_here - Rotate keys regularly
- Rotate production keys quarterly
- Rotate immediately if compromised
- Use separate keys per environment
- Development key
- Staging key
- Production key
Token Security
- Store securely
- Use secure cookies (HttpOnly, Secure, SameSite)
- Don't store in localStorage for sensitive apps
- Short expiration
- Access tokens: 1 hour recommended
- Refresh tokens: 7-30 days
- Revoke on logout bash
curl -X POST https://api-puguh.arsaka.io/api/v1/auth/logout \ -H "Authorization: Bearer YOUR_TOKEN"
Error Responses
PUGUH uses standard HTTP status codes. Error responses follow the FastAPI format:
401 Unauthorized
Missing or invalid credentials:
{
"detail": "Invalid or expired token"
} 403 Forbidden
Valid credentials but lacking permission:
{
"detail": "Missing permission: organization.members.create"
} 422 Validation Error
Request body failed validation:
{
"detail": [
{
"loc": ["body", "email"],
"msg": "value is not a valid email address",
"type": "value_error.email"
}
]
} 429 Too Many Requests
{
"detail": "Rate limit exceeded. Retry after 60 seconds."
} Check the Retry-After header for the wait time in seconds.
Rate Limiting
API calls are rate limited per plan:
| Plan | Requests/minute |
|---|---|
| Free | 60 |
| Pro | 300 |
| Business | 1,000 |
| Enterprise | Custom |
Rate limit headers included in every response:
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 299
X-RateLimit-Reset: 1640000000
Retry-After: 60 Testing Authentication
Test API Key
Verify your API key works by calling the health endpoint:
curl -X GET https://api-puguh.arsaka.io/api/v1/health \
-H "X-API-Key: YOUR_API_KEY" \
-H "X-Organization-ID: YOUR_ORGANIZATION_ID" Test JWT Token
Login and use the returned token to call a protected endpoint:
# 1. Login to get a token
TOKEN=$(curl -s -X POST https://api-puguh.arsaka.io/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "your_password"}' \
| jq -r '.access_token')
# 2. Use the token
curl -X GET https://api-puguh.arsaka.io/api/v1/iam/users \
-H "Authorization: Bearer $TOKEN" OAuth Integration (Enterprise)
For SSO integration:
Authorization URL
https://api-puguh.arsaka.io/oauth/authorize
?client_id=YOUR_CLIENT_ID
&redirect_uri=YOUR_REDIRECT_URI
&response_type=code
&scope=read:user read:resources
&state=RANDOM_STATE Exchange Code for Token
curl -X POST https://api-puguh.arsaka.io/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=AUTHORIZATION_CODE" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "redirect_uri=YOUR_REDIRECT_URI"