{
  "openapi": "3.1.0",
  "info": {
    "title": "Kilawatt Cloud x402 GPU compute",
    "version": "2.0.0",
    "description": "Pay-per-job GPU capacity with multi-provider failover, settled in USDC on Base. The request provisions capacity and does not accept code or commands.",
    "contact": {
      "email": "hello@kilawattcloud.dev"
    },
    "license": {
      "name": "Proprietary"
    }
  },
  "servers": [
    {
      "url": "https://www.kilawattcloud.dev"
    }
  ],
  "paths": {
    "/api/public/x402/exec": {
      "get": {
        "summary": "Not supported",
        "responses": {
          "405": {
            "description": "Method not allowed; Allow: POST, OPTIONS"
          }
        }
      },
      "post": {
        "operationId": "execGpuJob",
        "summary": "Provision and run a GPU job, paid per call over x402",
        "description": "Returns HTTP 402 with x402 payment requirements when no payment is attached. Supports x402 v1 with X-PAYMENT and a body challenge, and v2 with PAYMENT-SIGNATURE and PAYMENT-REQUIRED headers. v2 identifies Base mainnet as eip155:8453. The request provisions tracked GPU capacity; it has no field for code or commands, and the public API does not expose workload output.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Send the same key on paid retries. If a paid response was lost, a retry with the same key and a new payment authorization returns the original job id and status instead of creating a second job."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Only the listed fields affect the request. Other fields are ignored. There is no field for source code, commands, container images, or workload payloads.",
                "additionalProperties": true,
                "properties": {
                  "gpu_type": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "default": "nvidia-h100",
                    "enum": [
                      "nvidia-b300",
                      "nvidia-b200",
                      "nvidia-h200",
                      "nvidia-h100",
                      "nvidia-a100",
                      "nvidia-l40s",
                      "nvidia-l40",
                      "nvidia-a40",
                      "nvidia-a10",
                      "nvidia-rtx-a6000",
                      "nvidia-rtx-a5000",
                      "nvidia-rtx-a4500",
                      "nvidia-rtx-a4000",
                      "nvidia-rtx-5090",
                      "nvidia-rtx-4090",
                      "nvidia-rtx-3090"
                    ],
                    "description": "GPU model to provision. Any other value returns HTTP 400 unknown_gpu_type with the list of valid values."
                  },
                  "card_count": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 16,
                    "default": 1,
                    "description": "Number of GPUs in the job. Minimum 1. Maximum: 8 for H100, H200, A100, and L40S; 4 for B200; 16 for workstation-class cards. Other GPU classes use the server-enforced class limit."
                  },
                  "duration_seconds": {
                    "type": "number",
                    "minimum": 60,
                    "maximum": 86400,
                    "default": 600,
                    "description": "Requested runtime in seconds. Billing and pre-authorization use this value."
                  },
                  "routing_policy": {
                    "type": "string",
                    "enum": [
                      "lowest_cost",
                      "lowest_latency",
                      "zero_quota"
                    ],
                    "default": "lowest_cost",
                    "description": "Provider selection policy across the failover chain."
                  },
                  "workload_type": {
                    "type": "string",
                    "enum": [
                      "agent_exec",
                      "fine_tune",
                      "batch_inference"
                    ],
                    "default": "agent_exec",
                    "description": "Workload class dispatched through the Kilawatt gateway."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Payment settled and job dispatched",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "Kilawatt job identifier, normally the same value as job_id."
                    },
                    "job_id": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Execution record identifier used by GET /api/public/v1/jobs/{job_id}."
                    },
                    "instance_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "description": "provisioning when the node accepts the job."
                    },
                    "ready": {
                      "type": "boolean"
                    },
                    "health_status": {
                      "type": "string"
                    },
                    "provider": {
                      "type": "string",
                      "description": "Kilawatt infrastructure. The provider field is intentionally identical for every job and does not identify the upstream supplier."
                    },
                    "workload_type": {
                      "type": "string"
                    },
                    "gpu_type": {
                      "type": "string"
                    },
                    "card_count": {
                      "type": "integer"
                    },
                    "routing_policy": {
                      "type": "string"
                    },
                    "failover_hops": {
                      "type": "integer"
                    },
                    "billed_usd": {
                      "type": "number",
                      "description": "Exact job charge from the credited balance. The current x402 pricing path rounds this charge up to whole cents."
                    },
                    "provisioned_gpu": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "pricing_basis": {
                      "type": "string"
                    },
                    "health_monitoring": {
                      "type": "object"
                    },
                    "sla_credit_usd": {
                      "type": "number"
                    },
                    "payment": {
                      "type": "object",
                      "properties": {
                        "transaction_hash": {
                          "type": "string"
                        },
                        "network": {
                          "type": "string"
                        },
                        "amount_usd": {
                          "type": "number",
                          "description": "Full signed amount settled on-chain and credited, expressed in whole cents."
                        },
                        "payer": {
                          "type": "string"
                        }
                      }
                    },
                    "api_key": {
                      "type": "string",
                      "description": "The machine account's long-lived API key. Returned only in the wallet's first successful paid response because only its hash is stored; it cannot be recovered later."
                    }
                  }
                }
              }
            },
            "headers": {
              "PAYMENT-RESPONSE": {
                "description": "Base64-encoded x402 v2 settlement receipt",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request. code is one of: invalid_json (body is not a JSON object), unknown_gpu_type (includes valid_gpu_types), size_not_available (card count above 8 cannot be placed right now), wrong_payment_header (x402Version does not match the header: v1 uses X-PAYMENT, v2 uses PAYMENT-SIGNATURE), or a payment-payload error. No payment is taken."
          },
          "402": {
            "description": "Payment required, or the attached payment was not accepted. code price_changed (v1 and v2, v2 adds required_amount_usd) means the signed amount no longer covers the job; code insufficient_funds_or_invalid_signature means the wallet may lack USDC on Base or the signature is invalid.",
            "headers": {
              "PAYMENT-REQUIRED": {
                "description": "Base64-encoded x402 v2 PaymentRequired document",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Rejected by sanctions screening"
          },
          "409": {
            "description": "code payment_already_used: this payment authorization was already settled. Includes transaction_hash and, when known, job_id. Nothing is charged again."
          },
          "415": {
            "description": "code unsupported_media_type: Content-Type must be application/json"
          },
          "503": {
            "description": "No capacity can be priced or placed right now. No payment is taken; retry later. When code is unpriceable, the body may also include priceable_gpu_types (gpu_type values that can be priced right now) and a hint string. Both are omitted if that list cannot be built in time."
          }
        }
      }
    },
    "/api/public/v1/jobs/{job_id}/checkpoint": {
      "post": {
        "operationId": "saveJobCheckpoint",
        "summary": "Optional: save a checkpoint so a replacement machine resumes from the last checkpoint",
        "description": "Optional resume feature. If the machine serving a job is lost, a replacement can be placed and resumes from the last checkpoint. Authenticate with the job owner's API key (Authorization: Bearer kw_live_...) or the job token given to the machine (X-Kilawatt-Job-Token; the replacement receives KILAWATT_CHECKPOINT_URL and KILAWATT_JOB_TOKEN). The newest 10 checkpoints are kept, and all are deleted 30 days after the job ends.",
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "seq",
                  "payload"
                ],
                "properties": {
                  "seq": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "payload": {
                    "description": "Any JSON value, at most 262144 bytes"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Replay of an already saved seq; nothing changed"
          },
          "201": {
            "description": "Saved"
          },
          "401": {
            "description": "Missing or invalid API key or job token"
          },
          "404": {
            "description": "Job not found, or the feature is not enabled"
          },
          "409": {
            "description": "code seq_conflict or seq_not_increasing"
          },
          "413": {
            "description": "code checkpoint_too_large: store large files elsewhere and save only a pointer"
          },
          "429": {
            "description": "At most one save per 10 seconds per job"
          }
        }
      }
    },
    "/api/public/v1/jobs/{job_id}/checkpoint/latest": {
      "get": {
        "operationId": "getLatestJobCheckpoint",
        "summary": "Optional: newest checkpoint for a job",
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Newest checkpoint: job_id, seq, payload, payload_bytes, saved_at"
          },
          "401": {
            "description": "Missing or invalid API key or job token"
          },
          "404": {
            "description": "No checkpoint saved, job not found, or the feature is not enabled"
          }
        }
      }
    }
  }
}