{"openapi":"3.1.0","info":{"title":"OwlViz API","description":"Agent-ready Solana asset and collection intelligence API. OwlViz normalizes metadata, health, media reliability, multi-provider collection floors (Magic Eden + Tensor), reference floors, durable market change events, Market Watch sampling, and HMAC-signed webhooks — infrastructure for autonomous agents and LLM tools, not trade execution or strategy hosting. Base URL: https://api.owlviz.dev. Portal API keys (ov_live_…) enforce plan-based RPM (60s window): Free 120/60, Builder 600/300, Pro 2000/1000 global/expensive RPM, plus self-serve Market Watch and webhook quotas. Anonymous reads use Free IP limits. Self-serve change monitors (API key or portal) enforce plan quotas and 3600s min interval; manual check remains admin-only. Human docs: https://owlviz.dev/docs/agents. OpenAPI: /openapi.json. Solana Pay / USDC checkout (C3 parked) and Stripe are not available.","version":"1.0.0"},"servers":[{"url":"https://api.owlviz.dev","description":"Production (OwlViz)"}],"paths":{"/health":{"get":{"summary":"Service health","operationId":"getHealth","responses":{"200":{"description":"Service is up","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok"]},"service":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"environment":{"type":"string"},"dependencies":{"type":"object"}}}}}}},"tags":["System"],"description":"Liveness probe for agents and uptime checks."}},"/v1/assets/{mint}":{"get":{"summary":"Resolve normalized asset","operationId":"getAsset","parameters":[{"name":"mint","in":"path","required":true,"schema":{"type":"string"}},{"name":"refresh","in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Normalized asset","headers":{"X-Cache":{"schema":{"type":"string"}},"X-RateLimit-Limit":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/NormalizedAsset"}}},"example":{"data":{"id":"C5gHBKXwA8jduXNk3HyAVLnLBN6PEM8fTqkNNh5uyyjJ","assetType":"nft","name":"Example NFT","health":{"score":92,"status":"healthy","issues":[]}}}}}},"400":{"$ref":"#/components/responses/ApiError"},"404":{"$ref":"#/components/responses/ApiError"},"429":{"$ref":"#/components/responses/RateLimited"}},"tags":["Assets"],"description":"Resolve a Solana mint to a normalized asset. Optional Bearer ov_live_ key for higher rate limits."}},"/v1/assets/{mint}/health":{"get":{"summary":"Asset metadata health","operationId":"getAssetHealth","parameters":[{"$ref":"#/components/parameters/mint"}],"responses":{"200":{"description":"Health summary","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"assetId":{"type":"string"},"health":{"$ref":"#/components/schemas/MetadataHealth"}}}}}}}},"400":{"$ref":"#/components/responses/ApiError"},"429":{"$ref":"#/components/responses/RateLimited"}},"tags":["Assets"]}},"/v1/assets/{mint}/inspection":{"get":{"summary":"On-chain inspection","operationId":"getAssetInspection","parameters":[{"$ref":"#/components/parameters/mint"}],"responses":{"200":{"description":"Inspection payload"},"400":{"$ref":"#/components/responses/ApiError"},"429":{"$ref":"#/components/responses/RateLimited"}},"tags":["Assets"]}},"/v1/assets/{mint}/media":{"get":{"summary":"Media reliability","operationId":"getAssetMedia","parameters":[{"$ref":"#/components/parameters/mint"},{"name":"force","in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Media reliability state"},"429":{"$ref":"#/components/responses/RateLimited"}},"tags":["Assets"]}},"/v1/assets/{mint}/snapshots":{"get":{"summary":"Snapshot history","operationId":"listAssetSnapshots","parameters":[{"$ref":"#/components/parameters/mint"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"Snapshot list"},"503":{"$ref":"#/components/responses/ApiError"}},"tags":["Assets"]}},"/v1/collections/{address}":{"get":{"summary":"Collection summary","description":"Public read. When the collection is not registered yet, requests with a valid developer API key or monitoring admin token automatically queue a one-shot background index (see X-Collection-Auto-Index). Anonymous clients receive COLLECTION_NOT_FOUND without indexing.","operationId":"getCollection","parameters":[{"$ref":"#/components/parameters/address"}],"responses":{"200":{"description":"Collection entity"},"404":{"$ref":"#/components/responses/ApiError"},"429":{"$ref":"#/components/responses/RateLimited"}},"tags":["Collections"]}},"/v1/collections/{address}/health":{"get":{"summary":"Collection health aggregate","operationId":"getCollectionHealth","parameters":[{"$ref":"#/components/parameters/address"}],"responses":{"200":{"description":"Collection health"},"404":{"$ref":"#/components/responses/ApiError"}},"tags":["Collections"]}},"/v1/collections/{address}/holders":{"get":{"summary":"Collection holder distribution","operationId":"getCollectionHolders","description":"Ownership distribution facts for indexed assets (unique holders, concentration bands, optional listing overlap from cached market snapshots). Does not crawl ownership on anonymous reads; recomputes run in the background worker after indexing or when refresh=true with a developer API key / monitoring admin token (daily quota applies).","parameters":[{"$ref":"#/components/parameters/address"},{"name":"refresh","in":"query","schema":{"type":"boolean","default":false},"description":"Queue a one-shot holder recompute (developer API key or monitoring admin required)."}],"responses":{"200":{"description":"Holder distribution summary","headers":{"X-Cache":{"schema":{"type":"string","enum":["HIT","MISS","STALE"]}},"X-Holder-Recompute":{"schema":{"type":"string","enum":["queued"]},"description":"Present when a background recompute job was queued on this request."}}},"404":{"$ref":"#/components/responses/ApiError"},"409":{"$ref":"#/components/responses/ApiError"},"429":{"$ref":"#/components/responses/RateLimited"}},"tags":["Collections"]}},"/v1/collections/{address}/market":{"get":{"summary":"Collection marketplace floor snapshot","operationId":"getCollectionMarket","description":"Returns concurrent Magic Eden + Tensor floor observations for a canonical Solana collection address, including aggregate.bestFloor with provenance. Authenticated developer API keys may auto-register unknown collections on first read (one-shot index). Anonymous unknown collections return COLLECTION_NOT_FOUND. Tensor collection identity resolves via verified on-chain mint (GET /api/v1/collections?vocs=…) first, then sample-mint fallback — never fuzzy name search.","parameters":[{"$ref":"#/components/parameters/address"},{"name":"scope","in":"query","schema":{"type":"string","enum":["provider_only","provider","magic_eden","tensor","aggregated","all_markets"],"default":"provider_only"},"description":"Provider listing mode. Top-level fields remain Magic Eden for Sprint 1 compatibility; read aggregate.bestFloor for multi-provider best observed floor."}],"responses":{"200":{"description":"Market snapshot with explicit per-provider status: success (SOL floor available), no_listings (mapped but no SOL listings), unmapped (Tensor/ME could not map this collection address), unavailable (upstream error; stale cache may apply)","headers":{"X-Cache":{"schema":{"type":"string","enum":["HIT","MISS","STALE"]}},"X-Cache-TTL":{"schema":{"type":"string"}},"X-Cache-Age":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CollectionMarketSnapshot"}}},"example":{"data":{"address":"COLLECTION_ADDRESS","status":"success","floor":{"sol":1.25,"lamports":"1250000000"},"aggregate":{"bestFloor":{"status":"success","floor":{"sol":1.25,"lamports":"1250000000"}}}}}}}},"400":{"$ref":"#/components/responses/ApiError"},"404":{"$ref":"#/components/responses/ApiError"},"429":{"$ref":"#/components/responses/RateLimited"}},"tags":["Automation"]}},"/v1/collections/{address}/market/events":{"get":{"summary":"Collection market change events","operationId":"listCollectionMarketEvents","description":"Paginated durable market change events for one collection (newest first).","parameters":[{"$ref":"#/components/parameters/address"},{"name":"eventType","in":"query","schema":{"type":"string","enum":["spot_floor_changed","reference_floor_changed","provider_floor_changed","provider_status_changed"]}},{"name":"severity","in":"query","schema":{"type":"string","enum":["info","notice","warning"]}},{"name":"since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated market events newest-first","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/MarketEvent"}},"pagination":{"type":"object","properties":{"nextCursor":{"type":["string","null"]}}}}}}}},"400":{"$ref":"#/components/responses/ApiError"},"404":{"$ref":"#/components/responses/ApiError"},"429":{"$ref":"#/components/responses/RateLimited"}},"tags":["Automation"]}},"/v1/collections/{address}/market/reference":{"get":{"summary":"Collection market reference floor","operationId":"getCollectionMarketReference","description":"Returns Spot Floor (aggregate.bestFloor) and Reference Floor (rolling median of recent bucketed provider observations). Reports movement vs reference and recent range without pricing recommendations. Opt-in Market Watch continuous sampling (worker-driven) increases provider API usage and accumulates observations without public GET traffic.","parameters":[{"$ref":"#/components/parameters/address"},{"name":"window","in":"query","schema":{"type":"string","enum":["5m","15m","1h"],"default":"15m"},"description":"Rolling observation window for reference computation."}],"responses":{"200":{"description":"Market reference with status ready, warming_up, stale, or unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CollectionMarketReference"}}}}}},"400":{"$ref":"#/components/responses/ApiError"},"404":{"$ref":"#/components/responses/ApiError"},"429":{"$ref":"#/components/responses/RateLimited"}},"tags":["Automation"]}},"/v1/collections/{address}/market/history":{"get":{"summary":"Collection market observation history","operationId":"getCollectionMarketHistory","description":"Time series of observation buckets derived from persisted market_observations (spot, reference-style, or per-provider floors). Not exchange candles or external marketplace archives.","parameters":[{"$ref":"#/components/parameters/address"},{"name":"window","in":"query","schema":{"type":"string","enum":["5m","15m","1h","6h","24h","7d"],"default":"15m"}},{"name":"interval","in":"query","schema":{"type":"string","enum":["1m","5m","15m","1h","4h","6h","24h"]}},{"name":"metric","in":"query","schema":{"type":"string","enum":["spot_floor","reference_floor","provider_floor"],"default":"spot_floor"}},{"name":"provider","in":"query","schema":{"type":"string","enum":["magic_eden","tensor"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":500}}],"responses":{"200":{"description":"Observation bucket time series","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CollectionMarketHistory"}}}}}},"400":{"$ref":"#/components/responses/ApiError"},"404":{"$ref":"#/components/responses/ApiError"},"429":{"$ref":"#/components/responses/RateLimited"}},"tags":["Automation"]}},"/v1/collections/{address}/market/state":{"get":{"summary":"Collection market state (combined intelligence view)","operationId":"getCollectionMarketState","description":"Normalized current market snapshot derived from OwlViz spot floor, rolling reference floor, observation history (1h/24h spot changes), and coverage. Not a trading signal — composes existing `/market`, `/market/reference`, and `market_observations` data without new marketplace providers.","parameters":[{"$ref":"#/components/parameters/address"},{"name":"window","in":"query","schema":{"type":"string","enum":["5m","15m","1h"],"default":"15m"},"description":"Rolling observation window for reference floor (same as `/market/reference`)."}],"responses":{"200":{"description":"Combined market state","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CollectionMarketState"}}}}}},"400":{"$ref":"#/components/responses/ApiError"},"404":{"$ref":"#/components/responses/ApiError"},"429":{"$ref":"#/components/responses/RateLimited"}},"tags":["Automation"]}},"/v1/collections/{address}/assets":{"get":{"summary":"Indexed collection assets","operationId":"listCollectionAssets","parameters":[{"$ref":"#/components/parameters/address"},{"name":"limit","in":"query","schema":{"type":"integer"}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated assets"},"404":{"$ref":"#/components/responses/ApiError"}},"tags":["Collections"]}},"/v1/collections/{address}/index":{"post":{"summary":"Queue collection indexing","operationId":"queueCollectionIndex","parameters":[{"$ref":"#/components/parameters/address"},{"name":"refresh","in":"query","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Active index job already running"},"202":{"description":"Index job queued"},"409":{"$ref":"#/components/responses/ApiError"}},"tags":["Collections"]},"get":{"summary":"Latest collection index job status","operationId":"getCollectionIndexStatus","parameters":[{"$ref":"#/components/parameters/address"}],"responses":{"200":{"description":"Index job status","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CollectionIndexJobStatus"}}}}}},"404":{"$ref":"#/components/responses/ApiError"}},"tags":["Collections"]}},"/v1/collection-index-jobs/{jobId}":{"get":{"summary":"Collection index job status by id","operationId":"getCollectionIndexJob","parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Index job status","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CollectionIndexJobStatus"}}}}}},"404":{"$ref":"#/components/responses/ApiError"}},"tags":["Collections"]}},"/v1/collections/{address}/market-watch":{"get":{"summary":"Market watch status for a collection","description":"Public read of the opt-in continuous sampling watch for a collection address, if one exists.","operationId":"getCollectionMarketWatch","parameters":[{"$ref":"#/components/parameters/address"}],"responses":{"200":{"description":"Market watch status","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/MarketWatch"}}}}}},"404":{"$ref":"#/components/responses/ApiError"}},"tags":["Automation"]}},"/v1/market-events":{"get":{"summary":"List market change events","operationId":"listMarketEvents","parameters":[{"name":"collectionAddress","in":"query","schema":{"type":"string"}},{"name":"watchId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"eventType","in":"query","schema":{"type":"string","enum":["spot_floor_changed","reference_floor_changed","provider_floor_changed","provider_status_changed"]}},{"name":"severity","in":"query","schema":{"type":"string","enum":["info","notice","warning"]}},{"name":"since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated market events","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/MarketEvent"}},"pagination":{"type":"object","properties":{"nextCursor":{"type":["string","null"]}}}}}}}},"503":{"$ref":"#/components/responses/ApiError"}},"tags":["Automation"],"description":"Global paginated feed of market change events; filter by collectionAddress, watchId, or eventType."}},"/v1/market-events/{id}":{"get":{"summary":"Get market change event","operationId":"getMarketEvent","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Market event","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/MarketEvent"}}}}}},"404":{"$ref":"#/components/responses/ApiError"}},"tags":["Automation"]}},"/v1/market-watches":{"get":{"summary":"List market watches","operationId":"listMarketWatches","responses":{"200":{"description":"Market watches","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/MarketWatch"}}}}}}}},"tags":["Automation"]},"post":{"summary":"Create market watch","description":"Requires a portal API key (`ov_live_…`) or ops admin token. Subject to plan active-watch quotas. Continuous sampling increases Magic Eden and Tensor API usage.","operationId":"createMarketWatch","security":[{"DeveloperApiKey":[]},{"MonitoringAdminBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["collectionAddress"],"properties":{"collectionAddress":{"type":"string"},"intervalSeconds":{"type":"integer","default":120},"jitterSeconds":{"type":"integer","default":15}}}}}},"responses":{"201":{"description":"Watch created"},"403":{"$ref":"#/components/responses/ApiError"},"409":{"$ref":"#/components/responses/ApiError"},"429":{"$ref":"#/components/responses/ApiError"}},"tags":["Automation"]}},"/v1/market-watches/{id}":{"get":{"summary":"Get market watch","operationId":"getMarketWatch","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Market watch"},"404":{"$ref":"#/components/responses/ApiError"}},"tags":["Automation"]},"patch":{"summary":"Update market watch","operationId":"updateMarketWatch","security":[{"DeveloperApiKey":[]},{"MonitoringAdminBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["active","paused","disabled"]},"intervalSeconds":{"type":"integer"},"jitterSeconds":{"type":"integer"},"refreshNow":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Updated watch"},"404":{"$ref":"#/components/responses/ApiError"}},"tags":["Automation"]},"delete":{"summary":"Disable market watch","operationId":"deleteMarketWatch","security":[{"DeveloperApiKey":[]},{"MonitoringAdminBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Watch disabled"},"404":{"$ref":"#/components/responses/ApiError"}},"tags":["Automation"]}},"/v1/monitors":{"get":{"summary":"List change monitors","operationId":"listMonitors","parameters":[{"name":"target","in":"query","schema":{"type":"string"},"description":"Filter by Solana mint or collection address"},{"name":"targetType","in":"query","schema":{"type":"string","enum":["asset","collection"]}},{"name":"status","in":"query","schema":{"type":"string","enum":["active","paused","disabled"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":100}}],"responses":{"200":{"description":"Change monitors owned by the caller (or ops ownerless list for admin token)","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ChangeMonitor"}}}}}}},"401":{"$ref":"#/components/responses/ApiError"},"429":{"$ref":"#/components/responses/RateLimited"}},"tags":["Monitoring"],"description":"List self-serve change monitors for your portal API key. Ops admin token lists ownerless operator monitors. Cross-tenant rows are never returned."}},"/v1/monitors/{id}":{"get":{"summary":"Get change monitor","operationId":"getMonitor","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Change monitor","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ChangeMonitor"}}}}}},"401":{"$ref":"#/components/responses/ApiError"},"404":{"$ref":"#/components/responses/ApiError"}},"tags":["Monitoring"],"description":"Fetch one monitor by id. Keyed callers receive 404 for monitors owned by another account."}},"/v1/webhooks":{"get":{"summary":"List webhook endpoints","operationId":"listWebhooks","responses":{"200":{"description":"Webhook endpoints (no secrets)","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}}}}}}}},"tags":["Automation"],"description":"List webhook endpoints (no secrets). Requires developer API key or monitoring admin token. Keyed callers see owned endpoints; admin sees ownerless ops endpoints only."},"post":{"summary":"Create webhook endpoint","description":"Subscribe to monitor and/or market change events (Builder+ plan quota). Portal API key or ops admin token. Signing secret returned once on create.","operationId":"createWebhook","security":[{"DeveloperApiKey":[]},{"MonitoringAdminBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointCreate"},"example":{"url":"https://your-agent.example.com/owlviz/events","events":["spot_floor_changed","reference_floor_changed"]}}}},"responses":{"201":{"description":"Created — signing secret returned once","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookEndpointCreated"}}}}}},"403":{"$ref":"#/components/responses/ApiError"}},"tags":["Automation"]}},"/v1/webhooks/{id}":{"get":{"summary":"Get webhook endpoint","operationId":"getWebhook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Webhook endpoint","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookEndpoint"}}}}}},"404":{"$ref":"#/components/responses/ApiError"}},"tags":["Automation"]},"patch":{"summary":"Update webhook endpoint","operationId":"updateWebhook","security":[{"DeveloperApiKey":[]},{"MonitoringAdminBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointUpdate"}}}},"responses":{"200":{"description":"Updated webhook endpoint"},"404":{"$ref":"#/components/responses/ApiError"}},"tags":["Automation"]},"delete":{"summary":"Disable webhook endpoint","operationId":"deleteWebhook","security":[{"DeveloperApiKey":[]},{"MonitoringAdminBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Webhook disabled"},"404":{"$ref":"#/components/responses/ApiError"}},"tags":["Automation"]}},"/v1/webhooks/{id}/deliveries":{"get":{"summary":"List webhook deliveries","operationId":"listWebhookDeliveries","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"status","in":"query","schema":{"type":"string","enum":["pending","delivering","delivered","failed","dead"]}}],"responses":{"200":{"description":"Delivery history","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}}}}}}}},"tags":["Automation"]}},"/v1/webhooks/{id}/test":{"post":{"summary":"Send test webhook delivery","operationId":"testWebhook","security":[{"DeveloperApiKey":[]},{"MonitoringAdminBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Test delivery result"},"404":{"$ref":"#/components/responses/ApiError"}},"tags":["Automation"]}},"/v1/events":{"get":{"summary":"List monitor events","operationId":"listEvents","parameters":[{"name":"target","in":"query","schema":{"type":"string"}},{"name":"targetType","in":"query","schema":{"type":"string","enum":["asset","collection"]}},{"name":"limit","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Event feed"}},"tags":["Monitoring"]}},"/v1/webhooks/{id}/deliveries/{deliveryId}":{"get":{"summary":"Get webhook delivery","description":"Inspect a single delivery attempt record (status, attempt count, next retry, last error).","operationId":"getWebhookDelivery","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Delivery record","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookDelivery"}}}}}},"404":{"$ref":"#/components/responses/ApiError"}},"tags":["Automation"]}}},"components":{"parameters":{"mint":{"name":"mint","in":"path","required":true,"schema":{"type":"string"}},"address":{"name":"address","in":"path","required":true,"schema":{"type":"string"}}},"schemas":{"ApiErrorBody":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}}},"MetadataHealth":{"type":"object","properties":{"score":{"type":"number"},"status":{"type":"string","enum":["healthy","warning","degraded","critical"]},"issues":{"type":"array","items":{"type":"object"}},"checks":{"type":"object"}}},"NormalizedAsset":{"type":"object","description":"See docs/api/response-models.md for the full field reference.","properties":{"id":{"type":"string"},"assetType":{"type":"string"},"standard":{"type":"string"},"name":{"type":"string","nullable":true},"symbol":{"type":"string","nullable":true},"health":{"$ref":"#/components/schemas/MetadataHealth"}}},"CollectionMarketSnapshot":{"type":"object","properties":{"address":{"type":"string"},"status":{"type":"string","enum":["success","no_listings","unmapped","unavailable"]},"floor":{"type":"object","nullable":true,"properties":{"sol":{"type":"number"},"lamports":{"type":"string"}}},"listingCount":{"type":"integer","nullable":true},"observedAt":{"type":"string","format":"date-time"},"scope":{"type":"string","enum":["provider_only","aggregated"]},"provider":{"type":"object","properties":{"id":{"type":"string","enum":["magic_eden","tensor"]},"symbol":{"type":"string","nullable":true},"sampleMint":{"type":"string","nullable":true},"attribution":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"url":{"type":"string","format":"uri"}}}}},"message":{"type":"string"},"cache":{"type":"object","properties":{"fresh":{"type":"boolean"},"cachedAt":{"type":"string","format":"date-time","nullable":true},"ttlSeconds":{"type":"integer"},"staleMaxAgeSeconds":{"type":"integer"}}},"aggregate":{"type":"object","properties":{"bestFloor":{"type":"object","properties":{"floor":{"type":"object","nullable":true,"properties":{"sol":{"type":"number"},"lamports":{"type":"string"}}},"status":{"type":"string","enum":["success","no_listings","unmapped","unavailable"]}}}}},"sources":{"type":"array","items":{"type":"object","properties":{"status":{"type":"string","enum":["success","no_listings","unmapped","unavailable"]},"floor":{"type":"object","nullable":true,"properties":{"sol":{"type":"number"},"lamports":{"type":"string"}}},"listingCount":{"type":"integer","nullable":true},"observedAt":{"type":"string","format":"date-time"},"provider":{"$ref":"#/components/schemas/CollectionMarketSnapshot/properties/provider"},"freshness":{"type":"string","enum":["fresh","stale"]},"message":{"type":"string"}}}},"provenance":{"type":"object","properties":{"bestFloorProviderId":{"type":"string","nullable":true,"enum":["magic_eden","tensor",null]},"method":{"type":"string","enum":["lowest_fresh_lamports"]},"comparedProviders":{"type":"array","items":{"type":"string","enum":["magic_eden","tensor"]}}}},"freshness":{"type":"object","properties":{"allFresh":{"type":"boolean"},"staleProviders":{"type":"array","items":{"type":"string","enum":["magic_eden","tensor"]}},"observedAt":{"type":"string","format":"date-time"}}},"comparison":{"type":"object","properties":{"spreadLamports":{"type":"string","nullable":true},"spreadSol":{"type":"number","nullable":true},"providerCountWithFreshFloors":{"type":"integer"}}}}},"CollectionMarketReference":{"type":"object","properties":{"address":{"type":"string"},"status":{"type":"string","enum":["ready","warming_up","stale","unavailable"]},"spot":{"type":"object","properties":{"floor":{"type":"object","nullable":true,"properties":{"sol":{"type":"number"},"lamports":{"type":"string"}}},"status":{"type":"string","enum":["success","no_listings","unmapped","unavailable"]}}},"reference":{"type":"object","properties":{"floor":{"type":"object","nullable":true,"properties":{"sol":{"type":"number"},"lamports":{"type":"string"}}},"method":{"type":"string","enum":["rolling_median_lamports"]},"window":{"type":"string","enum":["5m","15m","1h"]},"sampleCount":{"type":"integer"},"bucketCount":{"type":"integer"},"distinctTimeBucketCount":{"type":"integer"},"providerCount":{"type":"integer"},"computedAt":{"type":"string","format":"date-time"}}},"coverage":{"type":"object","properties":{"status":{"type":"string","enum":["sufficient","sparse","insufficient","stale"]},"mode":{"type":"string","enum":["single_provider","multi_provider","none"]},"distinctTimeBucketCount":{"type":"integer"},"maxGapSeconds":{"type":"integer","nullable":true},"expectedMaxGapSeconds":{"type":"integer"},"historySpanSeconds":{"type":"integer","nullable":true},"oldestObservedAt":{"type":"string","format":"date-time","nullable":true},"newestObservedAt":{"type":"string","format":"date-time","nullable":true}}},"movement":{"type":"object","properties":{"spotVsReferenceLamports":{"type":"string","nullable":true},"spotVsReferenceBps":{"type":"integer","nullable":true}}},"range":{"type":"object","properties":{"low":{"type":"object","nullable":true,"properties":{"sol":{"type":"number"},"lamports":{"type":"string"}}},"high":{"type":"object","nullable":true,"properties":{"sol":{"type":"number"},"lamports":{"type":"string"}}},"spreadBps":{"type":"integer","nullable":true}}},"providers":{"type":"object","properties":{"observed":{"type":"array","items":{"type":"string","enum":["magic_eden","tensor"]}},"contributions":{"type":"object","properties":{"magic_eden":{"type":"integer"},"tensor":{"type":"integer"}}},"current":{"type":"object","additionalProperties":{"type":"string","enum":["success","no_listings","unmapped","unavailable"]}}}}}},"CollectionMarketHistory":{"type":"object","properties":{"collection":{"type":"string"},"metric":{"type":"string","enum":["spot_floor","reference_floor","provider_floor"]},"window":{"type":"string","enum":["5m","15m","1h","6h","24h","7d"]},"interval":{"type":"string","enum":["1m","5m","15m","1h","4h","6h","24h"]},"provider":{"type":"string","nullable":true,"enum":["magic_eden","tensor",null]},"windowStart":{"type":"string","format":"date-time"},"windowEnd":{"type":"string","format":"date-time"},"intervalSeconds":{"type":"integer"},"expectedBucketCount":{"type":"integer"},"populatedBucketCount":{"type":"integer"},"emptyBucketCount":{"type":"integer"},"truncated":{"type":"boolean"},"coverage":{"type":"object","properties":{"firstObservation":{"type":"string","format":"date-time","nullable":true},"lastObservation":{"type":"string","format":"date-time","nullable":true},"sampleCount":{"type":"integer"},"density":{"type":"string","enum":["high","medium","low","empty"]}}},"providerLatestFloors":{"type":"array","items":{"type":"object","properties":{"provider":{"type":"string","enum":["magic_eden","tensor"]},"floorLamports":{"type":"string"},"observedAt":{"type":"string","format":"date-time"}}}},"providerRange":{"type":"object","properties":{"lowLamports":{"type":"string","nullable":true},"highLamports":{"type":"string","nullable":true}}},"points":{"type":"array","items":{"type":"object","properties":{"timestamp":{"type":"string","format":"date-time"},"openLamports":{"type":"string"},"highLamports":{"type":"string"},"lowLamports":{"type":"string"},"closeLamports":{"type":"string"},"sampleCount":{"type":"integer"},"providers":{"type":"array","items":{"type":"string","enum":["magic_eden","tensor"]}}}}}}},"CollectionMarketState":{"type":"object","properties":{"collection":{"type":"string","description":"Canonical Solana collection address"},"observedAt":{"type":"string","format":"date-time","description":"Newest spot observation timestamp from the aggregated market snapshot"},"spotFloor":{"type":"object","properties":{"floorLamports":{"type":"string","nullable":true,"description":"Best fresh observed spot floor (lamports), same as aggregate.bestFloor"},"providers":{"type":"array","items":{"type":"object","properties":{"provider":{"type":"string","enum":["magic_eden","tensor"]},"floorLamports":{"type":"string","nullable":true}}}}}},"referenceFloor":{"type":"object","properties":{"floorLamports":{"type":"string","nullable":true},"window":{"type":"string","enum":["5m","15m","1h"]}}},"changes":{"type":"object","properties":{"1h":{"$ref":"#/components/schemas/MarketStateFloorChange"},"24h":{"$ref":"#/components/schemas/MarketStateFloorChange"}}},"coverage":{"type":"object","properties":{"density":{"type":"string","enum":["high","medium","low","empty"]},"sampleCount":{"type":"integer","minimum":0,"description":"Qualifying observation count in the trailing 24h window"}}}}},"MarketStateFloorChange":{"type":"object","properties":{"absoluteLamports":{"type":"string","nullable":true,"description":"Current spot floor minus baseline spot floor at the start of the lookback window"},"percent":{"type":"string","nullable":true,"description":"Percent change vs baseline ((current - baseline) / baseline * 100)"}}},"CollectionIndexJobStatus":{"type":"object","properties":{"jobId":{"type":"string","format":"uuid"},"collection":{"type":"string"},"status":{"type":"string","enum":["queued","running","complete","failed","cancelled"]},"discovered":{"type":"integer","minimum":0},"processed":{"type":"integer","minimum":0},"failed":{"type":"integer","minimum":0},"indexedCount":{"type":"integer","minimum":0,"description":"Successfully indexed assets (same as processed on v1 index jobs)."},"expectedCount":{"type":["integer","null"],"minimum":0,"description":"Expected collection size when known (Helius grand_total / stored supply)."},"coverage":{"type":"string","enum":["complete","partial"],"description":"Whether indexed assets match expected supply."},"page":{"type":"integer","minimum":1},"cursor":{"type":["string","null"]},"progressPercent":{"type":"number","minimum":0,"maximum":100},"lastError":{"type":["string","null"]},"startedAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}}},"ChangeMonitor":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"targetType":{"type":"string","enum":["asset","collection"]},"target":{"type":"string","description":"Solana mint or collection address"},"status":{"type":"string","enum":["active","paused","disabled"]},"intervalSeconds":{"type":"integer","minimum":3600,"description":"Poll interval; self-serve keyed monitors enforce a 3600s minimum"},"events":{"type":"array","items":{"type":"string"},"description":"Subscribed monitor event types for this target"},"lastCheckedAt":{"type":["string","null"],"format":"date-time"},"nextCheckAt":{"type":["string","null"],"format":"date-time"},"lastSuccessAt":{"type":["string","null"],"format":"date-time"},"consecutiveFailures":{"type":"integer"},"waitingForIndex":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"WebhookSubscriptionFilters":{"type":"object","properties":{"collectionAddress":{"type":"string"},"watchId":{"type":"string","format":"uuid"}}},"WebhookEventType":{"type":"string","description":"Monitor event type, market event type, wildcard *, or webhook.test","enum":["metadata.changed","spot_floor_changed","reference_floor_changed","provider_floor_changed","provider_status_changed","*","webhook.test"]},"WebhookEndpoint":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri"},"status":{"type":"string","enum":["active","disabled"]},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEventType"}},"filters":{"oneOf":[{"$ref":"#/components/schemas/WebhookSubscriptionFilters"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"WebhookEndpointCreate":{"type":"object","required":["url","events"],"properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEventType"}},"filters":{"$ref":"#/components/schemas/WebhookSubscriptionFilters"}}},"WebhookEndpointCreated":{"allOf":[{"$ref":"#/components/schemas/WebhookEndpoint"},{"type":"object","properties":{"secret":{"type":"string","description":"HMAC signing secret — returned once at create"}},"required":["secret"]}]},"WebhookEndpointUpdate":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"status":{"type":"string","enum":["active","disabled"]},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEventType"}},"filters":{"oneOf":[{"$ref":"#/components/schemas/WebhookSubscriptionFilters"},{"type":"null"}]}}},"WebhookDelivery":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"webhookEndpointId":{"type":"string","format":"uuid"},"monitorEventId":{"type":["string","null"],"format":"uuid"},"marketEventId":{"type":["string","null"],"format":"uuid"},"status":{"type":"string","enum":["pending","delivering","delivered","failed","dead"]},"attempt":{"type":"integer"},"httpStatus":{"type":["integer","null"]},"isTest":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}}},"MarketEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"collectionAddress":{"type":"string"},"watchId":{"type":["string","null"],"format":"uuid"},"type":{"type":"string","enum":["spot_floor_changed","reference_floor_changed","provider_floor_changed","provider_status_changed"]},"severity":{"type":"string","enum":["info","notice","warning"]},"summary":{"type":"string"},"before":{},"after":{},"payload":{"type":"object","description":"Snapshot facts: spot/reference/provider deltas and spotVsReferenceBps"},"occurredAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}},"MarketWatch":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"collectionAddress":{"type":"string"},"status":{"type":"string","enum":["active","paused","disabled"]},"intervalSeconds":{"type":"integer"},"jitterSeconds":{"type":"integer"},"lastCheckedAt":{"type":["string","null"],"format":"date-time"},"nextCheckAt":{"type":["string","null"],"format":"date-time"},"lastSuccessAt":{"type":["string","null"],"format":"date-time"},"consecutiveFailures":{"type":"integer"},"backoffSeconds":{"type":"integer"},"refreshRequestedAt":{"type":["string","null"],"format":"date-time"},"lastTick":{"type":["object","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}},"securitySchemes":{"DeveloperApiKey":{"type":"http","scheme":"bearer","description":"Portal-issued OwlViz API key (`ov_live_…`). Resolves developer account and plan for self-serve Market Watches and webhooks."},"MonitoringAdminBearer":{"type":"http","scheme":"bearer","description":"Ops admin token (MONITORING_ADMIN_TOKEN) for change-monitor beta writes and optional operator overrides. Never embed in frontend or NEXT_PUBLIC_* env vars."}},"responses":{"ApiError":{"description":"API error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"RateLimited":{"description":"Rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"string"}},"X-RateLimit-Limit":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"},"example":{"error":{"code":"RATE_LIMITED","message":"Too many requests. Please retry after the window resets."}}}}}}},"tags":[{"name":"System","description":"Service health and metadata about the API itself."},{"name":"Assets","description":"Normalized Solana assets: metadata, health scores, on-chain inspection, media reliability, snapshots."},{"name":"Collections","description":"Indexed collection summaries, health aggregates, and asset listings."},{"name":"Automation","description":"Agent-oriented market intelligence: multi-provider floors, reference floors, durable market events, Market Watch sampling, and signed webhook delivery. OwlViz provides data — not trade execution."},{"name":"Monitoring","description":"Change monitor event feeds (metadata/health deltas). Monitor CRUD is self-serve via API key or portal (plan quotas, 3600s min interval). Manual check remains admin-only."}]}