Quick Start : Get your API keys from the StateSet Dashboard and make your first authenticated request in minutes.
π Overview
StateSet uses API keys to authenticate requests. Authentication is performed via HTTP headers using the Bearer token format. All API requests must be made over HTTPS.
π API Key Types
Test Mode Prefix : sk_test_
Use for development and testing. Transactions are simulated and no real money moves.
Live Mode Prefix : sk_live_
Use for production. All transactions are real and irreversible.
Never expose your secret API keys in client-side code, public repositories, or anywhere else accessible to the public.
π Authentication Methods
Standard Authentication
Include your API key in the Authorization
header:
curl https://api.stateset.com/v1/account/balance \
-H "Authorization: Bearer sk_test_4eC39HqLyjWDarjtT1zdp7dc"
SDK Authentication
When using our official SDKs, initialize with your API key:
import { StateSet } from '@stateset/sdk' ;
const stateset = new StateSet ({
apiKey: process . env . STATESET_API_KEY // Best practice: use environment variables
});
π‘οΈ Security Best Practices
1. Use Environment Variables
Never hardcode API keys in your source code. Use environment variables: STATESET_API_KEY = sk_test_4eC39HqLyjWDarjtT1zdp7dc
// Load from environment
const apiKey = process . env . STATESET_API_KEY ;
2. Implement Key Rotation
Regularly rotate your API keys (recommended every 90 days):
Generate a new API key in the dashboard
Update your application to use the new key
Verify everything works correctly
Revoke the old key
3. Use Separate Keys per Environment
Development : Use test keys with limited permissions
Staging : Use test keys with production-like permissions
Production : Use live keys with minimal required permissions
4. Restrict Key Permissions
Create keys with only the permissions needed: // Dashboard API
const key = await stateset . apiKeys . create ({
name: 'Read-only Analytics Key' ,
permissions: [ 'analytics:read' , 'transactions:read' ]
});
Track API key usage to detect anomalies: const usage = await stateset . apiKeys . usage ({
keyId: 'key_abc123' ,
startDate: '2024-01-01' ,
endDate: '2024-01-31'
});
π Advanced Authentication
HMAC Signatures (High-Security Operations)
For sensitive operations like large transfers or issuance, add HMAC signatures:
const crypto = require ( 'crypto' );
function createHmacSignature ( payload , secret ) {
const timestamp = Math . floor ( Date . now () / 1000 );
const message = ` ${ timestamp } . ${ JSON . stringify ( payload ) } ` ;
const signature = crypto
. createHmac ( 'sha256' , secret )
. update ( message )
. digest ( 'hex' );
return {
signature ,
timestamp
};
}
// Use in request
const payload = { amount: '10000.00' , to: 'stateset1abc...' };
const { signature , timestamp } = createHmacSignature ( payload , process . env . HMAC_SECRET );
const response = await axios . post ( 'https://api.stateset.com/v1/stablecoin/transfer' , payload , {
headers: {
'Authorization' : `Bearer ${ apiKey } ` ,
'X-Signature' : signature ,
'X-Timestamp' : timestamp
}
});
OAuth 2.0 (Partner Integrations)
For third-party integrations, use OAuth 2.0:
// 1. Redirect user to authorize
const authUrl = `https://auth.stateset.com/oauth/authorize?
client_id= ${ CLIENT_ID } &
redirect_uri= ${ REDIRECT_URI } &
response_type=code&
scope=payments:read+payments:write` ;
// 2. Exchange code for token
const tokenResponse = await axios . post ( 'https://auth.stateset.com/oauth/token' , {
grant_type: 'authorization_code' ,
code: authorizationCode ,
client_id: CLIENT_ID ,
client_secret: CLIENT_SECRET ,
redirect_uri: REDIRECT_URI
});
// 3. Use access token
const response = await axios . get ( 'https://api.stateset.com/v1/payments' , {
headers: {
'Authorization' : `Bearer ${ tokenResponse . data . access_token } `
}
});
π Rate Limits
API keys have different rate limits based on your plan:
Plan Requests/Second Requests/Day Burst Limit Free 10 1,000 20 Starter 100 100,000 200 Growth 1,000 10,000,000 2,000 Enterprise Custom Custom Custom
Handling Rate Limits
async function makeRequestWithRetry ( url , options , maxRetries = 3 ) {
for ( let i = 0 ; i < maxRetries ; i ++ ) {
try {
const response = await axios . get ( url , options );
return response . data ;
} catch ( error ) {
if ( error . response ?. status === 429 ) {
const retryAfter = error . response . headers [ 'retry-after' ] || 2 ** i ;
console . log ( `Rate limited. Retrying after ${ retryAfter } seconds...` );
await new Promise ( resolve => setTimeout ( resolve , retryAfter * 1000 ));
} else {
throw error ;
}
}
}
throw new Error ( 'Max retries exceeded' );
}
π¨ Error Responses
Authentication errors return standardized responses:
{
"error" : {
"type" : "authentication_error" ,
"message" : "Invalid API key provided" ,
"code" : "invalid_api_key" ,
"status" : 401
}
}
Common authentication errors:
Error Code Description Solution missing_api_key
No API key provided Include Authorization
header invalid_api_key
API key is invalid Check key format and validity expired_api_key
API key has expired Generate a new key insufficient_permissions
Key lacks required permissions Use a key with proper permissions rate_limit_exceeded
Too many requests Implement backoff and retry
π Key Management API
Programmatically manage your API keys:
// List all keys
const keys = await stateset . apiKeys . list ();
// Create a new key
const newKey = await stateset . apiKeys . create ({
name: 'Mobile App Key' ,
permissions: [ 'payments:create' , 'payments:read' ],
expires_at: '2024-12-31T23:59:59Z'
});
// Revoke a key
await stateset . apiKeys . revoke ( 'key_abc123' );
// Update key permissions
await stateset . apiKeys . update ( 'key_abc123' , {
permissions: [ 'payments:read' ]
});
π§ͺ Testing Authentication
Use our test endpoint to verify your authentication:
curl https://api.stateset.com/v1/auth/test \
-H "Authorization: Bearer sk_test_4eC39HqLyjWDarjtT1zdp7dc"
Success response:
{
"authenticated" : true ,
"key_id" : "key_abc123" ,
"permissions" : [ "payments:create" , "payments:read" ],
"mode" : "test"
}
π± Mobile & Frontend Security
Never use secret API keys in mobile apps or frontend code. Use our public keys or implement a backend proxy.
Public Keys (Read-Only Operations)
// Safe to use in frontend
const publicKey = 'pk_test_TYooMQauvdEDq54NiTphI7jx' ;
// Limited to read-only operations
const balance = await fetch ( `https://api.stateset.com/v1/public/balance/ ${ address } ` , {
headers: {
'Authorization' : `Bearer ${ publicKey } `
}
});
Backend Proxy Pattern
// Frontend
const response = await fetch ( '/api/stateset-proxy/payment' , {
method: 'POST' ,
body: JSON . stringify ({ amount: 100 , recipient: 'stateset1abc...' })
});
// Backend (Node.js/Express)
app . post ( '/api/stateset-proxy/payment' , authenticate , async ( req , res ) => {
const payment = await stateset . payments . create ({
... req . body ,
customer: req . user . id
});
res . json ( payment );
});
π Troubleshooting
Verify API key is correct and properly formatted
Check if key is expired or revoked
Ensure Bearer
prefix is included
Confirm using correct environment (test vs live)
Check if key has required permissions
Verify youβre not exceeding rate limits
Ensure accessing allowed endpoints for key type
Run diagnostics: curl -v https://api.stateset.com/v1/auth/test \
-H "Authorization: Bearer YOUR_API_KEY"
Check response headers and body for details.
π Next Steps