REST API Reference
Complete reference for the OpenForge REST API built with FastAPI. The API provides programmatic access to all platform capabilities: project management, job submission and monitoring, result retrieval, report generation, and webhook registration. Auto-generated OpenAPI documentation is available at /docs (Swagger UI) and /redoc (ReDoc) on any running OpenForge server.
Overview #
Base URL: http://localhost:8080/api/v1 (Docker Compose) or your configured server hostname.
| Resource | Endpoints | Description |
|---|---|---|
| Projects | /projects | CRUD operations for OpenForge projects |
| Jobs | /jobs | Submit, monitor, and cancel verification jobs |
| Results | /results | Retrieve verification and analysis results |
| Reports | /reports | Generate and download reports |
| Webhooks | /webhooks | Register event callbacks for CI/CD |
| Health | /health | Server health and tool availability checks |
All responses use JSON format. Request bodies must use Content-Type: application/json. File uploads use multipart/form-data.
Authentication #
OpenForge supports two authentication methods:
Bearer Token
GET /api/v1/projects
Authorization: Bearer <token>
Generate tokens via the Web UI (Settings → API Tokens) or CLI (openforge config set token <value>).
API Key (Header)
GET /api/v1/projects
X-API-Key: <key>
For local Docker Compose deployments, authentication is disabled by default. Set OPENFORGE_AUTH_ENABLED=true in your .env to enable it.
Projects API #
POST /api/v1/projects — Create Project
Request:
{
"name": "ntt-butterfly",
"top_module": "ntt_butterfly",
"target_pdk": "sky130",
"description": "NTT butterfly unit for ML-KEM"
}
Response: 201 Created
{
"id": "proj_abc123",
"name": "ntt-butterfly",
"top_module": "ntt_butterfly",
"target_pdk": "sky130",
"created_at": "2026-01-15T10:30:00Z",
"status": "created",
"url": "/api/v1/projects/proj_abc123"
}
GET /api/v1/projects — List Projects
Query parameters:
?page=1&per_page=20&status=active&sort=updated_at
Response: 200 OK
{
"projects": [...],
"total": 42,
"page": 1,
"per_page": 20
}
GET /api/v1/projects/{id} — Get Project
PUT /api/v1/projects/{id} — Update Project
DELETE /api/v1/projects/{id} — Delete Project
POST /api/v1/projects/{id}/upload — Upload Design Files
Request: multipart/form-data
files[]: ntt_butterfly.v
files[]: mod_reduce.v
files[]: openforge.yaml
Response: 200 OK
{
"uploaded": 3,
"project_id": "proj_abc123",
"files": ["ntt_butterfly.v", "mod_reduce.v", "openforge.yaml"]
}
Jobs API #
POST /api/v1/projects/{id}/jobs — Submit Verification Job
Request:
{
"stages": ["lint", "simulation", "formal", "crypto"],
"config_overrides": {
"verification.simulation.coverage": true,
"verification.crypto_verification.side_channel.num_traces": 50000
}
}
Response: 202 Accepted
{
"job_id": "job_xyz789",
"project_id": "proj_abc123",
"status": "queued",
"stages": ["lint", "simulation", "formal", "crypto"],
"submitted_at": "2026-01-15T10:35:00Z",
"estimated_duration": "5m30s",
"url": "/api/v1/jobs/job_xyz789"
}
GET /api/v1/jobs/{id} — Get Job Status
Response: 200 OK
{
"job_id": "job_xyz789",
"status": "running",
"progress": {
"lint": {"status": "passed", "duration": "2.1s"},
"simulation": {"status": "running", "progress": "7/10 tests"},
"formal": {"status": "queued"},
"crypto": {"status": "queued"}
},
"started_at": "2026-01-15T10:35:02Z"
}
POST /api/v1/jobs/{id}/cancel — Cancel Job
GET /api/v1/jobs/{id}/logs — Get Job Logs
Query parameters:
?stage=simulation&tail=100&follow=false
Response: 200 OK
{
"logs": [
{"timestamp": "2026-01-15T10:35:03Z", "stage": "simulation", "level": "INFO", "message": "Compiling with Verilator 5.028..."},
{"timestamp": "2026-01-15T10:35:05Z", "stage": "simulation", "level": "INFO", "message": "Running test_ntt_butterfly..."}
]
}
Results API #
GET /api/v1/jobs/{id}/results — Get All Results
Response: 200 OK
{
"job_id": "job_xyz789",
"overall_status": "passed",
"stages": {
"lint": {"status": "passed", "warnings": 2, "errors": 0},
"simulation": {
"status": "passed",
"tests_passed": 10,
"tests_failed": 0,
"coverage": {"line": 96.4, "toggle": 89.7, "fsm": 100.0}
},
"formal": {
"status": "passed",
"properties_proven": 4,
"properties_failed": 0,
"properties_inconclusive": 0
},
"crypto": {
"constant_time": {"status": "passed", "violations": 0},
"side_channel": {"status": "passed", "max_t_value": 2.31, "threshold": 4.5},
"ntt_validation": {"status": "passed", "mismatches": 0},
"fips_compliance": {"status": "skipped", "reason": "No key storage detected"},
"entropy_analysis": {"status": "skipped", "reason": "No entropy sources detected"}
}
}
}
GET /api/v1/jobs/{id}/results/crypto — Get Crypto Results
GET /api/v1/jobs/{id}/results/coverage — Get Coverage Data
GET /api/v1/jobs/{id}/artifacts/{name} — Download Artifact
Artifacts include waveform traces (trace.fst), power traces (power_trace.csv), TVLA results (tvla_results.json), coverage data (coverage.xml), and reports.
Reports API #
POST /api/v1/jobs/{id}/reports — Generate Report
Request:
{
"format": "html",
"include": ["simulation", "formal", "crypto"],
"template": null
}
Response: 200 OK (HTML file download)
Webhooks #
POST /api/v1/webhooks — Register Webhook
Request:
{
"url": "https://your-server.com/openforge-events",
"events": ["job.completed", "job.failed"],
"secret": "your-webhook-secret",
"project_id": "proj_abc123"
}
Response: 201 Created
{
"webhook_id": "wh_def456",
"url": "https://your-server.com/openforge-events",
"events": ["job.completed", "job.failed"],
"active": true
}
Webhook Events
| Event | Trigger |
|---|---|
job.queued | Job submitted to queue |
job.started | Job execution begins |
job.completed | Job finished successfully |
job.failed | Job failed (verification error or infrastructure error) |
job.cancelled | Job cancelled by user |
stage.completed | Individual stage within a job completed |
Webhook Payload
{
"event": "job.completed",
"timestamp": "2026-01-15T10:40:30Z",
"job_id": "job_xyz789",
"project_id": "proj_abc123",
"status": "passed",
"summary": {
"tests_passed": 10,
"properties_proven": 4,
"crypto_checks_passed": 3
}
}
Webhook payloads are signed with HMAC-SHA256 using your webhook secret. Verify the X-OpenForge-Signature header to authenticate webhook deliveries.
WebSocket Streaming #
For real-time job monitoring, connect via WebSocket:
# Connect to job log stream
ws://localhost:8080/api/v1/jobs/{id}/stream
# Messages (JSON, one per line):
{"type": "log", "stage": "simulation", "message": "Running test_ntt_butterfly..."}
{"type": "progress", "stage": "simulation", "tests_complete": 5, "tests_total": 10}
{"type": "stage_complete", "stage": "simulation", "status": "passed"}
{"type": "job_complete", "status": "passed"}
Error Handling #
All errors follow a consistent JSON format:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid openforge.yaml: unknown field 'simlation'",
"details": {"field": "verification.simlation", "suggestion": "verification.simulation"}
}
}
| HTTP Status | Code | Description |
|---|---|---|
400 | VALIDATION_ERROR | Invalid request body or configuration |
401 | UNAUTHORIZED | Missing or invalid authentication |
403 | FORBIDDEN | Insufficient permissions |
404 | NOT_FOUND | Project, job, or resource not found |
409 | CONFLICT | Project name already exists |
422 | TOOL_ERROR | Verification tool returned an error |
429 | RATE_LIMITED | Too many requests |
500 | INTERNAL_ERROR | Server error |
503 | SERVICE_UNAVAILABLE | Worker queue full or tools unavailable |
Rate Limits #
| Endpoint | Limit | Window |
|---|---|---|
| Job submission | 60 requests | Per hour per project |
| Result retrieval | 300 requests | Per minute |
| File upload | 100 MB total | Per upload request |
| WebSocket connections | 10 concurrent | Per user |
Rate limit headers are included in all responses: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
OpenAPI Spec #
The complete OpenAPI 3.1 specification is auto-generated by FastAPI and available at:
| URL | Format |
|---|---|
/docs | Swagger UI (interactive) |
/redoc | ReDoc (documentation) |
/openapi.json | Raw OpenAPI JSON |
Use the Swagger UI at /docs to explore and test all endpoints interactively.