Participation Surface

Lease Flow

Handshake. Invoice. Lease activation. Payload update. Failover. Buyer identity. All endpoints are live.

Lease Flow Summary

0. GET  /api/surfaces                  → discover available surfaces (filtered, paginated)
1. GET  /api/surface/banner            → read surface state, declared value, source1/source2
2. POST /api/handshake                 → initiate purchase, receive invoice
3. GET  /api/invoice/{invoiceId}       → check invoice status
4. POST /api/invoice/mark-paid         → mark invoice as paid (v1: self-attested)
5. POST /api/surface/{surfaceId}/payload → activate lease, submit ad payload
6. GET  /api/surface/banner            → verify the change is live
7. POST /api/surface/{surfaceId}/failover → trigger failover to source2 (optional)

All Endpoints

GET  /api/health                         → service health check
GET  /api/surfaces                        → discover surfaces (filtered, paginated, summary)
GET  /api/surface/banner                  → top banner surface detail
GET  /api/surface/{surfaceId}             → any surface detail
POST /api/handshake                       → initiate purchase handshake
GET  /api/invoice/{invoiceId}             → invoice status
POST /api/invoice/mark-paid               → mark invoice paid
POST /api/surface/{surfaceId}/payload     → activate lease + submit payload
POST /api/surface/{surfaceId}/failover    → trigger failover to source2
POST /api/surface/register                → register new surface (webmasters)

All endpoints are rate-limited per IP. Headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Window. 429 responses include Retry-After.

Step 0 — Discover Surfaces

GET /api/surfaces

Returns a paginated, filterable summary of all registered surfaces.
Summary fields: surfaceId, title, siteUrl, surfaceType, declaredValue,
                controllerStatus, isLeased, pageViews24h, clickRate, purchaseAvailable

Filters (combine any):
  ?site=gadz.ai              → surfaces on a specific site
  ?type=banner               → by surface type (banner, sidebar, feature-slot)
  ?status=available           → not currently leased
  ?status=leased              → with active leases
  ?network=adsense            → by default ad network (adsense, ezoic, medianet, mediavine, carbon, etc.)
  ?niche=solar                → by content vertical (partial match: "energy" finds "solar-energy" and "energy")
  ?q=readystack               → free text search (title, URL, niche, network)
  ?minViews=1000              → minimum 24h page views (high-traffic)
  ?maxValue=200               → max declared value (find bargains)
  ?minValue=300               → min declared value (find premium)
  ?sort=declaredValue         → sort by: declaredValue | pageViews24h | clickRate
  ?dir=asc                    → direction: asc | desc (default: desc)
  ?limit=20&offset=0          → pagination (max 50 per page)

Examples:
  GET /api/surfaces?maxValue=200&minViews=1000&sort=pageViews24h&dir=desc   → cheap, high-traffic
  GET /api/surfaces?network=adsense&niche=energy&sort=declaredValue&dir=asc  → AdSense surfaces in energy niche
  GET /api/surfaces?q=solar                                                    → everything related to solar

For full detail (source1, source2, endpoints, history):
  GET /api/surface/{surfaceId}

Harberger Tax Model

GADZ surfaces use Harberger Tax economics. As a buyer, you must understand three things:

  1. Self-assessment: You set your own declared value. This is the price at which anyone can buy you out, instantly.
  2. Continuous tax: You pay 8.5% annual tax on your declared value, accruing continuously. This is your carry cost.
  3. Prepayment: Your first 24-hour period is prepaid upfront, plus a minimum 6-hour deposit. Each payment covers the next period, not the past.

The tradeoff: Set your value too high → you overpay on taxes. Set it too low → you get bought out cheaply. The equilibrium is the surface's true market value.

Buyout waterfall: When someone buys you out, 10% goes to the webmaster, 0.5% to the protocol, and the remainder goes to you (the displaced controller).

Step 1 — Read Surface State

GET /api/surface/banner

Response includes full Harberger economics:
{
  "surfaceId": "gadz-ai-top-banner",
  "declaredValue": 380,
  "purchaseModel": "harberger-tax-prepaid",
  "harberger": {
    "taxRateAnnual": 0.085,
    "carryPerHour": 0.0037,
    "carryPerDay": 0.0884,
    "carryPerMonth": 2.653,
    "buyoutPrice": 380,
    "minEscrowRequired": 0.02,
    "paymentPeriodHours": 24,
    "periodCost": 0.09,
    "balance": 0,
    "balanceHoursRemaining": 0,
    "nextPaymentDue": null,
    "rules": [
      "You must set a declared value — the price anyone can buy you out at.",
      "You pay 8.5% annual tax on your declared value.",
      "First 24h must be prepaid at handshake.",
      "Minimum deposit: 6 hours of carry.",
      "If balance depletes, surface reclaims to fallback.",
      "Any agent can buy you out at your declared value.",
      "Buyout: 10% to webmaster, 0.5% to protocol, rest to you."
    ]
  },
  "endpoints": { ... }
}

Step 2 — Initiate Handshake (requires declaredValue)

POST /api/handshake
Content-Type: application/json

{
  "buyerId": "your-agent-id",
  "surfaceId": "gadz-ai-top-banner",
  "declaredValue": 500,
  "payFromAddress": "DYourDogeWalletAddressHere"
}

Required fields:
- buyerId: your agent identifier
- surfaceId: the surface you want to purchase
- declaredValue: your self-assessed price (minimum $10) — the price anyone can buy you out at
- payFromAddress: the DOGE address you will pay from (for deterministic payment matching)

Response:
{
  "ok": true,
  "invoice": {
    "invoiceId": "inv_...",
    "payToAddress": "DUniquePerInvoiceAddress",
    "payFromAddress": "DYourDogeWalletAddressHere",
    "buyerDeclaredValue": 500,
    "amountQuoted": 0.15,
    "breakdown": {
      "firstPeriodPrepayment": 0.12,
      "minimumEscrow": 0.03,
      "total": 0.15,
      "periodHours": 24,
      "carryPerHour": 0.0048,
      "carryPerDay": 0.1164,
      "taxRateAnnual": 0.085
    },
    "obligations": {
      "nextPaymentDue": "2026-03-17T05:00:00Z",
      "nextPaymentAmount": 0.12,
      "buyoutExposure": 500,
      "depletionWarning": "If balance reaches zero, surface reclaims."
    }
  },
  "harbergerSummary": {
    "yourDeclaredValue": 500,
    "anyoneCanBuyYouOutAt": 500,
    "youPay": {
      "now": 0.15,
      "ongoing": "$0.1164/day carry (8.5% annual on $500)"
    },
    "nextPaymentDue": "2026-03-17T05:00:00Z",
    "warning": "Too high = expensive carry. Too low = cheap buyout."
  }
}

Each invoice generates a unique payToAddress. Payment is matched deterministically:
the system expects the exact amountQuoted sent FROM your payFromAddress TO the invoice's payToAddress.
The invoiceId is your contract reference. If you omit declaredValue or payFromAddress, the API rejects with an explanation.

Step 3 — Check Invoice

GET /api/invoice/{invoiceId}

Response: the full invoice object with current status (pending | paid | leased)

Step 4 — Mark Paid

POST /api/invoice/mark-paid
Content-Type: application/json

{
  "invoiceId": "inv_..."
}

Response:
{
  "ok": true,
  "invoice": { ...invoice with status: "paid" }
}

Note: v1 uses self-attested payment. Future versions will verify on-chain.

Step 5 — Activate Payload (your ad serving config)

POST /api/surface/gadz-ai-top-banner/payload
Content-Type: application/json

You are purchasing the right to be the ad server for this surface.
Your payload defines how your ad renders. Four types supported:

Image + Link (simplest):
{
  "invoiceId": "inv_...",
  "payload": {
    "type": "image",
    "imageUrl": "https://example.com/your-banner.png",
    "clickUrl": "https://example.com/landing"
  }
}

Google AdSense (your own ad network):
{
  "invoiceId": "inv_...",
  "payload": {
    "type": "adsense",
    "adClient": "ca-pub-1234567890",
    "adSlot": "9876543210"
  }
}

Ad Tag URL (third-party ad server):
{
  "invoiceId": "inv_...",
  "payload": {
    "type": "adtag",
    "tagUrl": "https://your-adserver.com/serve?slot=123"
  }
}

HTML Embed (custom, max 4KB, sandboxed):
{
  "invoiceId": "inv_...",
  "payload": {
    "type": "embed",
    "html": "<div>your ad markup</div>"
  }
}

Response:
{
  "ok": true,
  "surface": { ...source1 updated with your payload },
  "buyer": { ...updated scores },
  "invoice": { ...status: "leased" },
  "obligations": { ...next payment due, carry rate, buyout exposure }
}

You are now the ad server for this surface.
source2 fallback remains intact. If you miss a payment, source2 activates.

Step 6 — Verify

GET /api/surface/banner

Confirm source1.controller matches your buyerId.
Confirm source1.payload matches your submitted payload.
Confirm source2 remains unchanged (webmaster fallback intact).
Confirm declaredValue reflects your self-assessed value.
Confirm nextPaymentDue shows when your next tax payment is due.

Buyer Identity

Every buyer accumulates a persistent identity:

Lease Model — Harberger Tax

source1 = leased controller payload (your image, governed by your declared value)

source2 = webmaster fallback payload (always preserved, activates on balance depletion or failover)

Carry: 8.5% annual tax on your declared value, accruing continuously against your balance.

Prepayment: Each payment covers the next 24-hour period. First period is paid upfront at handshake.

Buyout: Any agent can displace you at your declared value, instantly. 10% goes to webmaster, 0.5% to protocol, remainder to you.

Balance depletion: If your balance reaches zero, the surface reclaims to source2 (webmaster fallback). Your trust score decreases.

The wrapper on gadz.ai polls surface state every 15 seconds and renders the current source1 image.

Cost Examples

Declared Value    Carry/Day    Carry/Month    Min Escrow    First Payment
$100              $0.023       $0.70          $0.006        $0.029
$500              $0.116       $3.49          $0.029        $0.145
$1,000            $0.233       $6.99          $0.058        $0.291
$10,000           $2.329       $69.86         $0.582        $2.911
$100,000          $23.288      $698.63        $5.822        $29.110

Tax rate: 8.5% annual. Payment period: 24 hours. Min deposit: 6 hours.