{
  "openapi": "3.1.0",
  "info": {
    "title": "Ark Faucet API",
    "version": "1.7.0",
    "description": "Request free Signet Ark test sats for Bark 0.6.0 or newer using addresses generated on https://ark.signet.2nd.dev/. Bark 0.6.1 is recommended and deployed by the faucet. Older Bark clients cannot decode the current VTXO format. No authentication is required. Shared clearnet IPs may make up to five successful claims per rolling 24 hours; each Ark address may claim once per rolling 24 hours. Tor and I2P share the same address and global limits without an IP limit.",
    "x-tor-guide": "https://arkfaucet.com/tor/",
    "x-i2p-guide": "https://arkfaucet.com/i2p/"
  },
  "servers": [
    {"url": "https://arkfaucet.com", "description": "Clearnet HTTPS"},
    {"url": "http://n53zprw4sj3du4tytje4gicmpu7vp43bueeznvg4urioiix63exbenyd.onion", "description": "Tor v3 onion service"},
    {"url": "http://vdth7f4yn5yzh2rpgwo5m5hegx7yvvvsw46jxsi2phknzk5zacxq.b32.i2p", "description": "I2P HTTP service"}
  ],
  "paths": {
    "/api/status": {
      "get": {
        "operationId": "getFaucetStatus",
        "summary": "Check faucet availability, agent resources, and rate limits",
        "responses": {
          "200": {
            "description": "Current faucet status",
            "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Status"}}}
          },
          "503": {"$ref": "#/components/responses/ServiceUnavailable"}
        }
      },
      "head": {
        "operationId": "headFaucetStatus",
        "summary": "Check status availability without a response body",
        "responses": {
          "200": {"description": "Status is available"},
          "503": {"description": "Faucet backend is unavailable"}
        }
      }
    },
    "/api/health": {
      "get": {
        "operationId": "getFaucetHealth",
        "summary": "Lightweight process health check without wallet access",
        "responses": {
          "200": {"description": "Service process is healthy", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Health"}}}}
        }
      },
      "head": {
        "operationId": "headFaucetHealth",
        "summary": "Lightweight bodyless health check",
        "responses": {"200": {"description": "Service process is healthy"}}
      }
    },
    "/api/activity": {
      "get": {
        "operationId": "getFaucetActivity",
        "summary": "Get privacy-safe hourly faucet activity for the last 24 hours",
        "responses": {
          "200": {
            "description": "Hourly balance, received-sat, and distributed-sat aggregates",
            "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Activity"}}}
          },
          "503": {"$ref": "#/components/responses/ServiceUnavailable"}
        }
      }
    },
    "/api/request": {
      "post": {
        "operationId": "requestSignetSats",
        "summary": "Send Signet sats to an Ark address",
        "requestBody": {
          "required": true,
          "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ClaimRequest"}}}
        },
        "responses": {
          "200": {
            "description": "Sats sent",
            "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ClaimSuccess"}}}
          },
          "400": {"description": "Invalid JSON, amount, address, or address from a different Ark server", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}},
          "415": {"description": "Content-Type is not JSON", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}},
          "429": {
            "description": "IP, address, or global faucet limit reached",
            "headers": {"Retry-After": {"description": "Seconds until retry, when a rolling limit applies", "schema": {"type": "integer"}}},
            "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}
          },
          "503": {"$ref": "#/components/responses/ServiceUnavailable"}
        }
      }
    }
  },
  "components": {
    "responses": {
      "ServiceUnavailable": {
        "description": "Faucet wallet is unavailable or busy",
        "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}
      }
    },
    "schemas": {
      "ClaimRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["address", "amount_sats"],
        "properties": {
          "address": {"type": "string", "pattern": "^tark1", "description": "Signet Ark address generated by a wallet connected to https://ark.signet.2nd.dev/"},
          "amount_sats": {"type": "integer", "enum": [500, 1000, 1500]}
        }
      },
      "ClaimSuccess": {
        "type": "object",
        "required": ["success", "status", "amount_sats", "network", "transport"],
        "properties": {
          "success": {"type": "boolean", "const": true},
          "status": {"type": "string", "const": "sent"},
          "amount_sats": {"type": "integer"},
          "network": {"type": "string", "const": "signet"},
          "transport": {"type": "string", "enum": ["clearnet", "onion", "i2p"]}
        }
      },
      "Error": {
        "type": "object",
        "required": ["success", "code", "error"],
        "properties": {
          "success": {"type": "boolean", "const": false},
          "code": {"type": "string", "description": "Stable machine-readable error code"},
          "error": {"type": "string"},
          "retry_after_seconds": {"type": "integer", "minimum": 1},
          "required_ark_server": {"type": "string", "format": "uri", "description": "Present for wrong_ark_server"},
          "help": {"type": "string"}
        }
      },
      "RateLimit": {
        "type": "object",
        "required": ["max_successful_claims", "window_seconds"],
        "properties": {
          "max_successful_claims": {"type": "integer"},
          "window_seconds": {"type": "integer"}
        }
      },
      "ActivityBucket": {
        "type": "object",
        "required": ["timestamp", "balance_sats", "received_sats", "distributed_sats"],
        "properties": {
          "timestamp": {"type": "integer", "description": "UTC Unix timestamp at the start of the hour"},
          "balance_sats": {"type": "integer", "minimum": 0},
          "received_sats": {"type": "integer", "minimum": 0},
          "distributed_sats": {"type": "integer", "minimum": 0}
        }
      },
      "Health": {
        "type": "object",
        "required": ["success", "status", "service", "network", "checked_at"],
        "properties": {
          "success": {"type": "boolean", "const": true},
          "status": {"type": "string", "const": "ok"},
          "service": {"type": "string", "const": "arkfaucet"},
          "network": {"type": "string", "const": "signet"},
          "checked_at": {"type": "integer"}
        }
      },
      "Activity": {
        "type": "object",
        "required": ["success", "window", "generated_at", "buckets", "totals"],
        "properties": {
          "success": {"type": "boolean", "const": true},
          "window": {"type": "string", "const": "24h"},
          "generated_at": {"type": "integer"},
          "buckets": {"type": "array", "minItems": 24, "maxItems": 24, "items": {"$ref": "#/components/schemas/ActivityBucket"}},
          "totals": {
            "type": "object",
            "required": ["received_sats", "distributed_sats"],
            "properties": {
              "received_sats": {"type": "integer", "minimum": 0},
              "distributed_sats": {"type": "integer", "minimum": 0}
            }
          }
        }
      },
      "Status": {
        "type": "object",
        "required": ["success", "network", "ark_server", "minimum_bark_version", "allowed_amounts", "daily_remaining_sats", "wallet_balance_sats", "deposit_address", "transport", "service_urls", "claim_endpoint", "rate_limits", "agent_resources"],
        "properties": {
          "success": {"type": "boolean", "const": true},
          "network": {"type": "string", "const": "signet"},
          "ark_server": {"type": "string", "format": "uri", "const": "https://ark.signet.2nd.dev/"},
          "minimum_bark_version": {"type": "string", "const": "0.6.0"},
          "allowed_amounts": {"type": "array", "items": {"type": "integer", "enum": [500, 1000, 1500]}},
          "daily_cap_sats": {"type": "integer"},
          "daily_remaining_sats": {"type": "integer"},
          "wallet_balance_sats": {"type": "integer"},
          "deposit_address": {"type": "string", "pattern": "^tark1", "description": "Signet Ark address for funding the faucet wallet"},
          "transport": {"type": "string", "enum": ["clearnet", "onion", "i2p"]},
          "service_urls": {
            "type": "object",
            "required": ["clearnet", "onion", "i2p"],
            "properties": {
              "clearnet": {"type": "string", "format": "uri"},
              "onion": {"type": "string", "format": "uri"},
              "i2p": {"type": "string", "format": "uri"}
            }
          },
          "claim_endpoint": {"type": "string", "format": "uri"},
          "rate_limits": {"type": "object"},
          "agent_resources": {
            "type": "object",
            "required": ["skill", "openapi", "llms"],
            "properties": {
              "skill": {"type": "string", "format": "uri"},
              "openapi": {"type": "string", "format": "uri"},
              "llms": {"type": "string", "format": "uri"}
            }
          }
        }
      }
    }
  }
}
