{"openapi":"3.1.0","info":{"title":"ApeCover API","version":"0.1.0","description":"Read-only view of indexed protocol state. Answers are derived from the event log and carry `asOfSlot`, so a consumer can see how stale they are. Not authoritative for decisions that move money — the chain is."},"servers":[{"url":"http://127.0.0.1:8080","description":"Local"}],"paths":{"/health":{"get":{"summary":"Liveness and projection freshness","description":"Always 200 while the process is up. The body says how far the projection has got, which is the question that actually matters.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok","degraded"]},"asOfSlot":{"type":"string","pattern":"^\\d+$","description":"Highest slot folded into this answer"},"asOfTs":{"type":"integer","description":"Server time when the answer was produced, in unix seconds"},"eventsApplied":{"type":"integer","minimum":0},"orphanedEvents":{"type":"integer","minimum":0}},"required":["status","asOfSlot","asOfTs","eventsApplied","orphanedEvents"],"additionalProperties":false}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The requested resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/pool/{address}":{"get":{"summary":"Pool state as of the latest indexed slot","parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"asOfSlot":{"type":"string","pattern":"^\\d+$","description":"Highest slot folded into this answer"},"asOfTs":{"type":"integer","description":"Server time when the answer was produced, in unix seconds"},"address":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"},"admin":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"},"vault":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"},"paused":{"type":"boolean"},"totalPremiums":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"totalLiabilities":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"totalPaid":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"totalContributed":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"totalWithdrawn":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"policiesIssued":{"type":"integer","minimum":0},"tradesRegistered":{"type":"integer","minimum":0},"claimsPaid":{"type":"integer","minimum":0},"claimsRejected":{"type":"integer","minimum":0},"liveExposure":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"expiryBacklog":{"type":["string","null"],"pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"}},"required":["asOfSlot","asOfTs","address","admin","vault","paused","totalPremiums","totalLiabilities","totalPaid","totalContributed","totalWithdrawn","policiesIssued","tradesRegistered","claimsPaid","claimsRejected","liveExposure","expiryBacklog"],"additionalProperties":false}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The requested resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/trades":{"get":{"summary":"Insured trades, filterable and paginated","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"description":"Default 50, max 200"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0}},{"name":"owner","in":"query","required":false,"schema":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"Filter to one trader"}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["registered","claimed","paid","rejected","expired"],"description":"Filter by lifecycle status"}},{"name":"tokenMint","in":"query","required":false,"schema":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"asOfSlot":{"type":"string","pattern":"^\\d+$","description":"Highest slot folded into this answer"},"asOfTs":{"type":"integer","description":"Server time when the answer was produced, in unix seconds"},"trades":{"type":"array","items":{"type":"object","properties":{"address":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"},"pool":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"},"policy":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"},"owner":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"},"tokenMint":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"},"tier":{"type":"string"},"tradeSize":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"reservedLiability":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"windowStart":{"type":"integer"},"windowEnd":{"type":"integer"},"status":{"type":"string","enum":["registered","claimed","paid","rejected","expired"]},"registeredSlot":{"type":"string","pattern":"^\\d+$"},"claim":{"type":["string","null"],"minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"},"payout":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"rejectionReason":{"type":["string","null"]}},"required":["address","pool","policy","owner","tokenMint","tier","tradeSize","reservedLiability","windowStart","windowEnd","status","registeredSlot","claim","payout","rejectionReason"],"additionalProperties":false}},"total":{"type":"integer","minimum":0}},"required":["asOfSlot","asOfTs","trades","total"],"additionalProperties":false}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The requested resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/trades/{address}":{"get":{"summary":"One insured trade","parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"asOfSlot":{"type":"string","pattern":"^\\d+$","description":"Highest slot folded into this answer"},"asOfTs":{"type":"integer","description":"Server time when the answer was produced, in unix seconds"},"trade":{"type":"object","properties":{"address":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"},"pool":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"},"policy":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"},"owner":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"},"tokenMint":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"},"tier":{"type":"string"},"tradeSize":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"reservedLiability":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"windowStart":{"type":"integer"},"windowEnd":{"type":"integer"},"status":{"type":"string","enum":["registered","claimed","paid","rejected","expired"]},"registeredSlot":{"type":"string","pattern":"^\\d+$"},"claim":{"type":["string","null"],"minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"},"payout":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"rejectionReason":{"type":["string","null"]}},"required":["address","pool","policy","owner","tokenMint","tier","tradeSize","reservedLiability","windowStart","windowEnd","status","registeredSlot","claim","payout","rejectionReason"],"additionalProperties":false}},"required":["asOfSlot","asOfTs","trade"],"additionalProperties":false}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The requested resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/policies":{"get":{"summary":"Issued policies","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"description":"Default 50, max 200"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0}},{"name":"owner","in":"query","required":false,"schema":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"asOfSlot":{"type":"string","pattern":"^\\d+$","description":"Highest slot folded into this answer"},"asOfTs":{"type":"integer","description":"Server time when the answer was produced, in unix seconds"},"policies":{"type":"array","items":{"type":"object","properties":{"address":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"},"pool":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"},"owner":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"},"tradesRegistered":{"type":"integer","minimum":0}},"required":["address","pool","owner","tradesRegistered"],"additionalProperties":false}},"total":{"type":"integer","minimum":0}},"required":["asOfSlot","asOfTs","policies","total"],"additionalProperties":false}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The requested resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/claims":{"get":{"summary":"Claims and their outcomes","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"description":"Default 50, max 200"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["claimed","paid","rejected"]}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"asOfSlot":{"type":"string","pattern":"^\\d+$","description":"Highest slot folded into this answer"},"asOfTs":{"type":"integer","description":"Server time when the answer was produced, in unix seconds"},"claims":{"type":"array","items":{"type":"object","properties":{"trade":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"},"claim":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"},"status":{"type":"string","enum":["claimed","paid","rejected"]},"payout":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"rejectionReason":{"type":["string","null"]}},"required":["trade","claim","status","payout","rejectionReason"],"additionalProperties":false}},"total":{"type":"integer","minimum":0}},"required":["asOfSlot","asOfTs","claims","total"],"additionalProperties":false}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The requested resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/admin/state":{"get":{"summary":"Operational detail: backlog, drift, and pause state","description":"Admin-only. Carries the expiry backlog breakdown from M2-10, which is the signal that the pool is losing capacity to un-cranked trades.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"asOfSlot":{"type":"string","pattern":"^\\d+$","description":"Highest slot folded into this answer"},"asOfTs":{"type":"integer","description":"Server time when the answer was produced, in unix seconds"},"pools":{"type":"array","items":{"type":"object","properties":{"address":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"A base58 Solana address"},"paused":{"type":"boolean"},"totalLiabilities":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"liveExposure":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"expiryBacklog":{"type":["string","null"],"pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"expiryBacklogCount":{"type":["integer","null"],"minimum":0},"oldestBacklogAgeSeconds":{"type":["integer","null"],"minimum":0}},"required":["address","paused","totalLiabilities","liveExposure","expiryBacklog","expiryBacklogCount","oldestBacklogAgeSeconds"],"additionalProperties":false}},"eventsApplied":{"type":"integer","minimum":0},"orphanedEvents":{"type":"integer","minimum":0}},"required":["asOfSlot","asOfTs","pools","eventsApplied","orphanedEvents"],"additionalProperties":false}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid admin bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The requested resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"adminToken":[]}]}},"/quote":{"post":{"summary":"Price a policy and pre-check whether the program would accept it","description":"Reads pool parameters from chain rather than from the indexed projection, because a quote is a number the caller is about to act on. Amounts are decimal strings: a u64 served as a JSON number loses precision past 2^53.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"pool":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$","description":"The pool to quote against"},"tokenMint":{"type":"string","minLength":32,"maxLength":44,"pattern":"^[1-9A-HJ-NP-Za-km-z]+$"},"tradeSize":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"tier":{"type":"integer","minimum":0,"maximum":2,"description":"0 Basic, 1 Standard, 2 DegenMax"},"packSize":{"type":"integer","description":"Trades in the pack. Must be one of 1, 10, 20, 50, 100"},"marketCapMicroUsd":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"}},"required":["pool","tokenMint","tradeSize","tier","packSize"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"eligible":{"type":"boolean","description":"Whether the program would accept this policy right now"},"issues":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","enum":["pool-paused","trade-too-small","trade-too-large","market-cap-too-high","exceeds-policy-covered-size","insufficient-pool-capacity","invalid-pack-size","unknown-pool"]},"detail":{"type":"string"}},"required":["code","detail"],"additionalProperties":false},"description":"Empty when eligible"},"quote":{"type":["object","null"],"properties":{"premium":{"type":"string","pattern":"^\\d+$","description":"Total the buyer pays"},"protocolFee":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"partnerFee":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"underwriterFee":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"toReserve":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"perTradeCap":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"payoutPerTrade":{"type":"string","pattern":"^\\d+$","description":"Paid if a covered trade rugs"},"liabilityPerTrade":{"type":"string","pattern":"^\\d+$","description":"Reserved against the pool per registered trade"}},"required":["premium","protocolFee","partnerFee","underwriterFee","toReserve","perTradeCap","payoutPerTrade","liabilityPerTrade"],"additionalProperties":false},"availableCapacity":{"type":["string","null"],"pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"marketCap":{"type":["object","null"],"properties":{"microUsd":{"type":"string","pattern":"^\\d+$","description":"An amount in lamports, as a decimal string — u64 does not survive JSON numbers"},"source":{"type":"string","description":"`caller` when supplied in the request, otherwise the provider that answered"}},"required":["microUsd","source"],"additionalProperties":false},"asOfTs":{"type":"integer"}},"required":["eligible","issues","quote","availableCapacity","marketCap","asOfTs"],"additionalProperties":false}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The requested resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/whoami":{"get":{"summary":"Check an API key and see what it is attached to","description":"The first call to make with a new key. Send it as `Authorization: Bearer <keyId>.<secret>`, or in `X-API-Key`. Answers 401 for a key that is not valid and 403 for one belonging to a suspended or rejected partner — the distinction matters, because a new key fixes the first and not the second.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"partner":{"type":"object","properties":{"id":{"type":"string","description":"Your partner id. Stable, and safe to log"},"label":{"type":"string","description":"The integration name you registered"},"status":{"type":"string","enum":["pending","approved","rejected","suspended"],"description":"pending, approved, rejected or suspended"},"onchainPartner":{"type":["string","null"],"description":"Your on-chain Partner account, or null if an operator has not registered one yet"},"earning":{"type":"boolean","description":"Whether revenue share is accruing. Approved alone is not enough — the on-chain account has to exist, because attribution is the policy.partner field"}},"required":["id","label","status","onchainPartner","earning"],"additionalProperties":false},"keyId":{"type":"string","description":"The key that authenticated this request"},"rateLimit":{"type":"object","properties":{"remaining":{"type":"integer","description":"Requests left in the current window"},"resetsAt":{"type":"integer","description":"Unix seconds when the window rolls"}},"required":["remaining","resetsAt"],"additionalProperties":false}},"required":["partner","keyId","rateLimit"],"additionalProperties":false}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The requested resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"adminToken":{"type":"http","scheme":"bearer"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string"},"detail":{"type":"string"}},"required":["error"],"additionalProperties":false}}}}