Quick start
**Reliable asset data for Solana.** One API for normalized metadata, health, media reliability, collection intelligence, and change monitoring.
Production base URL (Railway today; override via NEXT_PUBLIC_API_BASE_URL when a custom API hostname is attached):
https://solana-metadata-platform-production.up.railway.appPublic scanner — **Owlviz** (read-only UI; Railway today):
https://solana-metadata-dashboard-production.up.railway.appCustom domain example (env-driven, e.g. owlviz.dev):
https://api.owlviz.dev
https://owlviz.devExample mint (The Bullpen):
C5gHBKXwA8jduXNk3HyAVLnLBN6PEM8fTqkNNh5uyyjJResolve an asset in 2 minutes
Every asset lookup starts with a Solana mint address (base58 public key). Responses are JSON with a top-level data object. Many fields are nullable when metadata is missing or unresolved.
curl
curl -sS \
"https://solana-metadata-platform-production.up.railway.app/v1/assets/C5gHBKXwA8jduXNk3HyAVLnLBN6PEM8fTqkNNh5uyyjJ" \
-H "Accept: application/json"TypeScript / JavaScript
const API_BASE = 'https://solana-metadata-platform-production.up.railway.app';
const mint = 'C5gHBKXwA8jduXNk3HyAVLnLBN6PEM8fTqkNNh5uyyjJ';
const response = await fetch(`${API_BASE}/v1/assets/${mint}`, {
headers: { Accept: 'application/json' },
});
if (!response.ok) {
const body = (await response.json()) as { error?: { code?: string; message?: string } };
throw new Error(body.error?.message ?? `HTTP ${response.status}`);
}
const { data } = (await response.json()) as { data: unknown };
console.log(data);What you get back
The normalized asset includes identity fields (name, symbol, description), media, attributes, collection, creators, health, on-chain inspection (tokenProgram, permissions, extensions, risk), and diagnostics. See [response-models.md](./response-models.md) for the full field reference.
Query parameters
| Parameter | Routes | Meaning |
|---|---|---|
refresh=true | Asset routes | Bypass cache and re-resolve from upstream providers |
Cache headers
Asset and collection responses may include:
| Header | Values | Meaning |
|---|---|---|
X-Cache | HIT, MISS, BYPASS | Whether the response came from cache |
X-Cache-TTL | seconds | Configured TTL for cached entries |
Rate limits
Public asset and collection routes are rate limited per client IP. Defaults (may change):
- Global: **120** requests per **60** seconds
- Expensive routes (including
GET /v1/assets/:mint): additional **60** requests per **60** seconds per route template
Responses include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. When limited, the API returns **429** with Retry-After. See [errors-and-rate-limits.md](./errors-and-rate-limits.md).
/health is exempt from rate limiting.
Next steps
- [Assets](./assets.md) — resolution, health, inspection, snapshots
- [Media](./media.md) — reliability, recovery, preserved URLs
- [Collections](./collections.md) — indexing, health aggregates, asset lists
- [Monitoring](./monitoring.md) — change detection (read vs private-beta writes)
- [Errors & rate limits](./errors-and-rate-limits.md)
- [Examples](./examples/)