Skip to main content

Sparki API Reference Documentation

Version: 1.0.0
Last Updated: December 2025
Base URL: https://api.sparki.local/api/v1

Table of Contents

  1. Authentication
  2. Rate Limiting
  3. Error Handling
  4. Users API
  5. Projects API
  6. Services API
  7. Infrastructure API
  8. Webhooks
  9. SDKs & Client Libraries

Authentication

Overview

All API requests require authentication using either API Keys or Bearer Tokens.

API Key Authentication

# 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

# 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

# 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

# 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

// 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

{
    "error": "error_code",
    "message": "Human-readable error message",
    "details": {
        "field": "error_detail",
        "reason": "validation_failed"
    },
    "requestId": "req-123-abc"
}

Common Error Codes

CodeHTTPDescription
invalid_request400Malformed request or invalid parameters
authentication_failed401Invalid or missing credentials
insufficient_permissions403User lacks required permissions
not_found404Resource does not exist
conflict409Resource already exists or conflict detected
rate_limit_exceeded429Too many requests
server_error500Internal server error
service_unavailable503Service temporarily unavailable

Error Response Examples

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# 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

{
    "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

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

go get github.com/sparki/sdk-go
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

npm install @sparki/sdk-js
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

pip install sparki-sdk
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