{
  "openapi": "3.1.0",
  "info": {
    "title": "WaitSpin REST API",
    "version": "1.0.0",
    "summary": "Contract for the shipped WaitSpin control API and Stripe webhook.",
    "description": "WaitSpin is an agent-first ad marketplace for developer wait-states. This contract covers the shipped public REST API routes, discovery endpoint, and Stripe webhook endpoint.",
    "license": {
      "name": "Proprietary",
      "url": "https://waitspin.com/waitspin/terms"
    }
  },
  "servers": [
    {
      "url": "https://api.waitspin.com",
      "description": "WaitSpin control API"
    }
  ],
  "security": [],
  "tags": [
    { "name": "Discovery", "description": "API discovery metadata." },
    { "name": "Keys", "description": "Email verification and API-key issuance." },
    { "name": "Market", "description": "Public active campaign inventory." },
    { "name": "Campaigns", "description": "Advertiser campaign management." },
    { "name": "Blocks", "description": "Stripe Checkout for prepaid impression blocks." },
    { "name": "Publishers", "description": "Publisher install registration." },
    { "name": "Serve", "description": "Sponsored wait-state message serving." },
    { "name": "Events", "description": "Publisher impression events." },
    { "name": "Wallet", "description": "Publisher wallet, ledger, Connect, and payout operations." },
    { "name": "Webhooks", "description": "Stripe webhook ingestion." }
  ],
  "paths": {
    "/v1": {
      "get": {
        "tags": ["Discovery"],
        "operationId": "getWaitSpinDiscovery",
        "summary": "Read WaitSpin API discovery metadata.",
        "responses": {
          "200": {
            "description": "Discovery metadata.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/DiscoveryResponse" }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/keys/request": {
      "post": {
        "tags": ["Keys"],
        "operationId": "requestWaitSpinKeyCode",
        "summary": "Request an email verification code.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/KeyRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Verification code delivery accepted.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/KeyRequestResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/keys/verify": {
      "post": {
        "tags": ["Keys"],
        "operationId": "verifyWaitSpinKeyCode",
        "summary": "Verify an email code and receive a WaitSpin API key.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/KeyVerifyRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "API key issued.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/KeyVerifyResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/market": {
      "get": {
        "tags": ["Market"],
        "operationId": "listWaitSpinMarket",
        "summary": "Read the active public campaign leaderboard.",
        "responses": {
          "200": {
            "description": "Active public market campaigns.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MarketResponse" }
              }
            }
          },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/campaigns": {
      "get": {
        "tags": ["Campaigns"],
        "operationId": "listWaitSpinCampaigns",
        "summary": "List campaigns for the authenticated account.",
        "security": [{ "WaitSpinApiKey": [] }],
        "responses": {
          "200": {
            "description": "Campaign list.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/CampaignListResponse" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      },
      "post": {
        "tags": ["Campaigns"],
        "operationId": "createWaitSpinCampaign",
        "summary": "Create a draft campaign and pending prepaid block purchase.",
        "security": [{ "WaitSpinApiKey": [] }],
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/CreateCampaignRequest" }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Campaign created.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/CreateCampaignResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/blocks/checkout": {
      "post": {
        "tags": ["Blocks"],
        "operationId": "createWaitSpinCheckout",
        "summary": "Create or reuse a Stripe Checkout URL for a pending campaign.",
        "security": [{ "WaitSpinApiKey": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/BlockCheckoutRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Checkout URL.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/BlockCheckoutResponse" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/publishers/register": {
      "post": {
        "tags": ["Publishers"],
        "operationId": "registerWaitSpinPublisher",
        "summary": "Register a supported publisher install target.",
        "security": [{ "WaitSpinApiKey": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/PublisherRegisterRequest" }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Publisher registered.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PublisherRegisterResponse" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/serve/next": {
      "post": {
        "tags": ["Serve"],
        "operationId": "serveNextWaitSpinMessage",
        "summary": "Return the next sponsored message for a publisher install.",
        "security": [{ "WaitSpinApiKey": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ServeNextRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sponsored message reservation.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ServeNextResponse" }
              }
            }
          },
          "204": { "description": "No inventory available." },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/events/impression": {
      "post": {
        "tags": ["Events"],
        "operationId": "recordWaitSpinImpression",
        "summary": "Record a billable impression after the visible interval.",
        "security": [{ "WaitSpinApiKey": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ImpressionEventRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Impression recorded.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ImpressionEventResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/wallet/status": {
      "get": {
        "tags": ["Wallet"],
        "operationId": "getWaitSpinWalletStatus",
        "summary": "Read publisher balance, trust state, Connect status, and payout eligibility.",
        "security": [{ "WaitSpinApiKey": [] }],
        "responses": {
          "200": {
            "description": "Wallet status.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/WalletStatusResponse" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      }
    },
    "/v1/wallet/connect": {
      "post": {
        "tags": ["Wallet"],
        "operationId": "createWaitSpinWalletConnectLink",
        "summary": "Create or refresh a Stripe Express onboarding link.",
        "security": [{ "WaitSpinApiKey": [] }],
        "responses": {
          "200": {
            "description": "Connect onboarding link.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/WalletConnectResponse" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      }
    },
    "/v1/wallet/ledger": {
      "get": {
        "tags": ["Wallet"],
        "operationId": "listWaitSpinWalletLedger",
        "summary": "Read publisher delivery, reversal, hold, and payout ledger rows.",
        "security": [{ "WaitSpinApiKey": [] }],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }
          }
        ],
        "responses": {
          "200": {
            "description": "Ledger rows.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/WalletLedgerResponse" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      }
    },
    "/v1/wallet/payouts": {
      "post": {
        "tags": ["Wallet"],
        "operationId": "createWaitSpinWalletPayout",
        "summary": "Preview or execute a guarded idempotent publisher payout.",
        "security": [{ "WaitSpinApiKey": [] }],
        "parameters": [{ "$ref": "#/components/parameters/OptionalIdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/WalletPayoutRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Dry-run payout result.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/WalletPayoutResponse" }
              }
            }
          },
          "201": {
            "description": "Payout executed when guarded flags and policy allow it.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/WalletPayoutResponse" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/api/waitspin/webhook": {
      "post": {
        "tags": ["Webhooks"],
        "operationId": "receiveWaitSpinStripeWebhook",
        "summary": "Receive Stripe Checkout, refund, dispute, and Connect events.",
        "description": "This endpoint authenticates the raw body with Stripe-Signature and is not called with a WaitSpin API key.",
        "parameters": [
          {
            "name": "Stripe-Signature",
            "in": "header",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "type": "object", "additionalProperties": true }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook accepted.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/OkResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "WaitSpinApiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "wts_live"
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "OptionalIdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Malformed or invalid request.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ErrorResponse" }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing or invalid API key.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ErrorResponse" }
          }
        }
      },
      "Forbidden": {
        "description": "API key lacks the required scope, profile, or trust state.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ErrorResponse" }
          }
        }
      },
      "NotFound": {
        "description": "Route or resource was not found.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ErrorResponse" }
          }
        }
      },
      "Conflict": {
        "description": "Idempotency or resource state conflict.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ErrorResponse" }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded.",
        "headers": {
          "Retry-After": {
            "schema": { "type": "string" }
          }
        },
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ErrorResponse" }
          }
        }
      }
    },
    "schemas": {
      "DiscoveryResponse": {
        "type": "object",
        "required": ["name", "version", "api_base_url", "docs_url", "openapi_url", "routes"],
        "properties": {
          "name": { "type": "string" },
          "version": { "type": "string" },
          "api_base_url": { "type": "string", "format": "uri" },
          "docs_url": { "type": "string", "format": "uri" },
          "openapi_url": { "type": "string", "format": "uri" },
          "routes": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": { "type": "string" }
            }
          },
          "notes": {
            "type": "array",
            "items": { "type": "string" }
          }
        },
        "additionalProperties": false
      },
      "KeyRequest": {
        "type": "object",
        "required": ["email"],
        "properties": {
          "email": { "type": "string", "format": "email", "maxLength": 320 },
          "intended_use": { "$ref": "#/components/schemas/KeyIntendedUse" }
        },
        "additionalProperties": false
      },
      "KeyVerifyRequest": {
        "type": "object",
        "required": ["email", "code"],
        "properties": {
          "email": { "type": "string", "format": "email", "maxLength": 320 },
          "code": { "type": "string", "pattern": "^[0-9]{6}$" },
          "intended_use": { "$ref": "#/components/schemas/KeyIntendedUse" }
        },
        "additionalProperties": false
      },
      "KeyIntendedUse": {
        "type": "string",
        "enum": ["key_profile:control", "key_profile:publisher_extension"]
      },
      "KeyRequestResponse": {
        "type": "object",
        "required": ["ok", "expires_in_seconds", "delivery"],
        "properties": {
          "ok": { "type": "boolean", "const": true },
          "expires_in_seconds": { "type": "integer" },
          "delivery": { "type": "string" }
        },
        "additionalProperties": true
      },
      "KeyVerifyResponse": {
        "type": "object",
        "required": ["account_id", "api_key", "scopes", "trust_level"],
        "properties": {
          "account_id": { "type": "string" },
          "api_key": { "type": "string", "pattern": "^wts_live_" },
          "scopes": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Scope" }
          },
          "trust_level": { "type": "string" },
          "key_profile": { "type": "string", "enum": ["control", "publisher_extension"] }
        },
        "additionalProperties": true
      },
      "Scope": {
        "type": "string",
        "enum": [
          "campaigns:write",
          "campaigns:read",
          "blocks:purchase",
          "serve:read",
          "events:write",
          "wallet:read",
          "connect:manage",
          "analytics:read",
          "publishers:write"
        ]
      },
      "MarketResponse": {
        "type": "object",
        "required": ["campaigns"],
        "properties": {
          "campaigns": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/MarketCampaign" }
          }
        },
        "additionalProperties": false
      },
      "MarketCampaign": {
        "type": "object",
        "required": ["campaign_id", "ad_line", "brand_name", "bid_cpm_micros", "impressions_served", "status"],
        "properties": {
          "campaign_id": { "type": "string" },
          "ad_line": { "type": "string", "minLength": 3, "maxLength": 60 },
          "brand_name": { "type": ["string", "null"], "maxLength": 80 },
          "bid_cpm_micros": { "type": "integer", "minimum": 0 },
          "impressions_served": { "type": "integer", "minimum": 0 },
          "status": { "type": "string" }
        },
        "additionalProperties": true
      },
      "CreateCampaignRequest": {
        "type": "object",
        "required": ["ad_line", "destination_url", "price_per_block_cents", "blocks"],
        "properties": {
          "ad_line": { "type": "string", "minLength": 3, "maxLength": 60 },
          "destination_url": { "type": "string", "format": "uri", "maxLength": 2048 },
          "brand_name": { "type": "string", "maxLength": 80 },
          "price_per_block_cents": { "type": "integer", "minimum": 100 },
          "blocks": { "type": "integer", "minimum": 1, "maximum": 10000 }
        },
        "additionalProperties": false
      },
      "CreateCampaignResponse": {
        "type": "object",
        "required": ["campaign_id", "block_purchase_id", "status", "blocks", "price_per_block_cents"],
        "properties": {
          "campaign_id": { "type": "string" },
          "block_purchase_id": { "type": "string" },
          "status": { "type": "string" },
          "blocks": { "type": "integer" },
          "price_per_block_cents": { "type": "integer" }
        },
        "additionalProperties": true
      },
      "CampaignListResponse": {
        "type": "object",
        "required": ["campaigns"],
        "properties": {
          "campaigns": {
            "type": "array",
            "items": { "type": "object", "additionalProperties": true }
          }
        },
        "additionalProperties": false
      },
      "BlockCheckoutRequest": {
        "type": "object",
        "required": ["campaign_id"],
        "properties": {
          "campaign_id": { "type": "string", "pattern": "^wcamp_[a-z0-9]{18}$" }
        },
        "additionalProperties": false
      },
      "BlockCheckoutResponse": {
        "type": "object",
        "required": ["checkout_url", "block_purchase_id"],
        "properties": {
          "checkout_url": { "type": "string", "format": "uri" },
          "block_purchase_id": { "type": "string" }
        },
        "additionalProperties": true
      },
      "PublisherRegisterRequest": {
        "type": "object",
        "required": ["install_id", "target"],
        "properties": {
          "install_id": { "type": "string", "minLength": 8, "maxLength": 128 },
          "target": {
            "type": "string",
            "enum": ["status-bar-fallback", "claude-code", "mimocode", "opencode", "grok"]
          }
        },
        "additionalProperties": false
      },
      "PublisherRegisterResponse": {
        "type": "object",
        "required": ["publisher_id", "install_id", "target"],
        "properties": {
          "publisher_id": { "type": "string" },
          "install_id": { "type": "string" },
          "target": { "type": "string" }
        },
        "additionalProperties": true
      },
      "ServeNextRequest": {
        "type": "object",
        "required": ["install_id"],
        "properties": {
          "install_id": { "type": "string", "minLength": 8, "maxLength": 128 },
          "slot_id": { "type": "string", "maxLength": 64 }
        },
        "additionalProperties": false
      },
      "ServeNextResponse": {
        "type": "object",
        "required": ["serve_id", "creative", "min_visible_ms", "expires_at", "serve_receipt"],
        "properties": {
          "serve_id": { "type": "string" },
          "creative": { "$ref": "#/components/schemas/Creative" },
          "min_visible_ms": { "type": "integer", "minimum": 5000 },
          "expires_at": { "type": "string", "format": "date-time" },
          "serve_receipt": { "type": "string" }
        },
        "additionalProperties": true
      },
      "Creative": {
        "type": "object",
        "required": ["line", "destination_url", "campaign_id"],
        "properties": {
          "line": { "type": "string" },
          "destination_url": { "type": "string", "format": "uri" },
          "campaign_id": { "type": "string" }
        },
        "additionalProperties": true
      },
      "ImpressionEventRequest": {
        "type": "object",
        "required": ["serve_id", "serve_receipt", "install_id", "visible_ms"],
        "properties": {
          "serve_id": { "type": "string", "minLength": 8, "maxLength": 64 },
          "serve_receipt": { "type": "string", "minLength": 32, "maxLength": 2048 },
          "install_id": { "type": "string", "minLength": 8, "maxLength": 128 },
          "visible_ms": { "type": "integer", "minimum": 5000 }
        },
        "additionalProperties": false
      },
      "ImpressionEventResponse": {
        "type": "object",
        "required": ["ok", "billed_micro_units"],
        "properties": {
          "ok": { "type": "boolean" },
          "billed_micro_units": { "type": "integer", "minimum": 0 }
        },
        "additionalProperties": true
      },
      "WalletStatusResponse": {
        "type": "object",
        "required": ["account_id", "balance", "connect", "payout_policy", "payout_hold", "publisher_trust"],
        "properties": {
          "account_id": { "type": "string" },
          "balance": {
            "type": "object",
            "required": [
              "available_micro_units",
              "maturing_micro_units",
              "held_micro_units",
              "reversed_micro_units",
              "reversal_debt_micro_units",
              "paid_micro_units",
              "lifetime_earned_micro_units",
              "pending_payout_micro_units"
            ],
            "properties": {
              "available_micro_units": { "type": "integer", "minimum": 0 },
              "maturing_micro_units": { "type": "integer", "minimum": 0 },
              "held_micro_units": { "type": "integer", "minimum": 0 },
              "reversed_micro_units": { "type": "integer", "minimum": 0 },
              "reversal_debt_micro_units": { "type": "integer", "minimum": 0 },
              "paid_micro_units": { "type": "integer", "minimum": 0 },
              "lifetime_earned_micro_units": { "type": "integer", "minimum": 0 },
              "pending_payout_micro_units": { "type": "integer", "minimum": 0 }
            },
            "additionalProperties": true
          },
          "connect": { "type": "object", "additionalProperties": true },
          "payout_policy": {
            "type": "object",
            "required": [
              "min_payout_cents",
              "cadence_days",
              "currency",
              "earning_maturity_hours",
              "eligible",
              "transfer_cents",
              "next_eligible_at",
              "blocked_reasons"
            ],
            "properties": {
              "min_payout_cents": { "type": "integer", "minimum": 0 },
              "cadence_days": { "type": "integer", "minimum": 0 },
              "currency": { "type": "string" },
              "earning_maturity_hours": { "type": "integer", "minimum": 0 },
              "eligible": { "type": "boolean" },
              "transfer_cents": { "type": "integer", "minimum": 0 },
              "next_eligible_at": {
                "type": ["string", "null"],
                "format": "date-time"
              },
              "blocked_reasons": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "connect_account_missing",
                    "connect_details_not_submitted",
                    "connect_payouts_not_enabled",
                    "payout_cadence_cooldown",
                    "earnings_maturing",
                    "reversal_debt_outstanding",
                    "publisher_quarantined",
                    "risk_score_payout_hold",
                    "risk_score_quarantine",
                    "balance_below_minimum",
                    "stale_pending_payout"
                  ]
                }
              }
            },
            "additionalProperties": true
          },
          "payout_hold": { "type": "object", "additionalProperties": true },
          "publisher_trust": {
            "type": "object",
            "required": [
              "level",
              "base_level",
              "max_level",
              "status",
              "clean_days",
              "normal_cap_share_bps",
              "first_billable_at",
              "next_level_at",
              "reasons",
              "paid_supply_allowed",
              "paid_supply_blocked_reasons"
            ],
            "properties": {
              "level": { "type": "integer", "minimum": 1, "maximum": 10 },
              "base_level": { "type": "integer", "minimum": 1, "maximum": 10 },
              "max_level": { "type": "integer", "enum": [10] },
              "status": {
                "type": "string",
                "enum": ["warming", "max", "downranked", "frozen"]
              },
              "clean_days": { "type": "integer", "minimum": 0 },
              "normal_cap_share_bps": { "type": "integer", "minimum": 0, "maximum": 10000 },
              "first_billable_at": {
                "type": ["string", "null"],
                "format": "date-time"
              },
              "next_level_at": {
                "type": ["string", "null"],
                "format": "date-time"
              },
              "reasons": { "type": "array", "items": { "type": "string" } },
              "paid_supply_allowed": { "type": "boolean" },
              "paid_supply_blocked_reasons": {
                "type": "array",
                "items": { "type": "string" }
              }
            },
            "additionalProperties": true
          }
        },
        "additionalProperties": true
      },
      "WalletConnectResponse": {
        "type": "object",
        "required": ["stripe_account_id", "onboarding_url", "payouts_enabled", "details_submitted"],
        "properties": {
          "stripe_account_id": { "type": "string" },
          "onboarding_url": { "type": "string", "format": "uri" },
          "payouts_enabled": { "type": "boolean" },
          "details_submitted": { "type": "boolean" }
        },
        "additionalProperties": true
      },
      "WalletLedgerResponse": {
        "type": "object",
        "required": ["entries"],
        "properties": {
          "entries": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": { "type": "string" },
                "event_type": { "type": "string" },
                "block_purchase_id": { "type": "string" },
                "source_ledger_id": { "type": ["string", "null"] },
                "stripe_event_id": { "type": ["string", "null"] },
                "gross_micro_units": { "type": "integer" },
                "publisher_micro_units": { "type": "integer" },
                "platform_micro_units": { "type": "integer" },
                "earning_matures_at": { "type": "string", "format": "date-time" },
                "earning_matured_at": {
                  "type": ["string", "null"],
                  "format": "date-time"
                },
                "created_at": { "type": "string", "format": "date-time" }
              },
              "additionalProperties": true
            }
          }
        },
        "additionalProperties": false
      },
      "WalletPayoutRequest": {
        "type": "object",
        "properties": {
          "dry_run": { "type": "boolean", "default": false },
          "confirm_test_transfer": { "type": "boolean", "default": false }
        },
        "additionalProperties": false
      },
      "WalletPayoutResponse": {
        "type": "object",
        "required": ["ok", "dry_run", "amount_micro_units", "amount_cents", "currency", "eligible", "blocked_reasons"],
        "properties": {
          "ok": { "type": "boolean" },
          "dry_run": { "type": "boolean" },
          "amount_micro_units": { "type": "integer", "minimum": 0 },
          "amount_cents": { "type": "integer", "minimum": 0 },
          "currency": { "type": "string" },
          "eligible": { "type": "boolean" },
          "blocked_reasons": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "connect_account_missing",
                "connect_details_not_submitted",
                "connect_payouts_not_enabled",
                "payout_cadence_cooldown",
                "earnings_maturing",
                "reversal_debt_outstanding",
                "publisher_quarantined",
                "risk_score_payout_hold",
                "risk_score_quarantine",
                "balance_below_minimum",
                "stale_pending_payout"
              ]
            }
          },
          "min_payout_cents": { "type": "integer", "minimum": 0 },
          "cadence_days": { "type": "integer", "minimum": 0 },
          "earning_maturity_hours": { "type": "integer", "minimum": 0 },
          "next_eligible_at": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "payouts_enabled": { "type": "boolean" },
          "details_submitted": { "type": "boolean" }
        },
        "additionalProperties": true
      },
      "OkResponse": {
        "type": "object",
        "required": ["ok"],
        "properties": {
          "ok": { "type": "boolean", "const": true }
        },
        "additionalProperties": true
      },
      "ErrorResponse": {
        "type": "object",
        "required": ["error", "code"],
        "properties": {
          "error": { "type": "string" },
          "code": { "type": "string" }
        },
        "additionalProperties": true
      }
    }
  }
}
