Guides
Authentication
How to authenticate REST API requests with API keys
Overview
Moonbase REST API uses API key authentication. All authenticated endpoints require two headers:
NOVA-KEY- Your API keyNOVA-SECRET- Your API secret
Getting API Keys
API keys can be created through the Moonbase dashboard. Each key has:
- API Key: Public identifier for your key
- API Secret: Private secret for authentication (shown only once at creation)
Store your API secret securely. It cannot be recovered if lost.
Authentication Headers
| Header | Description |
|---|---|
NOVA-KEY | Your API key |
NOVA-SECRET | Your API secret |
Example Requests
GET Request
const apiKey = 'your_api_key';
const apiSecret = 'your_api_secret';
const response = await fetch('https://api.dev.mbhq.net/api/v1/orders/active', {
method: 'GET',
headers: {
'NOVA-KEY': apiKey,
'NOVA-SECRET': apiSecret
}
});POST Request
const apiKey = 'your_api_key';
const apiSecret = 'your_api_secret';
const response = await fetch('https://api.dev.mbhq.net/api/v1/orders', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'NOVA-KEY': apiKey,
'NOVA-SECRET': apiSecret
},
body: JSON.stringify({
product: 'BTC-VND',
side: 'BUY',
type: 'LIMIT',
base_size: '0.001',
limit_price: '2500000000'
})
});DELETE Request
const apiKey = 'your_api_key';
const apiSecret = 'your_api_secret';
const response = await fetch('https://api.dev.mbhq.net/api/v1/order/active?order_id=123', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
'NOVA-KEY': apiKey,
'NOVA-SECRET': apiSecret
}
});Complete Client Example
class MoonbaseClient {
private apiKey: string;
private apiSecret: string;
private baseUrl: string;
constructor(apiKey: string, apiSecret: string, baseUrl = 'https://api.dev.mbhq.net') {
this.apiKey = apiKey;
this.apiSecret = apiSecret;
this.baseUrl = baseUrl;
}
private getHeaders(includeContentType = false): Record<string, string> {
const headers: Record<string, string> = {
'NOVA-KEY': this.apiKey,
'NOVA-SECRET': this.apiSecret
};
if (includeContentType) {
headers['Content-Type'] = 'application/json';
}
return headers;
}
async request(method: string, path: string, body?: object): Promise<any> {
const response = await fetch(`${this.baseUrl}${path}`, {
method,
headers: this.getHeaders(!!body),
body: body ? JSON.stringify(body) : undefined
});
return response.json();
}
// Convenience methods
async getActiveOrders(product?: string) {
const path = product ? `/api/v1/orders/active?product=${product}` : '/api/v1/orders/active';
return this.request('GET', path);
}
async createOrder(order: {
product: string;
side: 'BUY' | 'SELL';
type: 'LIMIT' | 'MARKET';
base_size: string;
limit_price?: string;
}) {
return this.request('POST', '/api/v1/orders', order);
}
async cancelOrder(orderId: string) {
return this.request('DELETE', `/api/v1/order/active?order_id=${orderId}`);
}
async cancelAllOrders() {
return this.request('DELETE', '/api/v1/orders/active/all');
}
async getAccount(userId: string) {
return this.request('GET', `/accounts/${userId}`);
}
}
// Usage
const client = new MoonbaseClient('your_api_key', 'your_api_secret');
// Get active orders
const orders = await client.getActiveOrders('BTC-VND');
// Create a limit order
const order = await client.createOrder({
product: 'BTC-VND',
side: 'BUY',
type: 'LIMIT',
base_size: '0.001',
limit_price: '2500000000'
});Go Example
package main
import (
"bytes"
"encoding/json"
"net/http"
)
type MoonbaseClient struct {
baseURL string
apiKey string
apiSecret string
}
func (c *MoonbaseClient) request(method, path string, body interface{}) (*http.Response, error) {
var bodyReader *bytes.Reader
if body != nil {
jsonBody, _ := json.Marshal(body)
bodyReader = bytes.NewReader(jsonBody)
}
req, err := http.NewRequest(method, c.baseURL+path, bodyReader)
if err != nil {
return nil, err
}
req.Header.Set("NOVA-KEY", c.apiKey)
req.Header.Set("NOVA-SECRET", c.apiSecret)
if body != nil {
req.Header.Set("Content-Type", "application/json")
}
return http.DefaultClient.Do(req)
}API Endpoints
| Environment | Base URL |
|---|---|
| Development | https://api.dev.mbhq.net |
| Production | https://api.mbhq.net |
Error Responses
401 Unauthenticated
{
"error": {
"code": "AUTH_REQUIRED",
"message": "this request requires user authentication"
}
}Common causes:
- Missing
NOVA-KEYorNOVA-SECRETheaders - Invalid API key or secret
- API key expired or revoked
403 Permission Denied
{
"error": {
"code": "INSUFFICIENT_SCOPE",
"message": "this request requires additional scope"
}
}Public Endpoints
Some endpoints don't require authentication:
GET /products- List productsGET /products/{id}/orderbook- Get orderbookGET /products/{id}/trades- Get recent tradesGET /assets- List assets
Best Practices
- Secure storage: Store API secrets in environment variables or secure vaults
- Never expose: Don't expose secrets in client-side code or logs
- Key rotation: Rotate API keys periodically
- Separate keys: Use different keys for different environments
- Read-only keys: Use read-only keys for applications that only need to read data
Next Steps
- Rate Limits - Understand API rate limiting
- Order Types - Learn about order types and parameters
- WebSocket Authentication - Real-time API authentication