{"openapi":"3.1.0","info":{"title":"windle API","version":"0.1.0","description":"Sign-in and accounts for windle.fun. JSON over HTTPS; public routes are versioned under `/v1`.\n\n**Authentication.** Sign-In With Solana: get a single-use input from `GET /v1/auth/siws/nonce`, have the wallet sign it (`solana:signIn`), then `POST /v1/auth/siws/verify`. The session is an HttpOnly cookie (`wl_session`, Domain=.windle.fun), so browser clients call with `credentials: \"include\"`. There are no API keys.\n\n**Browsers.** Credentialed CORS is limited to an exact-origin allow-list; state-changing requests from other origins get `403 csrf_rejected`.\n\n**Errors.** Every non-2xx body is `{ \"error\": { \"code\", \"message\", \"requestId\" } }`. Branch on `code`.\n\n**Rate limits.** Per client IP; `429 rate_limited` with `Retry-After` and `X-RateLimit-*` headers.\n\n**Request ids.** Every response has `X-Request-Id`; send your own to correlate logs.","contact":{"name":"windle","url":"https://docs.windle.fun/api/overview/"}},"components":{"securitySchemes":{"session":{"type":"apiKey","in":"cookie","name":"wl_session","description":"HttpOnly session cookie set by POST /v1/auth/siws/verify. Browsers send it with `credentials: \"include\"`."}},"schemas":{}},"paths":{"/":{"get":{"summary":"Service index","tags":["System"],"description":"A small JSON index of the service. Browsers (an `Accept` header preferring `text/html`) get the windle API home page instead; the response varies on `Accept`.","responses":{"200":{"description":"Service index.","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Service name.","examples":["windle-api"]},"version":{"type":"string","description":"API package version.","examples":["0.1.0"]},"commit":{"description":"Build identifier of the running release.","type":"string"},"status":{"type":"string","enum":["ok"]},"docs":{"type":"string","format":"uri","description":"Human documentation."},"reference":{"type":"string","format":"uri","description":"Interactive API reference."},"openapi":{"type":"string","format":"uri","description":"OpenAPI 3.1 document."},"health":{"type":"string","format":"uri","description":"Liveness endpoint."}},"required":["name","version","status","docs","reference","openapi","health"],"additionalProperties":false,"description":"Service index."}}}}}}},"/health":{"get":{"summary":"Liveness","tags":["System"],"description":"The process is up and its event loop answers. Never checks dependencies, so a database outage does not get healthy containers restarted. Not rate limited.","responses":{"200":{"description":"Alive.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok"]}},"required":["status"],"additionalProperties":false,"description":"Alive."}}}}}}},"/ready":{"get":{"summary":"Readiness (Postgres + Redis)","tags":["System"],"description":"Pings Postgres and Redis (1.5 s timeout each) and reports per-dependency status and latency. Answers `503` with the same body when either is down. Not rate limited.","responses":{"200":{"description":"Both dependencies answered.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ready","not_ready"]},"checks":{"type":"object","properties":{"postgres":{"type":"object","properties":{"status":{"type":"string","enum":["up","down"],"description":"Whether the dependency answered within the timeout."},"latencyMs":{"type":"number","description":"Round-trip time of the ping, in milliseconds.","examples":[2]}},"required":["status","latencyMs"],"additionalProperties":false},"redis":{"type":"object","properties":{"status":{"type":"string","enum":["up","down"],"description":"Whether the dependency answered within the timeout."},"latencyMs":{"type":"number","description":"Round-trip time of the ping, in milliseconds.","examples":[2]}},"required":["status","latencyMs"],"additionalProperties":false}},"required":["postgres","redis"],"additionalProperties":false}},"required":["status","checks"],"additionalProperties":false,"description":"Both dependencies answered."}}}},"503":{"description":"At least one dependency is down or timed out.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ready","not_ready"]},"checks":{"type":"object","properties":{"postgres":{"type":"object","properties":{"status":{"type":"string","enum":["up","down"],"description":"Whether the dependency answered within the timeout."},"latencyMs":{"type":"number","description":"Round-trip time of the ping, in milliseconds.","examples":[2]}},"required":["status","latencyMs"],"additionalProperties":false},"redis":{"type":"object","properties":{"status":{"type":"string","enum":["up","down"],"description":"Whether the dependency answered within the timeout."},"latencyMs":{"type":"number","description":"Round-trip time of the ping, in milliseconds.","examples":[2]}},"required":["status","latencyMs"],"additionalProperties":false}},"required":["postgres","redis"],"additionalProperties":false}},"required":["status","checks"],"additionalProperties":false,"description":"At least one dependency is down or timed out."}}}}}}},"/v1/auth/providers":{"get":{"summary":"List sign-in methods","tags":["Auth"],"description":"Which sign-in methods this server offers. Only `siws` is live today; the others are reserved and answer `501`.","responses":{"200":{"description":"Sign-in methods and whether each is enabled.","content":{"application/json":{"schema":{"type":"object","properties":{"providers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["siws","email","x","google","telegram","discord"],"description":"Sign-in method id."},"enabled":{"type":"boolean","description":"Whether this server accepts the method right now."}},"required":["id","enabled"],"additionalProperties":false}}},"required":["providers"],"additionalProperties":false,"description":"Sign-in methods and whether each is enabled."}}}}}}},"/v1/auth/siws/nonce":{"get":{"summary":"Get a sign-in nonce","tags":["Auth"],"description":"Step 1 of Sign-In With Solana. Returns the complete `SolanaSignInInput` to pass unchanged to the wallet `solana:signIn` feature. The nonce is stored server-side and can be redeemed once by `POST /v1/auth/siws/verify` before `expirationTime` (5 minutes). GET and POST (no body) are equivalent.","responses":{"200":{"description":"A fresh sign-in input. The nonce is redeemable once, until `input.expirationTime`.","content":{"application/json":{"schema":{"type":"object","properties":{"nonce":{"type":"string","pattern":"^[A-Za-z0-9]{8,}$","description":"Single-use server nonce (alphanumeric, at least 8 characters).","examples":["k7Q2mX9vT4pL8wRz"]},"input":{"type":"object","properties":{"domain":{"type":"string","minLength":1,"description":"Host the user is signing in to (RFC 3986 authority).","examples":["oauth.windle.fun"]},"statement":{"description":"Human-readable line the wallet shows.","examples":["Sign in to windle"],"type":"string"},"uri":{"type":"string","format":"uri","description":"Origin of the sign-in page.","examples":["https://oauth.windle.fun"]},"version":{"type":"string","description":"SIWS message version.","enum":["1"]},"chainId":{"type":"string","enum":["mainnet","devnet","testnet"],"description":"Solana cluster the sign-in is bound to."},"nonce":{"type":"string","pattern":"^[A-Za-z0-9]{8,}$","description":"Single-use server nonce (alphanumeric, at least 8 characters).","examples":["k7Q2mX9vT4pL8wRz"]},"issuedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the nonce was issued (ISO 8601, UTC)."},"expirationTime":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"After this instant the nonce can no longer be redeemed."}},"required":["domain","uri","version","chainId","nonce","issuedAt","expirationTime"],"additionalProperties":false,"description":"SolanaSignInInput: pass it unchanged to the wallet `solana:signIn` feature."}},"required":["nonce","input"],"additionalProperties":false,"description":"A fresh sign-in input. The nonce is redeemable once, until `input.expirationTime`."}}}},"400":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"401":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"403":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"429":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"501":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"503":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}}}},"post":{"summary":"Get a sign-in nonce","tags":["Auth"],"description":"Step 1 of Sign-In With Solana. Returns the complete `SolanaSignInInput` to pass unchanged to the wallet `solana:signIn` feature. The nonce is stored server-side and can be redeemed once by `POST /v1/auth/siws/verify` before `expirationTime` (5 minutes). GET and POST (no body) are equivalent.","responses":{"200":{"description":"A fresh sign-in input. The nonce is redeemable once, until `input.expirationTime`.","content":{"application/json":{"schema":{"type":"object","properties":{"nonce":{"type":"string","pattern":"^[A-Za-z0-9]{8,}$","description":"Single-use server nonce (alphanumeric, at least 8 characters).","examples":["k7Q2mX9vT4pL8wRz"]},"input":{"type":"object","properties":{"domain":{"type":"string","minLength":1,"description":"Host the user is signing in to (RFC 3986 authority).","examples":["oauth.windle.fun"]},"statement":{"description":"Human-readable line the wallet shows.","examples":["Sign in to windle"],"type":"string"},"uri":{"type":"string","format":"uri","description":"Origin of the sign-in page.","examples":["https://oauth.windle.fun"]},"version":{"type":"string","description":"SIWS message version.","enum":["1"]},"chainId":{"type":"string","enum":["mainnet","devnet","testnet"],"description":"Solana cluster the sign-in is bound to."},"nonce":{"type":"string","pattern":"^[A-Za-z0-9]{8,}$","description":"Single-use server nonce (alphanumeric, at least 8 characters).","examples":["k7Q2mX9vT4pL8wRz"]},"issuedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the nonce was issued (ISO 8601, UTC)."},"expirationTime":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"After this instant the nonce can no longer be redeemed."}},"required":["domain","uri","version","chainId","nonce","issuedAt","expirationTime"],"additionalProperties":false,"description":"SolanaSignInInput: pass it unchanged to the wallet `solana:signIn` feature."}},"required":["nonce","input"],"additionalProperties":false,"description":"A fresh sign-in input. The nonce is redeemable once, until `input.expirationTime`."}}}},"400":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"401":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"403":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"429":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"501":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"503":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}}}}},"/v1/auth/siws/verify":{"post":{"summary":"Verify a signature and sign in","tags":["Auth"],"description":"Body is the wallet `SolanaSignInOutput` encoded for JSON: `signedMessage` base64, `signature` base58. The signed text must match the issued input field-for-field. On success the `wl_session` cookie is set (HttpOnly, Secure, SameSite=Lax, Domain=.windle.fun) and the session + profile are returned. A first sign-in creates the account. Any session already on the request is replaced.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"nonce":{"type":"string","pattern":"^[A-Za-z0-9]{8,}$","description":"Single-use server nonce (alphanumeric, at least 8 characters).","examples":["k7Q2mX9vT4pL8wRz"]},"address":{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]{32,44}$","description":"Wallet that signed; must equal the address inside the signed text.","examples":["7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy"]},"signedMessage":{"type":"string","format":"byte","pattern":"^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$","description":"`SolanaSignInOutput.signedMessage`: the exact bytes the wallet signed, base64-encoded."},"signature":{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]{64,88}$","description":"`SolanaSignInOutput.signature`: the 64-byte ed25519 signature, base58-encoded.","examples":["5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW"]}},"required":["nonce","address","signedMessage","signature"],"description":"The wallet `SolanaSignInOutput`, encoded for JSON."}}},"description":"The wallet `SolanaSignInOutput`, encoded for JSON."},"responses":{"200":{"description":"Signed in. The `wl_session` cookie is set on this response.","content":{"application/json":{"schema":{"type":"object","properties":{"session":{"type":"object","properties":{"authenticated":{"type":"boolean","enum":[true]},"userId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Id of the signed-in user."},"address":{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]{32,44}$","description":"Wallet the session was started with.","examples":["7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy"]},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Sliding expiry; every authenticated call pushes it forward."}},"required":["authenticated","userId","address","expiresAt"],"additionalProperties":false,"description":"Signed in."},"me":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Stable user id.","examples":["0b8f3c0e-6a51-4d47-9a8e-2f4c1d7b9e10"]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Account creation time (ISO 8601, UTC)."},"wallets":{"type":"array","items":{"type":"object","properties":{"chain":{"type":"string","description":"Chain of the wallet. Only Solana today.","enum":["solana"]},"address":{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]{32,44}$","description":"Base58 Solana address (ed25519 public key).","examples":["7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy"]},"linkedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the wallet was linked to the account (ISO 8601, UTC)."}},"required":["chain","address","linkedAt"],"additionalProperties":false,"description":"A wallet linked to the account."},"description":"Linked wallets, oldest first."}},"required":["id","createdAt","wallets"],"additionalProperties":false,"description":"The signed-in user."}},"required":["session","me"],"additionalProperties":false,"description":"Signed in. The `wl_session` cookie is set on this response."}}}},"400":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"401":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"403":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"429":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"501":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"503":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}}}}},"/v1/auth/session":{"get":{"summary":"Get the current session","tags":["Auth"],"description":"Anonymous callers get `200` with `authenticated: false`, so apps can branch without error handling. An authenticated call renews the sliding expiry and the cookie.","security":[{},{"session":[]}],"responses":{"200":{"description":"Session state. Anonymous is a normal 200, not an error.","content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"authenticated":{"type":"boolean","enum":[true]},"userId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Id of the signed-in user."},"address":{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]{32,44}$","description":"Wallet the session was started with.","examples":["7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy"]},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Sliding expiry; every authenticated call pushes it forward."}},"required":["authenticated","userId","address","expiresAt"],"additionalProperties":false,"description":"Signed in."},{"type":"object","properties":{"authenticated":{"type":"boolean","enum":[false]}},"required":["authenticated"],"additionalProperties":false,"description":"Anonymous: no cookie, or the session ended."}],"description":"Session state. Anonymous is a normal 200, not an error."}}}},"503":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}}}}},"/v1/auth/logout":{"post":{"summary":"Sign out","tags":["Auth"],"description":"Ends the current session and clears the cookie. Idempotent: calling it without a session is also `204`. Browsers must send an allow-listed `Origin`.","security":[{},{"session":[]}],"responses":{"204":{"description":"Session ended; cookie cleared"},"403":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"503":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}}}}},"/v1/me":{"get":{"summary":"Get the signed-in user","tags":["Account"],"description":"The account behind the session cookie and its linked wallets. `401 unauthenticated` without a session.","security":[{"session":[]}],"responses":{"200":{"description":"The signed-in user.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Stable user id.","examples":["0b8f3c0e-6a51-4d47-9a8e-2f4c1d7b9e10"]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Account creation time (ISO 8601, UTC)."},"wallets":{"type":"array","items":{"type":"object","properties":{"chain":{"type":"string","description":"Chain of the wallet. Only Solana today.","enum":["solana"]},"address":{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]{32,44}$","description":"Base58 Solana address (ed25519 public key).","examples":["7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy"]},"linkedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the wallet was linked to the account (ISO 8601, UTC)."}},"required":["chain","address","linkedAt"],"additionalProperties":false,"description":"A wallet linked to the account."},"description":"Linked wallets, oldest first."}},"required":["id","createdAt","wallets"],"additionalProperties":false,"description":"The signed-in user."}}}},"401":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"503":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}}}}},"/v1/x/recent":{"get":{"summary":"Recent X posts","tags":["X feed"],"description":"Newest posts of tracked KOL and founder accounts on X, newest first. The same data the stream starts with; use it for a first paint or without EventSource. Answers `503 x_feed_unavailable` (with `Retry-After`) when the feed relay is down.","parameters":[{"schema":{"default":50,"type":"integer","minimum":1,"maximum":100},"in":"query","name":"limit","required":false,"description":"How many posts to return, newest first (1-100, default 50)."}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"posts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^\\d{1,20}$"},"kind":{"type":"string","enum":["tweet","reply","quote","repost"]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"receivedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"url":{"type":"string","format":"uri"},"author":{"type":"object","properties":{"id":{"type":["string","null"]},"handle":{"type":"string"},"name":{"type":"string"},"avatarUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"followers":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"tags":{"type":"array","items":{"type":"string","enum":["kol","founder","featured","media"]}},"verified":{"type":"string","enum":["none","blue","business","government"]},"affiliate":{"anyOf":[{"type":"object","properties":{"name":{"type":"string"},"handle":{"type":["string","null"]},"badgeUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]}},"required":["name","handle","badgeUrl"],"additionalProperties":false},{"type":"null"}]},"automated":{"type":"boolean"},"parody":{"type":"boolean"}},"required":["id","handle","name","avatarUrl","followers","tags"],"additionalProperties":false},"text":{"type":"string"},"media":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["image","video","gif"]},"url":{"type":"string","format":"uri"},"posterUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"width":{"anyOf":[{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},{"type":"null"}]},"height":{"anyOf":[{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},{"type":"null"}]},"altText":{"type":["string","null"]},"durationMs":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"variants":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"contentType":{"type":"string"},"bitrate":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]}},"required":["url","contentType","bitrate"],"additionalProperties":false}}},"required":["type","url"],"additionalProperties":false}},"quoted":{"anyOf":[{"type":"object","properties":{"id":{"type":["string","null"]},"author":{"type":"object","properties":{"handle":{"type":"string"},"name":{"type":"string"},"avatarUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"verified":{"type":"string","enum":["none","blue","business","government"]}},"required":["handle","name","avatarUrl"],"additionalProperties":false},"text":{"type":"string"},"media":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["image","video","gif"]},"url":{"type":"string","format":"uri"},"posterUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"width":{"anyOf":[{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},{"type":"null"}]},"height":{"anyOf":[{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},{"type":"null"}]},"altText":{"type":["string","null"]},"durationMs":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"variants":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"contentType":{"type":"string"},"bitrate":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]}},"required":["url","contentType","bitrate"],"additionalProperties":false}}},"required":["type","url"],"additionalProperties":false}},"createdAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]},"urls":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"expandedUrl":{"type":"string","format":"uri"},"displayUrl":{"type":"string"}},"required":["url","expandedUrl","displayUrl"],"additionalProperties":false}},"card":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["summary","summary_large_image","player","app","unknown"]},"url":{"type":"string","format":"uri"},"domain":{"type":"string"},"title":{"type":"string"},"description":{"type":["string","null"]},"imageUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]}},"required":["kind","url","domain","title","description","imageUrl"],"additionalProperties":false},{"type":"null"}]},"poll":{"anyOf":[{"type":"object","properties":{"options":{"minItems":2,"maxItems":4,"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"votes":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["label","votes"],"additionalProperties":false}},"totalVotes":{"type":"integer","minimum":0,"maximum":9007199254740991},"endsAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]},"closed":{"type":"boolean"}},"required":["options","totalVotes","endsAt","closed"],"additionalProperties":false},{"type":"null"}]},"article":{"anyOf":[{"type":"object","properties":{"title":{"type":"string"},"previewText":{"type":["string","null"]},"coverUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"url":{"type":"string","format":"uri"}},"required":["title","previewText","coverUrl","url"],"additionalProperties":false},{"type":"null"}]}},"required":["id","author","text","media"],"additionalProperties":false},{"type":"null"}]},"inReplyTo":{"anyOf":[{"type":"object","properties":{"id":{"type":["string","null"]},"handle":{"type":"string"}},"required":["id","handle"],"additionalProperties":false},{"type":"null"}]},"source":{"type":"string","enum":["gmgn","twitterapi"]},"signals":{"maxItems":16,"type":"array","items":{"type":"string","maxLength":32}},"metrics":{"anyOf":[{"type":"object","properties":{"replies":{"type":"integer","minimum":0,"maximum":9007199254740991},"reposts":{"type":"integer","minimum":0,"maximum":9007199254740991},"quotes":{"type":"integer","minimum":0,"maximum":9007199254740991},"likes":{"type":"integer","minimum":0,"maximum":9007199254740991},"bookmarks":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"views":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]}},"required":["replies","reposts","quotes","likes","bookmarks","views"],"additionalProperties":false},{"type":"null"}]},"card":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["summary","summary_large_image","player","app","unknown"]},"url":{"type":"string","format":"uri"},"domain":{"type":"string"},"title":{"type":"string"},"description":{"type":["string","null"]},"imageUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]}},"required":["kind","url","domain","title","description","imageUrl"],"additionalProperties":false},{"type":"null"}]},"poll":{"anyOf":[{"type":"object","properties":{"options":{"minItems":2,"maxItems":4,"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"votes":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["label","votes"],"additionalProperties":false}},"totalVotes":{"type":"integer","minimum":0,"maximum":9007199254740991},"endsAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]},"closed":{"type":"boolean"}},"required":["options","totalVotes","endsAt","closed"],"additionalProperties":false},{"type":"null"}]},"article":{"anyOf":[{"type":"object","properties":{"title":{"type":"string"},"previewText":{"type":["string","null"]},"coverUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"url":{"type":"string","format":"uri"}},"required":["title","previewText","coverUrl","url"],"additionalProperties":false},{"type":"null"}]},"communityNote":{"anyOf":[{"type":"object","properties":{"text":{"type":"string"},"url":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]}},"required":["text","url"],"additionalProperties":false},{"type":"null"}]},"urls":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"expandedUrl":{"type":"string","format":"uri"},"displayUrl":{"type":"string"}},"required":["url","expandedUrl","displayUrl"],"additionalProperties":false}},"lang":{"type":["string","null"]},"possiblySensitive":{"type":"boolean"},"edited":{"type":"boolean"},"conversationId":{"type":["string","null"]},"thread":{"type":"boolean"},"enrichedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]}},"required":["id","kind","createdAt","receivedAt","url","author","text","media","quoted","inReplyTo","source"],"additionalProperties":false}}},"required":["posts"],"additionalProperties":false}}}},"400":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"429":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"503":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}}}}},"/v1/x/post/{id}":{"get":{"summary":"One X post by id","tags":["X feed"],"description":"Without `enrich`: a post of a tracked KOL or founder account that the feed saw recently (the relay keeps the last ~5000, including posts the feed itself does not show), e.g. to resolve a pasted tweet link. `404 x_post_not_found` when the feed has not seen the id (another account, too old, or deleted); `503 x_feed_unavailable` (with `Retry-After`) when the feed relay is down.\n\nWith `enrich=1`: the full post from X for any public post, for links a user pastes or opens (never for the whole live feed): verified type and affiliate badge, media sizes, alt text and playable video variants, metrics, link card, poll, X article, url entities, language, conversation and thread flags; `source` is `twitterapi` and `enrichedAt` says when X was asked. A post the feed also has keeps its `author.tags`, `signals` and `receivedAt`. Cached: refetched at most every 5 minutes (metrics), kept 24 h. Errors: `404 x_post_not_found` (deleted, protected or no such post), `429 rate_limited` (per client IP, cache hits are free), `503 x_enrich_unavailable` with `Retry-After` (enrichment off, X source down or the daily budget spent) — fall back to the plain lookup.","parameters":[{"schema":{"type":"string","enum":["0","1","true","false"]},"in":"query","name":"enrich","required":false,"description":"`1`: fetch the full post from X (any public post, with metrics, video variants, card, poll, article)."},{"schema":{"type":"string","pattern":"^\\d{1,20}$"},"in":"path","name":"id","required":true,"description":"Tweet id: 1-20 digits, as in `https://x.com/<handle>/status/<id>`."}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","pattern":"^\\d{1,20}$"},"kind":{"type":"string","enum":["tweet","reply","quote","repost"]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"receivedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"url":{"type":"string","format":"uri"},"author":{"type":"object","properties":{"id":{"type":["string","null"]},"handle":{"type":"string"},"name":{"type":"string"},"avatarUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"followers":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"tags":{"type":"array","items":{"type":"string","enum":["kol","founder","featured","media"]}},"verified":{"type":"string","enum":["none","blue","business","government"]},"affiliate":{"anyOf":[{"type":"object","properties":{"name":{"type":"string"},"handle":{"type":["string","null"]},"badgeUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]}},"required":["name","handle","badgeUrl"],"additionalProperties":false},{"type":"null"}]},"automated":{"type":"boolean"},"parody":{"type":"boolean"}},"required":["id","handle","name","avatarUrl","followers","tags"],"additionalProperties":false},"text":{"type":"string"},"media":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["image","video","gif"]},"url":{"type":"string","format":"uri"},"posterUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"width":{"anyOf":[{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},{"type":"null"}]},"height":{"anyOf":[{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},{"type":"null"}]},"altText":{"type":["string","null"]},"durationMs":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"variants":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"contentType":{"type":"string"},"bitrate":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]}},"required":["url","contentType","bitrate"],"additionalProperties":false}}},"required":["type","url"],"additionalProperties":false}},"quoted":{"anyOf":[{"type":"object","properties":{"id":{"type":["string","null"]},"author":{"type":"object","properties":{"handle":{"type":"string"},"name":{"type":"string"},"avatarUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"verified":{"type":"string","enum":["none","blue","business","government"]}},"required":["handle","name","avatarUrl"],"additionalProperties":false},"text":{"type":"string"},"media":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["image","video","gif"]},"url":{"type":"string","format":"uri"},"posterUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"width":{"anyOf":[{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},{"type":"null"}]},"height":{"anyOf":[{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},{"type":"null"}]},"altText":{"type":["string","null"]},"durationMs":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"variants":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"contentType":{"type":"string"},"bitrate":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]}},"required":["url","contentType","bitrate"],"additionalProperties":false}}},"required":["type","url"],"additionalProperties":false}},"createdAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]},"urls":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"expandedUrl":{"type":"string","format":"uri"},"displayUrl":{"type":"string"}},"required":["url","expandedUrl","displayUrl"],"additionalProperties":false}},"card":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["summary","summary_large_image","player","app","unknown"]},"url":{"type":"string","format":"uri"},"domain":{"type":"string"},"title":{"type":"string"},"description":{"type":["string","null"]},"imageUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]}},"required":["kind","url","domain","title","description","imageUrl"],"additionalProperties":false},{"type":"null"}]},"poll":{"anyOf":[{"type":"object","properties":{"options":{"minItems":2,"maxItems":4,"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"votes":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["label","votes"],"additionalProperties":false}},"totalVotes":{"type":"integer","minimum":0,"maximum":9007199254740991},"endsAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]},"closed":{"type":"boolean"}},"required":["options","totalVotes","endsAt","closed"],"additionalProperties":false},{"type":"null"}]},"article":{"anyOf":[{"type":"object","properties":{"title":{"type":"string"},"previewText":{"type":["string","null"]},"coverUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"url":{"type":"string","format":"uri"}},"required":["title","previewText","coverUrl","url"],"additionalProperties":false},{"type":"null"}]}},"required":["id","author","text","media"],"additionalProperties":false},{"type":"null"}]},"inReplyTo":{"anyOf":[{"type":"object","properties":{"id":{"type":["string","null"]},"handle":{"type":"string"}},"required":["id","handle"],"additionalProperties":false},{"type":"null"}]},"source":{"type":"string","enum":["gmgn","twitterapi"]},"signals":{"maxItems":16,"type":"array","items":{"type":"string","maxLength":32}},"metrics":{"anyOf":[{"type":"object","properties":{"replies":{"type":"integer","minimum":0,"maximum":9007199254740991},"reposts":{"type":"integer","minimum":0,"maximum":9007199254740991},"quotes":{"type":"integer","minimum":0,"maximum":9007199254740991},"likes":{"type":"integer","minimum":0,"maximum":9007199254740991},"bookmarks":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"views":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]}},"required":["replies","reposts","quotes","likes","bookmarks","views"],"additionalProperties":false},{"type":"null"}]},"card":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["summary","summary_large_image","player","app","unknown"]},"url":{"type":"string","format":"uri"},"domain":{"type":"string"},"title":{"type":"string"},"description":{"type":["string","null"]},"imageUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]}},"required":["kind","url","domain","title","description","imageUrl"],"additionalProperties":false},{"type":"null"}]},"poll":{"anyOf":[{"type":"object","properties":{"options":{"minItems":2,"maxItems":4,"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"votes":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["label","votes"],"additionalProperties":false}},"totalVotes":{"type":"integer","minimum":0,"maximum":9007199254740991},"endsAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]},"closed":{"type":"boolean"}},"required":["options","totalVotes","endsAt","closed"],"additionalProperties":false},{"type":"null"}]},"article":{"anyOf":[{"type":"object","properties":{"title":{"type":"string"},"previewText":{"type":["string","null"]},"coverUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"url":{"type":"string","format":"uri"}},"required":["title","previewText","coverUrl","url"],"additionalProperties":false},{"type":"null"}]},"communityNote":{"anyOf":[{"type":"object","properties":{"text":{"type":"string"},"url":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]}},"required":["text","url"],"additionalProperties":false},{"type":"null"}]},"urls":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"expandedUrl":{"type":"string","format":"uri"},"displayUrl":{"type":"string"}},"required":["url","expandedUrl","displayUrl"],"additionalProperties":false}},"lang":{"type":["string","null"]},"possiblySensitive":{"type":"boolean"},"edited":{"type":"boolean"},"conversationId":{"type":["string","null"]},"thread":{"type":"boolean"},"enrichedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]}},"required":["id","kind","createdAt","receivedAt","url","author","text","media","quoted","inReplyTo","source"],"additionalProperties":false}}}},"400":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"404":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"429":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"503":{"description":"Error envelope used by every non-2xx response.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}}}}},"/v1/x/stream":{"get":{"summary":"Live X posts (SSE)","tags":["X feed"],"description":"Server-Sent Events (`text/event-stream`). Use `new EventSource(url)`; no credentials are needed.\n\n- `snapshot` once on connect: `{ \"posts\": XPost[] }`, newest first (up to 50);\n- `post`: one `XPost`, new or enriched — replace any post with the same `id`;\n- `delete`: `{ \"id\" }` — remove that post;\n- `: ping` comment every 15 s.\n\nWhen the feed is unavailable the stream answers `200` with only a `retry:` hint and closes, so EventSource reconnects by itself after that delay and gets a fresh `snapshot`. Concurrent streams are limited per IP (`429 rate_limited`).","responses":{"200":{"description":"An endless `text/event-stream`.","content":{"text/event-stream":{"schema":{"type":"string","description":"An endless `text/event-stream`."}}}},"429":{"description":"Error envelope used by every non-2xx response.","content":{"text/event-stream":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}},"503":{"description":"Error envelope used by every non-2xx response.","content":{"text/event-stream":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. Branch on this, never on `message`.","examples":["unauthenticated"]},"message":{"type":"string","description":"Human-readable explanation; may change.","examples":["Sign in first"]},"requestId":{"description":"Echo of the `X-Request-Id` response header, for support and log lookup.","examples":["5b0e8f7a-3f61-4d2b-9a7c-1c2d3e4f5a6b"],"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Error envelope used by every non-2xx response."}}}}}}}},"servers":[{"url":"https://api.windle.fun"}],"tags":[{"name":"System","description":"Service index, liveness and readiness."},{"name":"Auth","description":"Sign-In With Solana and cookie sessions."},{"name":"Account","description":"The signed-in user."},{"name":"X feed","description":"Live posts of tracked KOL and founder accounts on X (JSON + SSE)."}],"externalDocs":{"description":"Guides","url":"https://docs.windle.fun/api/overview/"}}