| Crates.io | spec-ai-api |
| lib.rs | spec-ai-api |
| version | 0.6.0-prerelease.12 |
| created_at | 2025-11-25 00:04:09.631669+00 |
| updated_at | 2026-01-04 05:05:43.542631+00 |
| description | HTTP API for spec-ai framework |
| homepage | |
| repository | https://github.com/geoffsee/spec-ai |
| max_upload_size | |
| id | 1948933 |
| size | 337,649 |
HTTP API server for the spec-ai framework.
This crate provides a REST API and mesh server for remote agent interaction and coordination. It enables:
Built on modern async Rust web technologies:
The API server provides:
The API server uses mandatory TLS for all connections. This provides:
On first startup, the server automatically generates a self-signed certificate and saves it to:
~/.spec-ai/tls/server.crt~/.spec-ai/tls/server.keyThe certificate fingerprint is logged on startup and available via the /cert endpoint.
To use your own certificate, configure in spec-ai.config.toml or pass to ApiConfig:
# In config (future support) or via ApiConfig builder:
# tls_cert_path = "/path/to/cert.pem"
# tls_key_path = "/path/to/key.pem"
Since the server uses a self-signed certificate, clients should verify by fingerprint rather than chain of trust. The /cert endpoint returns certificate info:
curl -k https://localhost:3000/cert
Response:
{
"fingerprint": "AA:BB:CC:...",
"certificate_pem": "-----BEGIN CERTIFICATE-----...",
"not_after": "2025-12-10T...",
"subject": "CN=spec-ai-server-localhost, O=spec-ai",
"san": ["localhost", "127.0.0.1"]
}
In Swift, you can implement certificate pinning by comparing the fingerprint:
// Store the expected fingerprint (from /cert or server logs)
let expectedFingerprint = "AA:BB:CC:..."
// In URLSessionDelegate, verify the certificate
func urlSession(_ session: URLSession,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
guard let serverTrust = challenge.protectionSpace.serverTrust,
let certificate = SecTrustGetCertificateAtIndex(serverTrust, 0) else {
completionHandler(.cancelAuthenticationChallenge, nil)
return
}
let fingerprint = sha256Fingerprint(of: certificate)
if fingerprint == expectedFingerprint {
completionHandler(.useCredential, URLCredential(trust: serverTrust))
} else {
completionHandler(.cancelAuthenticationChallenge, nil)
}
}
The API supports optional bearer token authentication. When enabled, protected endpoints require a valid token.
Use the interactive setup script:
./scripts/setup-auth.sh
This will:
~/.spec-ai/credentials.json):[
{"username": "admin", "password_hash": "BASE64_PBKDF2_HASH"},
{"username": "user2", "password_hash": "BASE64_PBKDF2_HASH"}
]
/auth/hash endpoint (requires auth to be enabled first with at least one user, or temporarily disabled):curl -X POST http://localhost:3000/auth/hash \
-H 'Content-Type: application/json' \
-d '{"password": "your_secure_password"}'
spec-ai.config.toml:[auth]
enabled = true
credentials_file = "~/.spec-ai/credentials.json"
# token_expiry_secs = 86400 # 24 hours (default)
# token_secret = "your-secret-key" # Optional: for token persistence across restarts
| Method | Endpoint | Description |
|---|---|---|
| GET | /health |
Health check |
| GET | /cert |
Get server certificate info and fingerprint |
| POST | /auth/token |
Exchange username/password for bearer token |
| POST | /auth/hash |
Generate password hash for credentials file |
| Method | Endpoint | Description |
|---|---|---|
| GET | /agents |
List available agents |
| POST | /query |
Send query to agent |
| POST | /stream |
Streaming query response (SSE) |
| GET/POST/PUT/DELETE | /graph/* |
Knowledge graph operations |
| * | /registry/* |
Mesh registry operations |
| * | /messages/* |
Message routing |
| * | /sync/* |
Graph synchronization |
curl -X POST http://localhost:3000/auth/token \
-H 'Content-Type: application/json' \
-d '{"username": "admin", "password": "your_password"}'
Response:
{
"token": "eyJ...",
"token_type": "Bearer",
"expires_in": 86400
}
curl http://localhost:3000/agents \
-H 'Authorization: Bearer eyJ...'
token_secret is not set, a random key is generated at startup (tokens won't persist across restarts)token_secret in config for consistent token validation across restartsThis crate depends on:
spec-ai-core - Core agent runtime (with api feature enabled)spec-ai-config - Configuration managementspec-ai-policy - Policy enforcement for API requestsEnable the API server using the api feature flag:
cargo install spec-ai --features api
Start the server:
spec-ai server --port 3000
The API server is automatically started when configured in spec-ai.config.toml.
Run API-specific tests:
cargo test -p spec-ai-api
For end-user documentation, see the main spec-ai README.