Sparki API Reference Documentation
Version: 1.0.0Last Updated: December 2025
Base URL:
https://api.sparki.local/api/v1
Table of Contents
- Authentication
- Rate Limiting
- Error Handling
- Users API
- Projects API
- Services API
- Infrastructure API
- Webhooks
- SDKs & Client Libraries
Authentication
Overview
All API requests require authentication using either API Keys or Bearer Tokens.API Key Authentication
Copy
# Include X-API-Key header
curl -H "X-API-Key: your-api-key" \
https://api.sparki.local/api/v1/users/me
# Response includes user information
{
"id": "user-123",
"email": "developer@sparki.io",
"roles": ["developer"]
}
Bearer Token Authentication
Copy
# Login to get token
curl -X POST https://api.sparki.local/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "developer@sparki.io",
"password": "secure-password"
}'
# Response
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 3600
}
# Use token in Authorization header
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
https://api.sparki.local/api/v1/users/me
OAuth 2.0 (Coming Soon)
Google, GitHub, and Microsoft OAuth integration will be available in Q1 2026.Token Refresh
Copy
# POST /auth/refresh
curl -X POST https://api.sparki.local/api/v1/auth/refresh \
-H "Authorization: Bearer your-token"
# Response
{
"token": "new-jwt-token",
"expiresIn": 3600
}
Rate Limiting
Limits
- Default: 1,000 requests per hour per API key
- Authenticated: 5,000 requests per hour per user
- Webhooks: Unlimited (event-based)
Headers
Copy
# Every response includes rate limit information
HTTP/1.1 200 OK
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1701234567
# When rate limited
HTTP/1.1 429 Too Many Requests
{
"error": "rate_limit_exceeded",
"message": "Too many requests. Try again in 60 seconds.",
"retryAfter": 60
}
Backoff Strategy
Copy
// Recommended backoff implementation (exponential)
func retryWithBackoff(fn func() error, maxRetries int) error {
for attempt := 0; attempt < maxRetries; attempt++ {
err := fn()
if err == nil {
return nil
}
// Exponential backoff: 1s, 2s, 4s, 8s...
wait := time.Duration(math.Pow(2, float64(attempt))) * time.Second
time.Sleep(wait)
}
return errors.New("max retries exceeded")
}
Error Handling
Error Response Format
Copy
{
"error": "error_code",
"message": "Human-readable error message",
"details": {
"field": "error_detail",
"reason": "validation_failed"
},
"requestId": "req-123-abc"
}
Common Error Codes
| Code | HTTP | Description |
|---|---|---|
invalid_request | 400 | Malformed request or invalid parameters |
authentication_failed | 401 | Invalid or missing credentials |
insufficient_permissions | 403 | User lacks required permissions |
not_found | 404 | Resource does not exist |
conflict | 409 | Resource already exists or conflict detected |
rate_limit_exceeded | 429 | Too many requests |
server_error | 500 | Internal server error |
service_unavailable | 503 | Service temporarily unavailable |
Error Response Examples
Copy
# 400 Bad Request
{
"error": "invalid_request",
"message": "email field is required",
"details": {
"field": "email",
"reason": "required_field_missing"
}
}
# 401 Unauthorized
{
"error": "authentication_failed",
"message": "Invalid API key",
"details": {
"reason": "invalid_credentials"
}
}
# 404 Not Found
{
"error": "not_found",
"message": "User not found",
"details": {
"id": "user-123"
}
}
Users API
List Users
Copy
# GET /users
curl -H "X-API-Key: your-api-key" \
"https://api.sparki.local/api/v1/users?page=1&limit=20&role=developer"
# Response
{
"data": [
{
"id": "user-123",
"email": "developer@sparki.io",
"name": "John Developer",
"roles": ["developer"],
"createdAt": "2025-01-01T00:00:00Z",
"lastLoginAt": "2025-12-13T10:30:00Z"
},
{
"id": "user-456",
"email": "admin@sparki.io",
"name": "Jane Admin",
"roles": ["admin"],
"createdAt": "2025-01-01T00:00:00Z",
"lastLoginAt": "2025-12-13T09:45:00Z"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 42,
"totalPages": 3
}
}
Get User Profile
Copy
# GET /users/:id
curl -H "X-API-Key: your-api-key" \
https://api.sparki.local/api/v1/users/user-123
# Response
{
"id": "user-123",
"email": "developer@sparki.io",
"name": "John Developer",
"roles": ["developer"],
"organization": {
"id": "org-123",
"name": "Sparki Inc"
},
"createdAt": "2025-01-01T00:00:00Z",
"updatedAt": "2025-12-13T10:30:00Z",
"lastLoginAt": "2025-12-13T10:30:00Z"
}
Create User
Copy
# POST /users
curl -X POST https://api.sparki.local/api/v1/users \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"email": "newdev@sparki.io",
"name": "New Developer",
"password": "secure-password-123",
"roles": ["developer"]
}'
# Response
{
"id": "user-789",
"email": "newdev@sparki.io",
"name": "New Developer",
"roles": ["developer"],
"createdAt": "2025-12-13T11:00:00Z"
}
Update User
Copy
# PATCH /users/:id
curl -X PATCH https://api.sparki.local/api/v1/users/user-123 \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"name": "John Developer Updated",
"roles": ["developer", "maintainer"]
}'
# Response
{
"id": "user-123",
"email": "developer@sparki.io",
"name": "John Developer Updated",
"roles": ["developer", "maintainer"],
"updatedAt": "2025-12-13T11:05:00Z"
}
Delete User
Copy
# DELETE /users/:id
curl -X DELETE https://api.sparki.local/api/v1/users/user-123 \
-H "X-API-Key: your-api-key"
# Response
{
"success": true,
"message": "User deleted successfully"
}
Projects API
List Projects
Copy
# GET /projects
curl -H "X-API-Key: your-api-key" \
"https://api.sparki.local/api/v1/projects?status=active&limit=50"
# Response
{
"data": [
{
"id": "proj-123",
"name": "Backend API",
"description": "Main backend service",
"status": "active",
"owner": {
"id": "user-123",
"name": "John Developer"
},
"members": 5,
"createdAt": "2025-01-15T00:00:00Z",
"updatedAt": "2025-12-13T10:00:00Z"
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 12
}
}
Get Project Details
Copy
# GET /projects/:id
curl -H "X-API-Key: your-api-key" \
https://api.sparki.local/api/v1/projects/proj-123
# Response
{
"id": "proj-123",
"name": "Backend API",
"description": "Main backend service",
"status": "active",
"visibility": "private",
"owner": {
"id": "user-123",
"name": "John Developer",
"email": "developer@sparki.io"
},
"members": [
{
"id": "user-123",
"name": "John Developer",
"role": "owner"
},
{
"id": "user-456",
"name": "Jane Contributor",
"role": "contributor"
}
],
"repository": {
"url": "https://github.com/sparki/backend",
"branch": "main"
},
"ci": {
"enabled": true,
"provider": "github-actions"
},
"createdAt": "2025-01-15T00:00:00Z",
"updatedAt": "2025-12-13T10:00:00Z"
}
Create Project
Copy
# POST /projects
curl -X POST https://api.sparki.local/api/v1/projects \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"name": "New Project",
"description": "Description of project",
"visibility": "private",
"repository": {
"url": "https://github.com/sparki/new-project"
}
}'
# Response
{
"id": "proj-999",
"name": "New Project",
"description": "Description of project",
"visibility": "private",
"status": "active",
"owner": {
"id": "user-123",
"name": "John Developer"
},
"createdAt": "2025-12-13T11:10:00Z"
}
Services API
List Services
Copy
# GET /services
curl -H "X-API-Key: your-api-key" \
"https://api.sparki.local/api/v1/services?project=proj-123&status=running"
# Response
{
"data": [
{
"id": "svc-123",
"name": "api-server",
"type": "backend",
"status": "running",
"image": "ghcr.io/sparki/api-server:v1.2.3",
"replicas": {
"desired": 3,
"ready": 3,
"available": 3
},
"endpoints": [
"https://api.sparki.local"
],
"health": {
"status": "healthy",
"lastCheck": "2025-12-13T11:15:30Z"
},
"createdAt": "2025-01-20T00:00:00Z"
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 8
}
}
Get Service Logs
Copy
# GET /services/:id/logs?lines=100&follow=false
curl -H "X-API-Key: your-api-key" \
"https://api.sparki.local/api/v1/services/svc-123/logs?lines=50"
# Response (streaming for follow=true)
{
"logs": [
{
"timestamp": "2025-12-13T11:20:00Z",
"level": "INFO",
"message": "Server started on :3000",
"pod": "api-server-abc123"
},
{
"timestamp": "2025-12-13T11:20:01Z",
"level": "INFO",
"message": "Connected to database",
"pod": "api-server-abc123"
}
]
}
Deploy Service
Copy
# POST /services/:id/deploy
curl -X POST https://api.sparki.local/api/v1/services/svc-123/deploy \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"image": "ghcr.io/sparki/api-server:v1.3.0",
"replicas": 5,
"strategy": "rolling-update"
}'
# Response
{
"deploymentId": "deploy-456",
"status": "in-progress",
"progress": {
"updated": 2,
"ready": 2,
"available": 2,
"desired": 5
},
"createdAt": "2025-12-13T11:25:00Z"
}
Rollback Service
Copy
# POST /services/:id/rollback
curl -X POST https://api.sparki.local/api/v1/services/svc-123/rollback \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"revision": "v1.2.3"
}'
# Response
{
"deploymentId": "deploy-789",
"status": "in-progress",
"targetImage": "ghcr.io/sparki/api-server:v1.2.3",
"previousImage": "ghcr.io/sparki/api-server:v1.3.0"
}
Infrastructure API
Get Cluster Status
Copy
# GET /infrastructure/cluster
curl -H "X-API-Key: your-api-key" \
https://api.sparki.local/api/v1/infrastructure/cluster
# Response
{
"name": "sparki-eks",
"version": "1.27.3",
"status": "healthy",
"nodes": {
"total": 10,
"ready": 10,
"notReady": 0
},
"compute": {
"cpuAllocatable": "40",
"memoryAllocatable": "160Gi",
"cpuUsed": "15.2",
"memoryUsed": "65.4Gi"
},
"storage": {
"persistentVolumes": 25,
"persistentVolumeClaims": 18,
"totalCapacity": "500Gi"
},
"networking": {
"networkPolicies": 8,
"serviceCount": 42,
"ingressCount": 12
},
"security": {
"podsecuritystandards": "enforced",
"rbacEnabled": true,
"networkPoliciesEnabled": true,
"encryptionAtRest": true
},
"lastHealthCheck": "2025-12-13T11:20:00Z"
}
Get Node Information
Copy
# GET /infrastructure/nodes
curl -H "X-API-Key: your-api-key" \
"https://api.sparki.local/api/v1/infrastructure/nodes"
# Response
{
"data": [
{
"name": "ip-10-0-1-50.ec2.internal",
"status": "Ready",
"type": "worker",
"instanceType": "t3.large",
"kubeletVersion": "v1.27.3",
"containerRuntimeVersion": "docker://20.10.21",
"osImage": "Amazon Linux 2",
"kernelVersion": "5.10.184-175.749.amzn2.x86_64",
"capacity": {
"cpu": "4",
"memory": "16Gi"
},
"allocatable": {
"cpu": "3.9",
"memory": "15Gi"
},
"podCount": 12,
"createdAt": "2025-06-01T00:00:00Z"
}
]
}
Get Resource Metrics
Copy
# GET /infrastructure/metrics
curl -H "X-API-Key: your-api-key" \
"https://api.sparki.local/api/v1/infrastructure/metrics"
# Response
{
"timestamp": "2025-12-13T11:25:00Z",
"cluster": {
"cpu": {
"used": "15.2",
"allocatable": "40",
"utilizationPercent": 38
},
"memory": {
"used": "65.4Gi",
"allocatable": "160Gi",
"utilizationPercent": 41
},
"disk": {
"used": "250Gi",
"allocatable": "500Gi",
"utilizationPercent": 50
}
},
"network": {
"ingressBytesPerSecond": 1024000,
"egressBytesPerSecond": 512000,
"connectionCount": 15000
}
}
Webhooks
Register Webhook
Copy
# POST /webhooks
curl -X POST https://api.sparki.local/api/v1/webhooks \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-service.com/webhooks/sparki",
"events": ["deployment.created", "deployment.completed", "alert.triggered"],
"active": true
}'
# Response
{
"id": "webhook-123",
"url": "https://your-service.com/webhooks/sparki",
"events": ["deployment.created", "deployment.completed", "alert.triggered"],
"active": true,
"secret": "whsec_1234567890abcdef",
"createdAt": "2025-12-13T11:30:00Z"
}
Webhook Payload Format
Copy
{
"id": "evt-123",
"timestamp": "2025-12-13T11:35:00Z",
"event": "deployment.completed",
"data": {
"deploymentId": "deploy-456",
"status": "success",
"service": "api-server",
"image": "ghcr.io/sparki/api-server:v1.3.0",
"duration": 120
}
}
Verify Webhook Signature
Copy
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
)
func verifyWebhookSignature(payload []byte, signature string, secret string) bool {
h := hmac.New(sha256.New, []byte(secret))
h.Write(payload)
expectedSignature := "sha256=" + hex.EncodeToString(h.Sum(nil))
return hmac.Equal([]byte(signature), []byte(expectedSignature))
}
SDKs & Client Libraries
Go SDK
Copy
go get github.com/sparki/sdk-go
Copy
import "github.com/sparki/sdk-go"
client := sdk.NewClient(
sdk.WithAPIKey("your-api-key"),
sdk.WithBaseURL("https://api.sparki.local"),
)
// List users
users, err := client.Users.List(ctx, &sdk.ListUsersOptions{
Limit: 20,
Page: 1,
})
// Get project
project, err := client.Projects.Get(ctx, "proj-123")
// Deploy service
deployment, err := client.Services.Deploy(ctx, "svc-123", &sdk.DeployOptions{
Image: "ghcr.io/sparki/api-server:v1.3.0",
Replicas: 5,
Strategy: "rolling-update",
})
JavaScript/TypeScript SDK
Copy
npm install @sparki/sdk-js
Copy
import { SparkiClient } from "@sparki/sdk-js";
const client = new SparkiClient({
apiKey: "your-api-key",
baseUrl: "https://api.sparki.local",
});
// List services
const services = await client.services.list({
project: "proj-123",
status: "running",
});
// Deploy service
const deployment = await client.services.deploy("svc-123", {
image: "ghcr.io/sparki/api-server:v1.3.0",
replicas: 5,
strategy: "rolling-update",
});
Python SDK
Copy
pip install sparki-sdk
Copy
from sparki import Client
client = Client(api_key="your-api-key")
# List projects
projects = client.projects.list(status="active", limit=50)
# Get service logs
logs = client.services.logs("svc-123", lines=100)
# Check cluster status
status = client.infrastructure.cluster_status()
Changelog
v1.0.0 (Current)
- Initial API release
- Core endpoints: Users, Projects, Services, Infrastructure
- WebhookAPI support
- SDKs for Go, JavaScript/TypeScript, Python
v1.1.0 (Planned - Q1 2026)
- OAuth 2.0 support
- GraphQL endpoint
- Batch operations
- Advanced analytics
Support
- Documentation: https://docs.sparki.io/api
- Examples: https://github.com/sparki/api-examples
- Issues: https://github.com/sparki/sparki-tools/issues
- Slack: #sparki-api-dev