Authentication
Authentication
Getting Started
You should have received an API key from SafeSky. This single key consists of two components:
- API Key ID: Your public identifier
- API Secret: Your private secret key used for signing requests
Keep your API secret secure and never expose it in client-side code or public repositories.
⚠️ Important Notice: The legacy
X-API-Keyheader authentication method is deprecated and will be removed in an upcoming release. All integrations must migrate to HMAC authentication as described below. Please update your implementation as soon as possible to avoid service interruption.
HMAC Authentication
SafeSky API uses HMAC (Hash-based Message Authentication Code) for request authentication. This scheme provides several key benefits:
- Security: Credentials are never sent over the network; only a cryptographic signature is transmitted
- Integrity: Ensures requests haven't been tampered with during transit
- Replay Protection: Timestamps prevent replay attacks
- Stateless: No session management required on the server side
HMAC uses the SHA-256 hashing algorithm to create a unique signature for each request based on the request content and your API secret.
SDKs and Libraries
To simplify integration, SafeSky provides official SDKs for multiple platforms:
- Python: HMAC Auth SDK for Python
- Dart/Flutter: HMAC Auth SDK for Dart
- JavaScript/Node.js: HMAC Auth for Node.js
- Java: HMAC Auth SDK for Java
- Kotlin: HMAC Auth SDK for Kotlin
- C/C++: HMAC Auth SDK for C
- C#: HMAC Auth SDK for C#
These SDKs handle HMAC signature generation, request signing, and error handling automatically. We recommend using an SDK whenever possible to reduce implementation complexity and potential security issues.
Manual HMAC Implementation
If an SDK is not available for your platform, you can implement HMAC authentication manually.
Request Signature Components
Each authenticated request must include the following headers:
X-SafeSky-Key-Id: <your-api-key-id>
X-SafeSky-Timestamp: <unix-timestamp-in-seconds>
X-SafeSky-Signature: <hmac-signature>
Signature Generation Process
-
Create the Signature Base String
Concatenate the following components with newline characters (
\n):<HTTP-METHOD>\n <REQUEST-PATH>\n <TIMESTAMP>\n <REQUEST-BODY>HTTP-METHOD: Uppercase HTTP method (GET, POST, PUT, DELETE, etc.)REQUEST-PATH: The path and query string (e.g.,/api/v1/flights?status=active)TIMESTAMP: Unix timestamp in seconds (must match theX-SafeSky-Timestampheader)REQUEST-BODY: Raw request body for POST/PUT requests, or empty string for GET/DELETE
-
Generate HMAC Signature
Compute the HMAC-SHA256 hash of the signature base string using your API secret:
signature = HMAC-SHA256(api_secret, signature_base_string) -
Encode the Signature
Convert the signature to hexadecimal format (lowercase).
Example Implementation
Python
import hmac
import hashlib
import time
import requests
api_key_id = "your_api_key_id"
api_secret = "your_api_secret"
base_url = "https://api.safesky.app"
def sign_request(method, path, body=""):
timestamp = str(int(time.time()))
# Create signature base string
signature_base = f"{method}\n{path}\n{timestamp}\n{body}"
# Generate HMAC signature
signature = hmac.new(
api_secret.encode('utf-8'),
signature_base.encode('utf-8'),
hashlib.sha256
).hexdigest()
return {
'X-SafeSky-Key-Id': api_key_id,
'X-SafeSky-Timestamp': timestamp,
'X-SafeSky-Signature': signature
}
# Example GET request
headers = sign_request('GET', '/api/v1/flights')
response = requests.get(f"{base_url}/api/v1/flights", headers=headers)
JavaScript/Node.js
const crypto = require('crypto');
const axios = require('axios');
const apiKeyId = 'your_api_key_id';
const apiSecret = 'your_api_secret';
const baseUrl = 'https://api.safesky.app';
function signRequest(method, path, body = '') {
const timestamp = Math.floor(Date.now() / 1000).toString();
// Create signature base string
const signatureBase = `${method}\n${path}\n${timestamp}\n${body}`;
// Generate HMAC signature
const signature = crypto
.createHmac('sha256', apiSecret)
.update(signatureBase)
.digest('hex');
return {
'X-SafeSky-Key-Id': apiKeyId,
'X-SafeSky-Timestamp': timestamp,
'X-SafeSky-Signature': signature
};
}
// Example GET request
const headers = signRequest('GET', '/api/v1/flights');
axios.get(`${baseUrl}/api/v1/flights`, { headers })
.then(response => console.log(response.data));
cURL
#!/bin/bash
API_KEY_ID="your_api_key_id"
API_SECRET="your_api_secret"
METHOD="GET"
PATH="/api/v1/flights"
TIMESTAMP=$(date +%s)
BODY=""
# Create signature base string
SIGNATURE_BASE="${METHOD}\n${PATH}\n${TIMESTAMP}\n${BODY}"
# Generate HMAC signature
SIGNATURE=$(echo -n -e "${SIGNATURE_BASE}" | openssl dgst -sha256 -hmac "${API_SECRET}" | cut -d' ' -f2)
# Make request
curl -X GET "https://api.safesky.app${PATH}" \
-H "X-SafeSky-Key-Id: ${API_KEY_ID}" \
-H "X-SafeSky-Timestamp: ${TIMESTAMP}" \
-H "X-SafeSky-Signature: ${SIGNATURE}"
Important Considerations
- Clock Synchronization: Ensure your system clock is synchronized with NTP. The API will reject requests with timestamps more than 5 minutes old or in the future.
- Character Encoding: Always use UTF-8 encoding for the signature base string.
- Body Serialization: For POST/PUT requests, use the exact body bytes that will be sent (typically JSON). Don't modify or pretty-print the JSON after signing.
- Query Parameters: Include query parameters in the path component (e.g.,
/api/v1/flights?status=active). - Signature Case: The signature must be lowercase hexadecimal.
Error Responses
Authentication failures will return HTTP 401 with one of the following error codes:
invalid_signature: The signature doesn't match the expected valueinvalid_timestamp: The timestamp is too old or too far in the futureinvalid_key: The API key ID is unknown or inactivemissing_headers: Required authentication headers are missing
Testing Your Implementation
To verify your implementation:
- Test with a simple GET request to
/api/v1 - Compare your signature generation with the SDK implementation
- Enable debug logging to inspect the signature base string
- Verify timestamp synchronization with
date +%svs server time
For additional support, contact SafeSky technical support or refer to the full API documentation.