# Authentications # Authentication ## OAuth 2.0 Token-Based Authentication The Back Office API uses OAuth 2.0 with the Client Credentials flow for server-to-server authentication. This method is ideal for back office integrations where a user context is not required. ### Quick Start 1. Obtain your Client ID and Client Secret from Developer Support 2. Exchange credentials for an access token 3. Include the token in the Authorization header for all API requests 4. Tokens expire after 1 hour and must be refreshed ### Token Endpoint **Endpoint**: `POST https://api.lwolf.com/oauth/token` **Parameters**: | Parameter | Type | Required | Description | |---|---|---|---| | grant_type | string | Yes | Must be "client_credentials" | | client_id | string | Yes | Your OAuth 2.0 Client ID | | client_secret | string | Yes | Your OAuth 2.0 Client Secret | | scope | string | No | Space-separated scopes (read, write, admin) | ### cURL Example ```bash curl -X POST https://api.lwolf.com/oauth/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&scope=read write" ``` ### JavaScript Example ```javascript const getAccessToken = async () => { const response = await fetch('https://api.lwolf.com/oauth/token', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ grant_type: 'client_credentials', client_id: 'YOUR_CLIENT_ID', client_secret: 'YOUR_CLIENT_SECRET', scope: 'read write' }) }); const data = await response.json(); return data.access_token; }; ``` ### Python Example ```python import requests def get_access_token(): url = 'https://api.lwolf.com/oauth/token' payload = { 'grant_type': 'client_credentials', 'client_id': 'YOUR_CLIENT_ID', 'client_secret': 'YOUR_CLIENT_SECRET', 'scope': 'read write' } response = requests.post(url, data=payload) return response.json()['access_token'] ``` ### Security Best Practices - Never expose your Client Secret in client-side code - Store credentials in environment variables or secure vaults - Rotate credentials regularly according to your security policy - Always use HTTPS for all API communications - Monitor token usage for anomalies ### Token Management - Access tokens are valid for 1 hour - Refresh tokens are not issued in Client Credentials flow - Request a new token when the current one expires - Implement token caching to minimize token requests - Handle 401 Unauthorized responses by refreshing the token ### Common Errors | Error | Status Code | Description | |---|---|---| | invalid_client | 401 | Client ID or secret is incorrect | | invalid_grant | 400 | Grant type is invalid or credentials are wrong | | invalid_scope | 400 | Requested scope is not available | | server_error | 500 | Internal server error during token generation | ## HTTP Request Overview All API requests use standard HTTP methods (GET, POST, PUT, DELETE) with JSON request/response bodies. ### HTTP Request Format **Base URI**: `https://api.lwolf.com` (production) or `https://api.pre.lwolf.com` (preproduction) **Format**: `{METHOD} {ENDPOINT} HTTP/1.1` **Example**: `GET /offices HTTP/1.1` ### Example Request with Response **Request**: ```bash curl -X GET https://api.lwolf.com/offices?limit=10 \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \ -H "Content-Type: application/json" ``` **Response**: ```json [ { "id": "OFF001", "name": "Downtown Office", "address": "123 Main Street", "city": "New York", "state": "NY", "zipCode": "10001", "phone": "(212) 555-0100", "status": "active" }, { "id": "OFF002", "name": "Midtown Office", "address": "456 5th Avenue", "city": "New York", "state": "NY", "zipCode": "10016", "phone": "(212) 555-0200", "status": "active" } ] ``` ### JavaScript Implementation ```javascript const listOffices = async (accessToken) => { const response = await fetch('https://api.lwolf.com/offices?limit=10', { method: 'GET', headers: { 'Authorization': `Bearer ${accessToken}`, 'Content-Type': 'application/json' } }); const data = await response.json(); return data; }; ``` ### Python Implementation ```python import requests def list_offices(access_token): url = 'https://api.lwolf.com/offices' headers = { 'Authorization': f'Bearer {access_token}', 'Content-Type': 'application/json' } params = {'limit': 10} response = requests.get(url, headers=headers, params=params) return response.json() ``` ### Best Practices - Always include the Content-Type header in requests - Use query parameters for filtering and pagination - Handle error responses gracefully - Implement exponential backoff for rate-limited requests - Cache responses when appropriate to reduce API load - Use connection pooling for high-volume integrations