REST API¶
Live in v2.16.0+
The REST API is fully functional and running in production. This page documents the implemented endpoints and usage examples. Built on Spring Boot 3.2 with gecko-simulation-core, enabling headless simulation without GUI dependencies.
The REST API provides an HTTP/REST interface for controlling GeckoCIRCUITS programmatically. It is built on Spring Boot 3.2 and uses the gecko-simulation-core module for all simulation logic, enabling cloud deployment, CI/CD automation, and remote computation.
Quick Start¶
Deploy and test the REST API with Docker:
# Start the API server (port 8080)
docker-compose up -d
# Check health
curl http://localhost:8080/actuator/health
# View API documentation
# Open http://localhost:8080/swagger-ui.html in your browser
Architecture¶
┌──────────────┐ HTTP ┌──────────────────┐
│ Python │◄─────────────►│ gecko-rest-api │
│ Browser │ port 8080 │ (Spring Boot) │
│ curl │ │ Uses gecko-core │
└──────────────┘ └──────────────────┘
API Documentation¶
Full interactive documentation available at:
http://localhost:8080/swagger-ui.html (when running)
OpenAPI specification:
Authentication¶
Optional in v2.22.0+
API key authentication is disabled by default for backward compatibility. Enable it in production deployments for security.
Configuration¶
API key authentication is controlled via application.properties:
# Enable/disable authentication (default: false)
gecko.api.auth-enabled=true
# Comma-separated list of valid API keys
gecko.api.keys=my-key-1,my-key-2,my-key-3
Or via environment variables:
Usage¶
When authentication is enabled, all protected endpoints require the X-API-Key header:
curl¶
# With API key
curl -H "X-API-Key: my-secret-key" \
http://localhost:8080/api/v1/simulations
# Without API key (only works when auth-enabled=false)
curl http://localhost:8080/api/v1/simulations
Python¶
import requests
session = requests.Session()
session.headers.update({"X-API-Key": "my-secret-key"})
# All requests include the API key automatically
response = session.post(
"http://localhost:8080/api/v1/simulations",
json={"circuitFile": "path/to/circuit.ipes"}
)
if response.status_code == 401:
print("Invalid API key")
else:
print(response.json())
JavaScript/Node.js¶
const axios = require('axios');
const client = axios.create({
baseURL: 'http://localhost:8080',
headers: {
'X-API-Key': 'my-secret-key'
}
});
client.post('/api/v1/simulations', {
circuitFile: 'path/to/circuit.ipes'
})
.then(response => console.log(response.data))
.catch(error => {
if (error.response.status === 401) {
console.error('Unauthorized: Invalid API key');
}
});
Error Response¶
Invalid or missing API key returns 401 Unauthorized:
Public Endpoints¶
The following endpoints do not require API authentication:
| Path | Description |
|---|---|
/api/v1/health | Health check |
/actuator/health | Actuator health |
/swagger-ui/** | Swagger UI |
/v3/api-docs/** | OpenAPI specification |
/ws/** | WebSocket endpoint |
/ws-raw/** | Raw WebSocket endpoint |
Security Best Practices¶
-
Always use HTTPS in production:
-
Rotate keys regularly - Update keys quarterly or when team changes:
-
Use environment variables - Never hardcode keys:
-
Different keys per environment:
For more details, see v2.22.0 Release Notes.
Live Endpoints¶
Loss Calculation Endpoints¶
Calculate power loss for semiconductor devices.
Switching Loss (Voltage and Energy Scaling)
{
"voltage": 400,
"current": 50,
"frequency": 20000,
"temperature": 125,
"referenceVoltage": 600,
"referenceCurrent": 100,
"referenceFrequency": 20000,
"referenceTemperature": 125,
"e_on_ref": 5.2e-5,
"e_off_ref": 3.8e-5
}
Conduction Loss (Resistance Model)
Detailed Loss (Temperature-Dependent Interpolation)
Circuit File Endpoints¶
Parse Circuit File
POST /api/v1/circuits/parse
Content-Type: multipart/form-data
curl -F "file=@circuit.ipes" http://localhost:8080/api/v1/circuits/parse
Get Circuit Metadata
List Components
Validate Circuit
List All Circuits
Delete Circuit
Clone Circuit
Create a deep copy of a loaded circuit with optional parameter overrides.
Request (with parameter overrides):
Response (201 Created):
{
"circuitId": "circuit-uuid-new",
"name": "circuit_clone",
"componentCount": 24,
"parameters": {
"simulationDuration": 0.02,
"timeStep": 1e-6,
"solverType": "trapezoidal"
}
}
Update Circuit Parameters
Modify simulation parameters (duration, time step, solver) for a loaded circuit.
Request (all fields optional):
Response (200 OK):
{
"circuitId": "circuit-uuid-001",
"name": "circuit",
"parameters": {
"simulationDuration": 0.05,
"timeStep": 5e-7,
"solverType": "gear-shichman"
}
}
Live in: v2.20.0+
Simulation Endpoints¶
Submit Simulation (Async)
Request:
{
"circuitFile": "base64-encoded-.ipes-data",
"simulationTime": 0.01,
"timeStep": 1e-7,
"solverType": "backward-euler",
"parameters": {
"PWM.1.dutyCycle": 0.5,
"R.1.resistance": 10.0
}
}
Solver Types: - backward-euler - Implicit 1st order (stable, for stiff circuits) - trapezoidal - Implicit 2nd order (balanced accuracy/stability) - gear-shichman - Variable order (best for variable dynamics)
Get Simulation Status and Results
List All Simulations
Cancel Simulation
Pause Simulation
Resume Simulation
Get Detailed Progress
Response fields: - preCalcProgress - Initial condition calculation % - mainSimProgress - Main transient simulation % - currentStep - Current time step number - totalSteps - Total steps to complete - estimatedRemainingMs - Estimated time remaining
Export Results
Batch Job Tracking
Get aggregated status for all simulations in a batch submitted via v2.19.0+ batch endpoint.
Response:
{
"batchId": "batch-uuid-12345",
"totalSimulations": 20,
"completed": 18,
"failed": 1,
"running": 1,
"pending": 0,
"overallProgress": 90,
"done": false,
"submittedAt": "2026-02-18T10:30:00Z",
"simulations": {
"sim-uuid-001": {
"status": "completed",
"progress": 100,
"parameterSet": {"R1.resistance": 10.0}
},
"sim-uuid-002": {
"status": "failed",
"progress": 45,
"parameterSet": {"R1.resistance": 50.0},
"errorMessage": "Convergence failure at t=0.015s"
}
},
"failedIds": ["sim-uuid-002"]
}
Cancel Batch
Cancels all running and pending simulations in a batch.
Returns: 204 No Content on success
Live in: v2.20.0+
WebSocket Streaming¶
Real-time progress updates via WebSocket with STOMP message framing. Provides bidirectional communication capability for interactive monitoring and future client-to-server commands.
WebSocket Endpoints
/ws- SockJS-compatible WebSocket endpoint (for browsers)/ws-raw- Raw WebSocket endpoint (for non-browser clients)
Both endpoints support STOMP protocol for message framing.
Discover WebSocket Connection Details
Response:
{
"simulationId": "9a1d5f7e-3b2c-4d9e-8f1a-6c2b4a7d9e3f",
"stompEndpoint": "/ws",
"rawWebSocketEndpoint": "/ws-raw",
"subscribeDestination": "/topic/simulations/9a1d5f7e-3b2c-4d9e-8f1a-6c2b4a7d9e3f",
"protocol": "STOMP/1.2",
"supportsBidirectional": true,
"baseUrl": "http://localhost:8080"
}
JavaScript Browser Client (SockJS)
<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1.6.1/dist/sockjs.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/stompjs@2.3.3/stomp.min.js"></script>
<script>
const socket = new SockJS('http://localhost:8080/ws');
const client = Stomp.over(socket);
client.connect({}, (frame) => {
console.log('Connected:', frame);
// Subscribe to simulation progress updates
client.subscribe('/topic/simulations/9a1d5f7e-3b2c-4d9e-8f1a-6c2b4a7d9e3f', (message) => {
const progress = JSON.parse(message.body);
console.log(`Progress: ${progress.progress}%`);
console.log(`Status: ${progress.status}`);
console.log(`Time: ${progress.currentTime}s / ${progress.endTime}s`);
if (progress.status === 'COMPLETED') {
client.disconnect();
}
});
});
// Graceful disconnect
window.addEventListener('beforeunload', () => {
if (client && client.connected) {
client.disconnect();
}
});
</script>
Python Client (stomp.py)
import stomp
import json
import time
class ProgressListener(stomp.ConnectionListener):
def on_message(self, frame):
progress = json.loads(frame.body)
print(f"Progress: {progress['progress']}% | Status: {progress['status']}")
print(f"Time: {progress['currentTime']}s / {progress['endTime']}s")
# Connect via raw WebSocket
conn = stomp.Connection([('localhost', 8080)], wait_on_receipt=True)
conn.set_listener('progress', ProgressListener())
conn.connect()
# Subscribe to simulation progress
conn.subscribe('/topic/simulations/9a1d5f7e-3b2c-4d9e-8f1a-6c2b4a7d9e3f', id=1, ack='auto')
# Keep listening
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
conn.disconnect()
Raw WebSocket (wscat tool)
# Install wscat
npm install -g wscat
# Connect to raw WebSocket endpoint
wscat -c ws://localhost:8080/ws-raw
# Send STOMP CONNECT frame
CONNECT
accept-version:1.0,1.1,1.2
^@
# Subscribe to topic
SUBSCRIBE
id:sub-0
destination:/topic/simulations/9a1d5f7e-3b2c-4d9e-8f1a-6c2b4a7d9e3f
^@
# Receive messages...
Progress Message Format
Both SSE (/api/v1/simulations/{id}/stream) and WebSocket (/topic/simulations/{id}) use the same JSON message structure:
{
"simulationId": "9a1d5f7e-3b2c-4d9e-8f1a-6c2b4a7d9e3f",
"progress": 45.0,
"currentTime": 0.009,
"endTime": 0.02,
"step": 9000,
"totalSteps": 20000,
"status": "RUNNING",
"timestamp": "2026-02-18T10:30:00Z",
"errorMessage": null
}
Comparison: SSE vs WebSocket
| Feature | SSE | WebSocket |
|---|---|---|
| Endpoint | /api/v1/simulations/{id}/stream | /topic/simulations/{id} |
| Protocol | HTTP/1.1 (text/event-stream) | TCP (STOMP/1.2) |
| Direction | Server → Client only | Bidirectional (client → server coming in future versions) |
| Browser Support | Native EventSource API | Requires SockJS or ws library |
| Auto-Reconnect | Yes (EventSource) | No (application manages) |
| Latency | ~100ms (HTTP) | ~10-50ms (TCP) |
| Overhead | Higher (HTTP headers) | Lower (raw TCP frames) |
| Best For | Simple dashboards | Interactive monitoring, multi-client scenarios |
Both endpoints receive updates simultaneously from the same broadcastProgress() call, ensuring synchronized progress messages.
Live in: v2.21.0+
Signal Analysis Endpoints¶
Post-processing analysis of simulation or raw signal data.
Signal Characteristics
Returns 9 key metrics for any waveform.
Request (with raw data):
Or reference simulation results:
Response:
{
"average": 0.0,
"rms": 0.707,
"thd": 2.5,
"min": -1.0,
"max": 1.0,
"peakToPeak": 2.0,
"ripple": 0.01,
"klirr": 0.025,
"shapeFactor": 1.11,
"sampleCount": 20000
}
Fourier Harmonic Analysis
Decompose signal into harmonic components with amplitude and phase.
Request (raw data):
{
"data": [0.0, 0.707, 1.0, 0.707, 0.0, -0.707, -1.0, -0.707],
"sampleRate": 50000.0,
"baseFrequency": 50.0
}
Response:
{
"baseFrequency": 50.0,
"harmonics": 10,
"dcComponent": 0.01,
"fundamentalAmplitude": 1.0,
"fundamentalPhaseDegrees": 0.0,
"cnAmplitudes": [0.01, 1.0, 0.05, 0.02, 0.015, 0.008, 0.005, 0.003, 0.002, 0.001],
"jnPhases": [0.0, 0.0, 0.1, -0.05, 0.2, -0.1, 0.15, -0.08, 0.12, -0.06]
}
RMS (Root Mean Square)
Quick RMS calculation for any signal.
Request:
Response:
Analysis Endpoint Table
| Endpoint | Method | Purpose | Returns |
|---|---|---|---|
/api/v1/analysis/characteristics | POST | 9 waveform metrics (RMS, THD, ripple, etc.) | CharacteristicsResult |
/api/v1/analysis/fourier | POST | Harmonic decomposition with amplitude & phase | FourierResult |
/api/v1/analysis/rms | POST | RMS calculation | number |
Live in: v2.19.0+
Usage Examples¶
Python Client¶
import requests
import numpy as np
BASE_URL = "http://localhost:8080/api/v1"
# Submit simulation
response = requests.post(f"{BASE_URL}/simulations", json={
"circuitFile": "base64_encoded_data",
"parameters": {"PWM.1.dutyCycle": 0.5},
"simulationTime": 0.001,
"timeStep": 5e-8,
"solverType": "trapezoidal"
})
sim_id = response.json()["simulationId"]
print(f"Simulation {sim_id} submitted")
# Poll for completion
import time
while True:
status = requests.get(f"{BASE_URL}/simulations/{sim_id}").json()
if status["status"] in ["completed", "failed"]:
break
print(f"Progress: {status['progress']['mainSimProgress']}%")
time.sleep(1)
# Get results
results = status["results"]["measurements"]
print(f"Vout: {results['SCOPE.1.ch1_avg']:.2f} V")
Bash / curl¶
# Loss calculation
curl -X POST http://localhost:8080/api/v1/loss/conduction \
-H "Content-Type: application/json" \
-d '{"voltage": 400, "current": 50, "temperature": 125}'
# Upload circuit
curl -F "file=@circuit.ipes" http://localhost:8080/api/v1/circuits/parse
# Submit simulation
curl -X POST http://localhost:8080/api/v1/simulations \
-H "Content-Type: application/json" \
-d '{"circuitFile": "circuit_base64", "simulationTime": 0.01, "timeStep": 1e-7}'
Request / Response Models¶
SimulationRequest¶
| Field | Type | Description |
|---|---|---|
circuitFile | string | Base64-encoded .ipes file or circuit ID |
simulationTime | number | Total simulation time (seconds) |
timeStep | number | Integration time step (seconds) |
solverType | enum | backward-euler, trapezoidal, gear-shichman |
parameters | map | Parameter overrides |
ProgressDetails¶
| Field | Type | Description |
|---|---|---|
preCalcProgress | number | Initial condition solver progress (0-100%) |
mainSimProgress | number | Main transient simulation progress (0-100%) |
currentStep | number | Current simulation step number |
totalSteps | number | Total steps for complete simulation |
estimatedRemainingMs | number | Estimated milliseconds until completion |
Deployment¶
Docker (Recommended)¶
# Using docker-compose
docker-compose up -d
# Manual Docker run
docker run -p 8080:8080 gecko-rest-api:latest
See Also¶
- Remote Interface (RMI) - Java RMI integration
- GeckoSCRIPT - Built-in scripting
- Python Integration
- Docker Setup