Authentication Guide
All Neutron API requests require authentication. This guide covers how to generate signatures, get access tokens, and use them securely.
How It Works
- Generate a signature using your API Key and Secret (HMAC-SHA256)
- Exchange for an access token via the authentication endpoint
- Use the token as a Bearer token in all API calls
Signature Formula
stringToSign = "{apiKey}&payload={jsonPayload}"
signature = HMAC-SHA256(apiSecret, stringToSign) -> hex
The payload can be any valid JSON (e.g., {"test":"auth"}). The same JSON is sent as the request body.
Code Examples
Node.js
const crypto = require('crypto');
function authenticate(apiKey, apiSecret) {
const payload = JSON.stringify({ test: 'auth' });
const stringToSign = `${apiKey}&payload=${payload}`;
const signature = crypto
.createHmac('sha256', apiSecret)
.update(stringToSign)
.digest('hex');
return fetch('https://api.neutron.me/api/v2/authentication/token-signature', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': apiKey,
'X-Api-Signature': signature,
},
body: payload,
}).then(res => res.json());
}
const { accessToken, accountId } = await authenticate('your-api-key', 'your-api-secret');Python
import hmac
import hashlib
import json
import requests
def authenticate(api_key, api_secret):
payload = json.dumps({"test": "auth"})
string_to_sign = f"{api_key}&payload={payload}"
signature = hmac.new(
api_secret.encode(),
string_to_sign.encode(),
hashlib.sha256
).hexdigest()
response = requests.post(
'https://api.neutron.me/api/v2/authentication/token-signature',
headers={
'Content-Type': 'application/json',
'X-Api-Key': api_key,
'X-Api-Signature': signature,
},
data=payload,
)
return response.json()
result = authenticate('your-api-key', 'your-api-secret')
access_token = result['accessToken']Go
func authenticate(apiKey, apiSecret string) (string, error) {
payload := `{"test":"auth"}`
stringToSign := apiKey + "&payload=" + payload
h := hmac.New(sha256.New, []byte(apiSecret))
h.Write([]byte(stringToSign))
signature := hex.EncodeToString(h.Sum(nil))
req, _ := http.NewRequest("POST",
"https://api.neutron.me/api/v2/authentication/token-signature",
strings.NewReader(payload))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Api-Key", apiKey)
req.Header.Set("X-Api-Signature", signature)
resp, err := http.DefaultClient.Do(req)
// ... parse response for accessToken
}PHP
function authenticate($apiKey, $apiSecret) {
$payload = json_encode(['test' => 'auth']);
$stringToSign = "{$apiKey}&payload={$payload}";
$signature = hash_hmac('sha256', $stringToSign, $apiSecret);
$ch = curl_init('https://api.neutron.me/api/v2/authentication/token-signature');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
"X-Api-Key: {$apiKey}",
"X-Api-Signature: {$signature}",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
return json_decode(curl_exec($ch), true);
}cURL / Bash
API_KEY="your-api-key"
API_SECRET="your-api-secret"
PAYLOAD='{"test":"auth"}'
STRING_TO_SIGN="${API_KEY}&payload=${PAYLOAD}"
SIGNATURE=$(echo -n "$STRING_TO_SIGN" | openssl dgst -sha256 -hmac "$API_SECRET" | cut -d' ' -f2)
curl -X POST https://api.neutron.me/api/v2/authentication/token-signature \
-H "Content-Type: application/json" \
-H "X-Api-Key: $API_KEY" \
-H "X-Api-Signature: $SIGNATURE" \
-d "$PAYLOAD"Response
{
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"expiredAt": 1770428400000,
"accountId": "ne01-abc123def456"
}Using the Token
Include the token in the Authorization header for all API calls:
curl https://api.neutron.me/api/v2/account/YOUR_ACCOUNT_ID \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"Token Management
- Tokens have a limited validity period -- check
expiredAt - Using an expired token returns 401 Unauthorized
- No refresh token flow -- simply re-authenticate when expired
Auto-Refresh Pattern
class NeutronClient {
constructor(apiKey, apiSecret) {
this.apiKey = apiKey;
this.apiSecret = apiSecret;
this.token = null;
this.tokenExpiry = null;
}
async getToken() {
if (!this.token || Date.now() > this.tokenExpiry - 300000) {
const result = await authenticate(this.apiKey, this.apiSecret);
this.token = result.accessToken;
this.tokenExpiry = result.expiredAt;
}
return this.token;
}
}Security Best Practices
Do: Store secrets in env vars or secret managers. Rotate keys periodically. Restrict key permissions to what's needed.
Don't: Expose secrets in client-side code. Commit secrets to git. Share secrets over chat.
Updated 6 days ago
