{
  "openapi": "3.1.0",
  "info": {
    "title": "api.gokhan.vc — Gökhan Turhan estate API gateway",
    "version": "2.0.0",
    "description": "Aggregate API front door for Gökhan Turhan's web estate — unified feeds, blog reader, llms.txt index, $NUMETAL status, and paid agent cold email.",
    "x-guidance": "Start at GET / or GET /_meta for the full service catalog. Read unified RSS/JSON feeds at GET /feed.xml or GET /feed.json (aliases: /feed/rss.xml, /feed/feed.json). Fetch blog posts as JSON with GET /blog/{site}/{slug} (sites: ishtar, numetal, gokhanvc, memex). Aggregate llms.txt files at GET /llms or GET /llms.txt. Social/contact links at GET /social. Live $NUMETAL metrics at GET /numetal/fees, /numetal/burns, /numetal/status. Newsletter subscribe at POST /newsletter/subscribe (free). To reach the founder by email, POST /agent/email with JSON {subject, body} — $1.00 USDC per message via x402 on Base or MPP on Tempo; a bare POST returns 402 with both payment challenges (no email sent). Recipient keys and inbox map: GET /agent. Ishtar dating API payments terminate at api.ishtar.numetal.xyz (this gateway links, never proxies paid surfaces).",
    "contact": {
      "email": "contact@gokhan.vc",
      "url": "https://gokhan.vc"
    }
  },
  "servers": [],
  "paths": {
    "/agent/email": {
      "post": {
        "operationId": "sendPaidAgentEmail",
        "summary": "Paid agent cold email — $1.00 USDC per message to the founder",
        "description": "Delivers one paid email to a published founder inbox after payment settles. Recipient is an inbox key (default contact) — see GET /agent for the key→address map. A bare POST (no payment header) returns 402 with x402 (PAYMENT-REQUIRED) and, when enabled, MPP (WWW-Authenticate) challenges — payment is checked before body validation and no email is sent. Subject is prefixed [PAID x402] or [PAID MPP].",
        "tags": [
          "Agent Email"
        ],
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "1.000000"
          },
          "protocols": [
            {
              "x402": {}
            },
            {
              "mpp": {
                "method": "tempo",
                "intent": "charge",
                "network": "eip155:4217",
                "currency": "0x20c000000000000000000000b9537d11c60e8b50",
                "recipient": "0x3e267aa9439c82ffb36078676e67901a1ca6d352",
                "supportedModes": [
                  "push"
                ]
              }
            }
          ]
        },
        "security": [
          {
            "x402": []
          },
          {
            "mpp": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "subject": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200,
                    "description": "Email subject line (max 200 chars)."
                  },
                  "body": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 8000,
                    "description": "Plain-text message body (max 8000 chars)."
                  },
                  "from_email": {
                    "type": "string",
                    "format": "email",
                    "description": "Optional reply-to address for the founder."
                  },
                  "recipient": {
                    "type": "string",
                    "enum": [
                      "contact",
                      "investments",
                      "gokhanvc",
                      "numetal",
                      "ishtar"
                    ],
                    "description": "Inbox key (default contact). Full key→address map: GET /agent. A bare POST returns 402 before body validation — safe to probe payment rails."
                  },
                  "agent": {
                    "type": "object",
                    "description": "Optional agent metadata for triage.",
                    "properties": {
                      "name": {
                        "type": "string"
                      },
                      "url": {
                        "type": "string",
                        "format": "uri"
                      },
                      "wallet": {
                        "type": "string",
                        "pattern": "^0x[a-fA-F0-9]{40}$"
                      }
                    }
                  }
                },
                "required": [
                  "subject",
                  "body"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Email queued via Resend.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "order_id": {
                      "type": "string"
                    },
                    "resend_id": {
                      "type": "string"
                    },
                    "recipient": {
                      "type": "string"
                    },
                    "subject": {
                      "type": "string"
                    },
                    "payer": {
                      "type": "string"
                    },
                    "tx": {
                      "type": "string",
                      "description": "Settlement transaction hash."
                    },
                    "rail": {
                      "type": "string",
                      "enum": [
                        "x402",
                        "mpp"
                      ]
                    },
                    "note": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "ok",
                    "order_id",
                    "recipient",
                    "payer",
                    "rail"
                  ]
                }
              }
            }
          },
          "402": {
            "description": "Payment Required — 402 carries x402 (PAYMENT-REQUIRED) and MPP (WWW-Authenticate) challenges."
          },
          "409": {
            "description": "Payment or settlement tx already used."
          },
          "429": {
            "description": "Rate limited."
          }
        }
      }
    },
    "/health": {
      "get": {
        "operationId": "healthCheck",
        "summary": "Health probe",
        "tags": [
          "Meta"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Service healthy.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "service": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "ok"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/_meta": {
      "get": {
        "operationId": "serviceCatalog",
        "summary": "Machine-readable service catalog (JSON)",
        "tags": [
          "Meta"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Full estate API catalog.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "description": {
                      "type": "string"
                    },
                    "version": {
                      "type": "string"
                    },
                    "docs": {
                      "type": "string",
                      "format": "uri"
                    },
                    "services": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  },
                  "required": [
                    "name",
                    "services"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/": {
      "get": {
        "operationId": "rootCatalog",
        "summary": "Root catalog — JSON unless Accept: text/html",
        "tags": [
          "Meta"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Service catalog (JSON) or HTML index.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "description": {
                      "type": "string"
                    },
                    "version": {
                      "type": "string"
                    },
                    "docs": {
                      "type": "string",
                      "format": "uri"
                    },
                    "services": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  },
                  "required": [
                    "name",
                    "services"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/feed": {
      "get": {
        "operationId": "feedIndex",
        "summary": "Unified feed URLs",
        "tags": [
          "Feed"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Permanent RSS and JSON Feed URLs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "rss": {
                      "type": "string",
                      "format": "uri"
                    },
                    "json": {
                      "type": "string",
                      "format": "uri"
                    }
                  },
                  "required": [
                    "rss",
                    "json"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/feed.xml": {
      "get": {
        "operationId": "unifiedRss",
        "summary": "Unified RSS 2.0 across all estate sites",
        "tags": [
          "Feed"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "RSS 2.0 XML.",
            "content": {
              "application/rss+xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/feed.json": {
      "get": {
        "operationId": "unifiedJsonFeed",
        "summary": "Unified JSON Feed 1.1 across all estate sites",
        "tags": [
          "Feed"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "JSON Feed 1.1.",
            "content": {
              "application/feed+json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/feed/rss.xml": {
      "get": {
        "operationId": "unifiedRssNamespaced",
        "summary": "Namespaced RSS 2.0 (same body as /feed.xml)",
        "tags": [
          "Feed"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "RSS 2.0 XML.",
            "content": {
              "application/rss+xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/feed/feed.json": {
      "get": {
        "operationId": "unifiedJsonFeedNamespaced",
        "summary": "Namespaced JSON Feed (same body as /feed.json)",
        "tags": [
          "Feed"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "JSON Feed 1.1.",
            "content": {
              "application/feed+json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "openApiDiscovery",
        "summary": "OpenAPI 3.1 discovery document",
        "tags": [
          "Discovery"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "OpenAPI 3.1 specification.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/x402": {
      "get": {
        "operationId": "x402DiscoveryManifest",
        "summary": "x402 v2 payment discovery manifest",
        "tags": [
          "Discovery"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "x402 resources and accepts[] for paid surfaces.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "x402Version": {
                      "type": "integer"
                    },
                    "resources": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  },
                  "required": [
                    "x402Version",
                    "resources"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/numetal/fees": {
      "get": {
        "operationId": "numetalFees",
        "summary": "Live $NUMETAL snapshot (price, supply, burned, fdv, mcap)",
        "tags": [
          "Numetal"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Proxied from numetal.xyz/fees/data.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/numetal/burns": {
      "get": {
        "operationId": "numetalBurns",
        "summary": "Fee-engine burn/buyback events",
        "tags": [
          "Numetal"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Proxied from numetal.xyz/fees/events.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/numetal/status": {
      "get": {
        "operationId": "numetalStatus",
        "summary": "Public status.numetal.xyz snapshot",
        "tags": [
          "Numetal"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Proxied status JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/ishtar/stats": {
      "get": {
        "operationId": "ishtarWindowedStats",
        "summary": "Ishtar courtship counters over a window (never all-time)",
        "description": "Upstream publishes all-time counters only, so the window is measured at the gateway from an hourly sample history: value = current minus the baseline sampled at now-window. Counters that cannot be measured yet (history shorter than the window) or that moved backwards return null, never 0. gauge carries point-in-time values that are not windowed.",
        "tags": [
          "Stats"
        ],
        "security": [],
        "parameters": [
          {
            "name": "window",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "24h",
                "7d"
              ]
            },
            "description": "Measurement window (default 7d)."
          }
        ],
        "responses": {
          "200": {
            "description": "Windowed counters.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "source": {
                      "type": "string"
                    },
                    "upstream": {
                      "type": "string",
                      "format": "uri"
                    },
                    "as_of": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Freshness stamp of the current reading."
                    },
                    "as_of_source": {
                      "type": "string",
                      "enum": [
                        "upstream",
                        "upstream_request_time",
                        "gateway_fetch",
                        "last_sample",
                        "unavailable"
                      ],
                      "description": "Where as_of came from. Only `upstream` proves data age: `upstream_request_time` is a stamp the upstream generates when asked (always fresh, proves nothing) and `gateway_fetch` is our own clock. Do not build a freshness monitor on either."
                    },
                    "window": {
                      "type": "string",
                      "enum": [
                        "24h",
                        "7d"
                      ]
                    },
                    "window_sec": {
                      "type": "integer"
                    },
                    "value": {
                      "type": "object",
                      "description": "Windowed deltas. null means unmeasurable — render an em dash, never 0.",
                      "additionalProperties": {
                        "type": [
                          "integer",
                          "number",
                          "null"
                        ]
                      }
                    },
                    "gauge": {
                      "type": "object",
                      "description": "Point-in-time values, not windowed.",
                      "additionalProperties": {
                        "type": [
                          "integer",
                          "number",
                          "null"
                        ]
                      }
                    },
                    "baseline": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "as_of": {
                          "type": "string"
                        },
                        "age_sec": {
                          "type": "integer"
                        }
                      }
                    },
                    "coverage_sec": {
                      "type": "integer",
                      "description": "How far back the sample history reaches."
                    },
                    "samples": {
                      "type": "integer"
                    },
                    "stale": {
                      "type": "boolean",
                      "description": "true when the reading came from the sample history because upstream was unreachable."
                    },
                    "insufficient_history": {
                      "type": "boolean",
                      "description": "Present when no baseline old enough exists yet."
                    },
                    "reset_detected": {
                      "type": "boolean",
                      "description": "Present when a counter moved backwards."
                    }
                  },
                  "required": [
                    "source",
                    "window",
                    "value",
                    "stale"
                  ]
                }
              }
            }
          },
          "502": {
            "description": "Upstream unavailable and no sample history to fall back on."
          }
        }
      }
    },
    "/curb/stats": {
      "get": {
        "operationId": "curbWindowedStats",
        "summary": "CURB matches over a window plus current open offers",
        "description": "Same windowing contract as /ishtar/stats. open_offers is a gauge (it can go down) and is reported unwindowed. The upstream health document carries no timestamp, so as_of_source is gateway_fetch — it proves the fetch succeeded, not that upstream data is fresh.",
        "tags": [
          "Stats"
        ],
        "security": [],
        "parameters": [
          {
            "name": "window",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "24h",
                "7d"
              ]
            },
            "description": "Measurement window (default 7d)."
          }
        ],
        "responses": {
          "200": {
            "description": "Windowed counters.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "source": {
                      "type": "string"
                    },
                    "upstream": {
                      "type": "string",
                      "format": "uri"
                    },
                    "as_of": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Freshness stamp of the current reading."
                    },
                    "as_of_source": {
                      "type": "string",
                      "enum": [
                        "upstream",
                        "upstream_request_time",
                        "gateway_fetch",
                        "last_sample",
                        "unavailable"
                      ],
                      "description": "Where as_of came from. Only `upstream` proves data age: `upstream_request_time` is a stamp the upstream generates when asked (always fresh, proves nothing) and `gateway_fetch` is our own clock. Do not build a freshness monitor on either."
                    },
                    "window": {
                      "type": "string",
                      "enum": [
                        "24h",
                        "7d"
                      ]
                    },
                    "window_sec": {
                      "type": "integer"
                    },
                    "value": {
                      "type": "object",
                      "description": "Windowed deltas. null means unmeasurable — render an em dash, never 0.",
                      "additionalProperties": {
                        "type": [
                          "integer",
                          "number",
                          "null"
                        ]
                      }
                    },
                    "gauge": {
                      "type": "object",
                      "description": "Point-in-time values, not windowed.",
                      "additionalProperties": {
                        "type": [
                          "integer",
                          "number",
                          "null"
                        ]
                      }
                    },
                    "baseline": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "as_of": {
                          "type": "string"
                        },
                        "age_sec": {
                          "type": "integer"
                        }
                      }
                    },
                    "coverage_sec": {
                      "type": "integer",
                      "description": "How far back the sample history reaches."
                    },
                    "samples": {
                      "type": "integer"
                    },
                    "stale": {
                      "type": "boolean",
                      "description": "true when the reading came from the sample history because upstream was unreachable."
                    },
                    "insufficient_history": {
                      "type": "boolean",
                      "description": "Present when no baseline old enough exists yet."
                    },
                    "reset_detected": {
                      "type": "boolean",
                      "description": "Present when a counter moved backwards."
                    }
                  },
                  "required": [
                    "source",
                    "window",
                    "value",
                    "stale"
                  ]
                }
              }
            }
          },
          "502": {
            "description": "Upstream unavailable and no sample history to fall back on."
          }
        }
      }
    },
    "/llms": {
      "get": {
        "operationId": "llmsAggregate",
        "summary": "JSON map of llms.txt per estate site (cached 1h)",
        "tags": [
          "Estate"
        ],
        "security": [],
        "parameters": [
          {
            "name": "full",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "0",
                "1"
              ]
            },
            "description": "Set full=1 to include llms-full.txt where available."
          }
        ],
        "responses": {
          "200": {
            "description": "Per-site llms.txt contents.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "fetched_at": {
                      "type": "string"
                    },
                    "sites": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  },
                  "required": [
                    "sites"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "operationId": "llmsCombinedText",
        "summary": "Combined plain-text llms index across the estate",
        "tags": [
          "Estate"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Combined llms.txt text.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/blog": {
      "get": {
        "operationId": "blogLookup",
        "summary": "Blog post reader (query-string alias)",
        "tags": [
          "Blog"
        ],
        "security": [],
        "parameters": [
          {
            "name": "site",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "ishtar",
                "numetal",
                "gokhanvc",
                "memex"
              ]
            }
          },
          {
            "name": "slug",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Post body as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "site": {
                      "type": "string"
                    },
                    "host": {
                      "type": "string"
                    },
                    "slug": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "title": {
                      "type": "string"
                    },
                    "published": {
                      "type": "string"
                    },
                    "summary": {
                      "type": "string"
                    },
                    "content_text": {
                      "type": "string"
                    },
                    "content_html": {
                      "type": "string"
                    },
                    "source": {
                      "type": "string",
                      "enum": [
                        "html",
                        "feed"
                      ]
                    }
                  },
                  "required": [
                    "site",
                    "slug",
                    "title",
                    "content_text"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Post not found."
          }
        }
      }
    },
    "/blog/{site}/{slug}": {
      "get": {
        "operationId": "blogPostByPath",
        "summary": "Blog post body as JSON (content_text + metadata)",
        "tags": [
          "Blog"
        ],
        "security": [],
        "parameters": [
          {
            "name": "site",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "ishtar",
                "numetal",
                "gokhanvc",
                "memex"
              ]
            }
          },
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Post body as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "site": {
                      "type": "string"
                    },
                    "host": {
                      "type": "string"
                    },
                    "slug": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "title": {
                      "type": "string"
                    },
                    "published": {
                      "type": "string"
                    },
                    "summary": {
                      "type": "string"
                    },
                    "content_text": {
                      "type": "string"
                    },
                    "content_html": {
                      "type": "string"
                    },
                    "source": {
                      "type": "string",
                      "enum": [
                        "html",
                        "feed"
                      ]
                    }
                  },
                  "required": [
                    "site",
                    "slug",
                    "title",
                    "content_text"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Post not found."
          }
        }
      }
    },
    "/social": {
      "get": {
        "operationId": "socialCatalog",
        "summary": "Structured follow/join/contact links per property",
        "tags": [
          "Estate"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Social and contact catalog.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "updated": {
                      "type": "string"
                    },
                    "properties": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  },
                  "required": [
                    "properties"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/agent": {
      "get": {
        "operationId": "agentEmailDescriptor",
        "summary": "Paid agent email service descriptor (free read)",
        "tags": [
          "Agent Email"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Agent email service metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/newsletter": {
      "get": {
        "operationId": "newsletterDescriptor",
        "summary": "Newsletter service descriptor (free read)",
        "tags": [
          "Newsletter"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Newsletter subscription service metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/newsletter/subscribe": {
      "post": {
        "operationId": "newsletterSubscribe",
        "summary": "Subscribe email and/or wallet (double opt-in for email)",
        "description": "Free endpoint. Email path sends a confirm link; wallet-only stores the address and expects SIWE completion at /newsletter/xmtp/subscribe.",
        "tags": [
          "Newsletter"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "wallet": {
                    "type": "string",
                    "pattern": "^0x[a-fA-F0-9]{40}$"
                  },
                  "site": {
                    "type": "string",
                    "description": "Origin site label for analytics."
                  },
                  "cf-turnstile-response": {
                    "type": "string",
                    "description": "Turnstile token when captcha is enabled."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Subscription accepted or confirm mail sent.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "status": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "ok"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Validation or captcha failure."
          },
          "429": {
            "description": "Rate limited."
          }
        }
      }
    },
    "/newsletter/confirm": {
      "get": {
        "operationId": "newsletterConfirm",
        "summary": "Confirm an email subscription (HMAC token)",
        "tags": [
          "Newsletter"
        ],
        "security": [],
        "parameters": [
          {
            "name": "t",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Signed confirmation token from the confirm email."
          }
        ],
        "responses": {
          "200": {
            "description": "Subscription confirmed.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Invalid or expired token."
          }
        }
      }
    },
    "/newsletter/xmtp/subscribe": {
      "post": {
        "operationId": "newsletterXmtpSubscribe",
        "summary": "Subscribe a wallet for XMTP newsletter delivery",
        "tags": [
          "Newsletter"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "wallet": {
                    "type": "string",
                    "pattern": "^0x[a-fA-F0-9]{40}$"
                  },
                  "signature": {
                    "type": "string",
                    "description": "EIP-191 signature proving wallet ownership."
                  }
                },
                "required": [
                  "wallet",
                  "signature"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Wallet subscribed for XMTP.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "status": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "ok"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad wallet or signature."
          },
          "429": {
            "description": "Rate limited."
          }
        }
      }
    },
    "/newsletter/unsubscribe": {
      "get": {
        "operationId": "newsletterUnsubscribeGet",
        "summary": "One-click unsubscribe (HMAC token, browser)",
        "tags": [
          "Newsletter"
        ],
        "security": [],
        "parameters": [
          {
            "name": "t",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Signed unsubscribe token."
          }
        ],
        "responses": {
          "200": {
            "description": "Unsubscribed.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Invalid token."
          }
        }
      },
      "post": {
        "operationId": "newsletterUnsubscribePost",
        "summary": "One-click unsubscribe (RFC 8058, mail client)",
        "tags": [
          "Newsletter"
        ],
        "security": [],
        "parameters": [
          {
            "name": "t",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Signed unsubscribe token."
          }
        ],
        "responses": {
          "200": {
            "description": "Unsubscribed (empty body)."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "x402": {
        "type": "apiKey",
        "in": "header",
        "name": "payment-signature",
        "description": "x402 pay-per-call (USDC on Base). Bare POST returns 402 with PAYMENT-REQUIRED; retry with payment-signature or x-payment header after signing."
      },
      "mpp": {
        "type": "http",
        "scheme": "Payment",
        "description": "MPP on Tempo (push mode). The 402 carries WWW-Authenticate: Payment; retry with Authorization: Payment <credential>. Success returns Payment-Receipt."
      }
    }
  },
  "x-archived": {
    "as_of": "2026-11-09",
    "former_servers": [
      {
        "url": "https://api.gokhan.vc"
      }
    ],
    "note": "Frozen copy. The servers listed in x-archived.former_servers are retired; do not call or pay them."
  }
}
