v1.0.0

Getting Started

Introduction

Welcome to the IconVault API — the ultimate RESTful service for accessing premium SVG brand icons. Our API provides programmatic access to 429+ SVG icons across 278 brands and 11 categories, with multiple variants per icon including standard, dark, light, and wordmark styles. Whether you're building a developer portfolio, a SaaS dashboard, or a design system, IconVault gives you instant access to the icons you need without managing assets manually.

The API is completely free to use with generous rate limits of 2,000 requests per IP per 15-minute window. No authentication is required — just start making requests. All responses are in JSON format with consistent structure, making it easy to integrate into any application or workflow. Built by Xbibz Official, IconVault is designed with developer experience as the top priority.

429+ Icons
Premium SVG brand icons
<50ms Response
Edge-optimized globally
No Auth Required
Start using immediately

Quick Start

Getting started with IconVault is as simple as making a single HTTP request. There's no signup, no API keys, and no complex configuration. Just pick your preferred language or tool and make your first request. Below are examples in the most common languages to get you up and running in under a minute.

bash
1# Get the first 5 icons
2curl "https://iconvault-api.pages.dev/api/icons?limit=5"
3
4# Search for Discord icon
5curl "https://iconvault-api.pages.dev/api/icons/search?q=discord"
6
7# Get a specific icon as raw SVG
8curl "https://iconvault-api.pages.dev/api/icons/Discord?format=svg"

Base URL

All API requests should be made to the base URL below. The API uses HTTPS exclusively to ensure secure communication. All endpoints are relative to this base URL. When testing locally, replace with your local server address.

text
https://iconvault-api.pages.dev

Tip: When developing locally with the IconVault project running on your machine, use http://localhost:3000 as the base URL instead.

Authentication

IconVault API does not require any authentication. There are no API keys, tokens, or login credentials needed. Simply make requests to any endpoint and receive data. This design choice was made to reduce friction and make the API as accessible as possible for developers of all skill levels.

However, to ensure fair usage and protect the service from abuse, all requests are subject to rate limiting. Each IP address is allowed 2,000 requests per 15-minute window. This is generous enough for most use cases, including production applications. If you find yourself hitting the limit, consider implementing client-side caching (see the Rate Limiting and Best Practices sections for detailed guidance).

No API Key Required
Just start making requests. Rate limiting is enforced per IP address with standard HTTP headers to track your usage.

API Reference

Complete reference for all IconVault API endpoints. Each endpoint includes detailed parameter descriptions, request examples in multiple languages, and full response schemas. All endpoints return JSON unless the format=svg parameter is specified.

GET/api

The root endpoint returns a welcome message along with basic API information including the current version, available endpoints, and rate limit configuration. This is useful for verifying the API is operational and discovering available resources programmatically.

Request Examples

bash
curl "https://iconvault-api.pages.dev/api"

Response Example

json
1{
2  "success": true,
3  "message": "Welcome to IconVault API!",
4  "version": "1.0.0",
5  "developer": "Xbibz Official",
6  "endpoints": {
7    "icons": "/api/icons",
8    "icon_detail": "/api/icons/{slug}",
9    "search": "/api/icons/search?q={query}",
10    "categories": "/api/categories",
11    "stats": "/api/stats"
12  },
13  "rate_limit": {
14    "max_requests": 2000,
15    "window": "15 minutes"
16  },
17  "documentation": "Visit the website for full API documentation."
18}
GET/api/icons

The primary endpoint for listing and browsing icons. Returns paginated results with powerful filtering by category, variant type, and free-text search. Each icon object includes all available variants with their direct URLs, API URLs, and SVG URLs. Pagination metadata helps you navigate through the full collection of 278 brands efficiently.

Query Parameters

NameTypeRequiredDefaultDescription
pagenumberOptional1Page number for pagination. Starts at 1.
limitnumberOptional20Number of items per page. Maximum value is 100.
categorystringOptionalFilter icons by category. Case-insensitive. E.g., "Social", "Programming", "Design"
variantstringOptionalFilter to only brands that have a specific variant. E.g., "dark", "wordmark"
searchstringOptionalSearch icons by name or slug. Case-insensitive partial matching.

Request Examples

bash
1# Get first 20 icons (default)
2curl "https://iconvault-api.pages.dev/api/icons"
3
4# Get page 2 with 10 items per page
5curl "https://iconvault-api.pages.dev/api/icons?page=2&limit=10"
6
7# Filter by Social category
8curl "https://iconvault-api.pages.dev/api/icons?category=Social"
9
10# Search for icons matching "react"
11curl "https://iconvault-api.pages.dev/api/icons?search=react"
12
13# Combine: Social category with dark variant, page 1, limit 5
14curl "https://iconvault-api.pages.dev/api/icons?category=Social&variant=dark&limit=5&page=1"

Response Example

json
1{
2  "success": true,
3  "data": {
4    "icons": [
5      {
6        "name": "Discord",
7        "slug": "Discord",
8        "category": "Social",
9        "available_variants": ["standard"],
10        "variants": {
11          "standard": {
12            "slug": "Discord",
13            "url": "https://iconvault-api.pages.dev/icons/Discord.svg",
14            "size": 1217,
15            "api_url": "https://iconvault-api.pages.dev/api/icons/Discord?variant=standard",
16            "svg_url": "https://iconvault-api.pages.dev/api/icons/Discord?variant=standard&format=svg"
17          }
18        }
19      }
20    ],
21    "pagination": {
22      "page": 1,
23      "limit": 20,
24      "total": 278,
25      "total_pages": 14,
26      "has_next": true,
27      "has_prev": false
28    }
29  },
30  "meta": {
31    "total_icons": 429,
32    "total_brands": 278,
33    "categories": ["AI & ML", "Browser", "Cloud & Hosting", "..."],
34    "timestamp": "2025-01-15T12:00:00.000Z"
35  }
36}

Tip: Use the pagination object to build navigation. The has_next and has_prev boolean flags make it easy to enable/disable next/previous buttons.

GET/api/icons/{slug}

Retrieve detailed information about a specific icon by its slug. The response includes the brand name, category, the selected variant with all URLs, and a list of all available variants. This endpoint also supports requesting the raw SVG content directly by setting format=svg, which returns the SVG with proper Content-Type: image/svg+xml headers.

Parameters

NameTypeRequiredDefaultDescription
slugstringRequiredThe icon slug identifier (path parameter). E.g., "Discord", "React", "Docker". Case-insensitive.
variantstringOptionalstandardPreferred variant to return. Falls back to standard if the requested variant is unavailable.
formatstringOptionalSet to "svg" or "raw" to receive raw SVG content instead of JSON.

Request Examples

bash
1# Get Discord icon details (JSON)
2curl "https://iconvault-api.pages.dev/api/icons/Discord"
3
4# Get dark variant
5curl "https://iconvault-api.pages.dev/api/icons/Deno?variant=dark"
6
7# Get raw SVG content
8curl "https://iconvault-api.pages.dev/api/icons/Discord?format=svg"
9
10# Case-insensitive slug matching
11curl "https://iconvault-api.pages.dev/api/icons/discord"

Response (JSON)

json
1{
2  "success": true,
3  "data": {
4    "name": "Discord",
5    "slug": "Discord",
6    "category": "Social",
7    "requested_variant": "standard",
8    "selected_variant": {
9      "slug": "Discord",
10      "url": "https://iconvault-api.pages.dev/icons/Discord.svg",
11      "svg_url": "https://iconvault-api.pages.dev/api/icons/Discord?variant=standard&format=svg",
12      "size": 1217
13    },
14    "available_variants": [
15      {
16        "variant": "standard",
17        "slug": "Discord",
18        "url": "https://iconvault-api.pages.dev/icons/Discord.svg",
19        "size": 1217,
20        "api_url": "https://iconvault-api.pages.dev/api/icons/Discord?variant=standard",
21        "svg_url": "https://iconvault-api.pages.dev/api/icons/Discord?variant=standard&format=svg"
22      }
23    ]
24  }
25}

Response (SVG format)

xml
1<!-- When format=svg, the response is raw SVG with Content-Type: image/svg+xml -->
2<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" ...>
3  <!-- SVG path data -->
4</svg>
GET/api/categories

Retrieve all available icon categories with brand and icon counts. This endpoint is useful for building category navigation, filters, or displaying category statistics in your application. Each category includes a URL-friendly slug for use in other API queries.

Request Examples

bash
curl "https://iconvault-api.pages.dev/api/categories"

Response Example

json
1{
2  "success": true,
3  "data": [
4    {
5      "name": "AI & ML",
6      "slug": "ai-ml",
7      "brand_count": 12,
8      "icon_count": 45
9    },
10    {
11      "name": "Browser",
12      "slug": "browser",
13      "brand_count": 8,
14      "icon_count": 24
15    },
16    {
17      "name": "Social",
18      "slug": "social",
19      "brand_count": 22,
20      "icon_count": 67
21    }
22  ]
23}
GET/api/stats

Get comprehensive API statistics including total icons, brands, variants, categories, and rate limit configuration. Also includes per-category breakdowns with brand and icon counts. Useful for dashboards, status pages, or displaying overview statistics.

Request Examples

bash
curl "https://iconvault-api.pages.dev/api/stats"

Response Example

json
1{
2  "success": true,
3  "data": {
4    "total_icons": 429,
5    "total_brands": 278,
6    "total_variants": 429,
7    "categories_count": 11,
8    "categories": [
9      { "category": "AI & ML", "brands": 12, "icons": 45 },
10      { "category": "Social", "brands": 22, "icons": 67 }
11    ],
12    "version": "1.0.0",
13    "source": "XbibzModder777/icon-svg",
14    "rate_limit": {
15      "max_requests": 2000,
16      "window": "15 minutes",
17      "headers": [
18        "X-RateLimit-Limit",
19        "X-RateLimit-Remaining",
20        "X-RateLimit-Reset",
21        "X-RateLimit-Policy"
22      ]
23    }
24  }
25}

Static Website Integration

If you're building a static website — whether it's a blog, landing page, or documentation site — you can use IconVault icons without any JavaScript framework. SVGs can be embedded directly in HTML using several methods, each with different trade-offs in terms of caching, styling flexibility, and performance.

Using <img> Tags

The simplest way to use IconVault icons in a static site is via the <img> tag with the direct SVG URL. This approach benefits from browser caching and CDN delivery. However, you cannot style the SVG's internal elements (like changing colors with CSS) when using this method.

index.html
html
1<!-- Using direct SVG URL -->
2<img
3  src="https://iconvault-api.pages.dev/icons/Discord.svg"
4  alt="Discord"
5  width="32"
6  height="32"
7/>
8
9<!-- With fallback and loading optimization -->
10<img
11  src="https://iconvault-api.pages.dev/icons/React.svg"
12  alt="React framework logo"
13  width="48"
14  height="48"
15  loading="lazy"
16  class="icon"
17/>
18
19<!-- Using the API endpoint with format=svg -->
20<img
21  src="https://iconvault-api.pages.dev/api/icons/Docker?format=svg"
22  alt="Docker"
23  width="32"
24  height="32"
25/>

Inline SVG

For maximum styling control, fetch the SVG content and embed it directly in your HTML. This allows you to style the icon with CSS, apply hover effects, and change colors dynamically. You can get the raw SVG via the format=svg parameter.

inline-svg.html
html
1<!-- Method 1: Direct inline SVG (copy-paste from API response) -->
2<div class="icon-container">
3  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="32" height="32">
4    <!-- SVG content from /api/icons/Discord?format=svg -->
5  </svg>
6</div>
7
8<!-- Method 2: Fetch SVG via JavaScript and inject -->
9<div id="icon-container"></div>
10
11<script>
12  async function loadIcon(slug, container) {
13    const response = await fetch(
14      'https://iconvault-api.pages.dev/api/icons/' + slug + '?format=svg'
15    );
16    const svgText = await response.text();
17    container.innerHTML = svgText;
18  }
19
20  loadIcon('Discord', document.getElementById('icon-container'));
21</script>
22
23<!-- Style inline SVGs with CSS -->
24<style>
25  .icon-container svg {
26    width: 32px;
27    height: 32px;
28    fill: currentColor; /* Inherits text color */
29    transition: fill 0.2s;
30  }
31  .icon-container:hover svg {
32    fill: #f97316; /* Orange on hover */
33  }
34</style>

CSS Background Image

You can use SVG icons as CSS background images for decorative elements, pseudo-elements, or components where you don't need direct SVG manipulation. This is a clean approach for status indicators, list bullets, or background decorations.

styles.css
css
1/* Using SVG as CSS background */
2.icon-discord {
3  width: 32px;
4  height: 32px;
5  background-image: url('https://iconvault-api.pages.dev/icons/Discord.svg');
6  background-size: contain;
7  background-repeat: no-repeat;
8  background-position: center;
9}
10
11/* With pseudo-element */
12.tech-stack li::before {
13  content: '';
14  display: inline-block;
15  width: 20px;
16  height: 20px;
17  margin-right: 8px;
18  background-size: contain;
19  background-repeat: no-repeat;
20  vertical-align: middle;
21}
22
23.tech-stack li.react::before {
24  background-image: url('https://iconvault-api.pages.dev/icons/React.svg');
25}
26
27.tech-stack li.docker::before {
28  background-image: url('https://iconvault-api.pages.dev/icons/Docker.svg');
29}
30
31/* Using with mask for color control */
32.adaptive-icon {
33  width: 32px;
34  height: 32px;
35  background-color: currentColor;
36  -webkit-mask-image: url('https://iconvault-api.pages.dev/icons/Discord.svg');
37  mask-image: url('https://iconvault-api.pages.dev/icons/Discord.svg');
38  -webkit-mask-size: contain;
39  mask-size: contain;
40  -webkit-mask-repeat: no-repeat;
41  mask-repeat: no-repeat;
42}

Using <object> or <embed> Tags

The <object> and <embed> tags allow you to embed SVGs with the ability to reference their internal structure from external CSS, while still benefiting from browser caching.

object-embed.html
html
1<!-- Using <object> tag -->
2<object
3  type="image/svg+xml"
4  data="https://iconvault-api.pages.dev/icons/React.svg"
5  width="32"
6  height="32"
7  aria-label="React logo"
8>
9  <!-- Fallback for unsupported browsers -->
10  <img src="https://iconvault-api.pages.dev/icons/React.svg" alt="React" />
11</object>
12
13<!-- Using <embed> tag -->
14<embed
15  type="image/svg+xml"
16  src="https://iconvault-api.pages.dev/icons/Docker.svg"
17  width="32"
18  height="32"
19/>

Downloading Icons for Local Use

For maximum performance and offline capability, you can download icons and serve them locally. This eliminates external dependencies and DNS lookup latency. Use the format=svg endpoint to fetch raw SVG content for local storage.

download-icons.sh
bash
1#!/bin/bash
2# Download icons for local use
3ICONS=("Discord" "React" "Docker" "Figma" "GitHub" "VS_Code")
4BASE="https://iconvault-api.pages.dev/api/icons"
5
6mkdir -p public/icons
7
8for icon in "${ICONS[@]}"; do
9  curl -s "${BASE}/${icon}?format=svg" -o "public/icons/${icon}.svg"
10  echo "Downloaded ${icon}.svg"
11done
12
13echo "All icons downloaded!"
local-usage.html
html
<!-- Reference downloaded icons locally -->
<img src="/icons/Discord.svg" alt="Discord" width="32" height="32" />
<img src="/icons/React.svg" alt="React" width="32" height="32" />

Dynamic Website Integration

For modern web applications built with frameworks like React, Next.js, Vue, Svelte, or Angular, IconVault provides flexible integration options. Below are complete guides for each framework with code examples, hooks, and best practices.

React Integration

React applications can integrate IconVault icons using custom hooks, lazy loading, and inline SVG rendering. The recommended approach is to create a reusable Icon component that handles fetching, caching, and error states gracefully. With React's component model, you get full control over styling and behavior.

IconVaultIcon.tsx
tsx
1import { useState, useEffect } from 'react';
2
3interface IconProps {
4  slug: string;
5  variant?: string;
6  size?: number;
7  className?: string;
8}
9
10// Cache for SVG content
11const svgCache = new Map();
12
13export function IconVaultIcon({ slug, variant = 'standard', size = 24, className = '' }: IconProps) {
14  const [svg, setSvg] = useState(null);
15  const [loading, setLoading] = useState(true);
16  const [error, setError] = useState(false);
17
18  const cacheKey = slug + '-' + variant;
19
20  useEffect(() => {
21    if (svgCache.has(cacheKey)) {
22      setSvg(svgCache.get(cacheKey));
23      setLoading(false);
24      return;
25    }
26
27    setLoading(true);
28    setError(false);
29
30    fetch('https://iconvault-api.pages.dev/api/icons/' + slug + '?variant=' + variant + '&format=svg')
31      .then(res => {
32        if (!res.ok) throw new Error('Icon not found');
33        return res.text();
34      })
35      .then(svgText => {
36        svgCache.set(cacheKey, svgText);
37        setSvg(svgText);
38      })
39      .catch(() => setError(true))
40      .finally(() => setLoading(false));
41  }, [slug, variant, cacheKey]);
42
43  if (loading) {
44    return <div style={{ width: size, height: size }} className={"animate-pulse bg-muted rounded " + className} />;
45  }
46  if (error) {
47    return <div style={{ width: size, height: size }} className={"bg-destructive/10 rounded " + className} />;
48  }
49  if (!svg) return null;
50
51  return (
52    <div
53      className={"icon-vault " + className}
54      style={{ width: size, height: size }}
55      dangerouslySetInnerHTML={{ __html: svg }}
56      aria-label={slug + ' icon'}
57      role="img"
58    />
59  );
60}
61
62// Usage:
63// <IconVaultIcon slug="Discord" size={32} />
64// <IconVaultIcon slug="React" variant="dark" />
useIconSearch.ts
tsx
1// Custom hook for icon search
2import { useState, useEffect } from 'react';
3
4export function useIconSearch(query, debounceMs = 300) {
5  const [results, setResults] = useState([]);
6  const [loading, setLoading] = useState(false);
7
8  useEffect(() => {
9    if (!query || query.length < 2) {
10      setResults([]);
11      return;
12    }
13
14    const timer = setTimeout(async () => {
15      setLoading(true);
16      try {
17        const res = await fetch(
18          'https://iconvault-api.pages.dev/api/icons/search?q=' + encodeURIComponent(query)
19        );
20        const data = await res.json();
21        setResults(data.data || []);
22      } catch {
23        setResults([]);
24      } finally {
25        setLoading(false);
26      }
27    }, debounceMs);
28
29    return () => clearTimeout(timer);
30  }, [query, debounceMs]);
31
32  return { results, loading };
33}

Next.js Integration

Next.js applications benefit from server-side rendering, the Image component, and built-in optimization. When using IconVault with Next.js, you should fetch SVGs on the server when possible, and use the next/image component for optimized loading when using img tags. For inline SVG styling, fetch the SVG content server-side and pass it as a prop.

NextIcon.tsx
tsx
1// Server Component (Next.js App Router)
2async function getIconSvg(slug, variant = 'standard') {
3  try {
4    const res = await fetch(
5      'https://iconvault-api.pages.dev/api/icons/' + slug + '?variant=' + variant + '&format=svg',
6      { next: { revalidate: 86400 } } // Cache for 24 hours
7    );
8    if (!res.ok) return null;
9    return res.text();
10  } catch {
11    return null;
12  }
13}
14
15// Server Component
16export async function ServerIcon({ slug, variant, size = 24, className }) {
17  const svg = await getIconSvg(slug, variant);
18  if (!svg) return <div style={{ width: size, height: size }} className="bg-muted rounded" />;
19
20  return (
21    <div
22      style={{ width: size, height: size }}
23      className={className}
24      dangerouslySetInnerHTML={{ __html: svg }}
25      role="img"
26      aria-label={slug + ' icon'}
27    />
28  );
29}
30
31// Usage in a page:
32// import { ServerIcon } from '@/components/ServerIcon';
33// export default function Page() {
34//   return <ServerIcon slug="Discord" size={48} />;
35// }

Vue.js Integration

Vue.js applications can use IconVault with a composable function for fetching icons and a component for rendering. Vue's reactivity system makes it easy to create dynamic icon displays with search, filtering, and lazy loading capabilities.

IconVaultIcon.vue
vue
1<script setup>
2import { ref, watch, onMounted } from 'vue'
3
4const props = defineProps({
5  slug: { type: String, required: true },
6  variant: { type: String, default: 'standard' },
7  size: { type: Number, default: 24 }
8})
9
10const svg = ref(null)
11const loading = ref(true)
12const error = ref(false)
13
14const cache = new Map()
15
16async function fetchIcon() {
17  const key = props.slug + '-' + props.variant
18  if (cache.has(key)) {
19    svg.value = cache.get(key)
20    loading.value = false
21    return
22  }
23
24  loading.value = true
25  error.value = false
26
27  try {
28    const res = await fetch(
29      'https://iconvault-api.pages.dev/api/icons/' + props.slug + '?variant=' + props.variant + '&format=svg'
30    )
31    if (!res.ok) throw new Error('Not found')
32    const text = await res.text()
33    cache.set(key, text)
34    svg.value = text
35  } catch {
36    error.value = true
37  } finally {
38    loading.value = false
39  }
40}
41
42onMounted(fetchIcon)
43watch(() => [props.slug, props.variant], fetchIcon)
44</script>
45
46<template>
47  <div
48    v-if="svg && !loading && !error"
49    :style="{ width: size + 'px', height: size + 'px' }"
50    v-html="svg"
51    role="img"
52    :aria-label="slug + ' icon'"
53  />
54  <div v-else-if="loading" :style="{ width: size + 'px', height: size + 'px' }" class="animate-pulse bg-muted rounded" />
55</template>
56
57<!-- Usage: <IconVaultIcon slug="Discord" :size="32" -->

Svelte Integration

Svelte's compiled approach means you get zero-runtime-overhead icon components. Create a reusable Svelte component that fetches and caches SVG content, with built-in loading and error states. Svelte's reactive declarations make the logic clean and easy to follow.

IconVaultIcon.svelte
svelte
1<script>
2  import { onMount } from 'svelte';
3
4  export let slug = '';
5  export let variant = 'standard';
6  export let size = 24;
7
8  let svg = '';
9  let loading = true;
10  let error = false;
11
12  const cache = new Map();
13
14  async function fetchIcon() {
15    const key = slug + '-' + variant;
16    if (cache.has(key)) {
17      svg = cache.get(key);
18      loading = false;
19      return;
20    }
21
22    loading = true;
23    error = false;
24
25    try {
26      const res = await fetch(
27        'https://iconvault-api.pages.dev/api/icons/' + slug + '?variant=' + variant + '&format=svg'
28      );
29      if (!res.ok) throw new Error('Not found');
30      const text = await res.text();
31      cache.set(key, text);
32      svg = text;
33    } catch {
34      error = true;
35    } finally {
36      loading = false;
37    }
38  }
39
40  onMount(fetchIcon);
41  $: if (slug || variant) fetchIcon();
42</script>
43
44{#if loading}
45  <div class="icon-loading" style="width: {size}px; height: {size}px;"></div>
46{:else if error}
47  <div class="icon-error" style="width: {size}px; height: {size}px;"></div>
48{:else}
49  <div
50    class="icon-vault"
51    style="width: {size}px; height: {size}px;"
52    {@html svg}
53    role="img"
54    aria-label="{slug} icon"
55  ></div>
56{/if}

Angular Integration

Angular applications can use IconVault through a service that handles fetching and caching, combined with a component for rendering. Angular's HttpClient and dependency injection system make it straightforward to create a robust icon management solution with proper TypeScript typing.

icon-vault.service.ts
typescript
1import { Injectable } from '@angular/core';
2import { HttpClient } from '@angular/common/http';
3import { Observable, of } from 'rxjs';
4import { map, shareReplay, catchError } from 'rxjs/operators';
5
6@Injectable({ providedIn: 'root' })
7export class IconVaultService {
8  private baseUrl = 'https://iconvault-api.pages.dev/api';
9  private svgCache = new Map();
10
11  constructor(private http: HttpClient) {}
12
13  getIconSvg(slug, variant = 'standard'): Observable<string> {
14    const key = slug + '-' + variant;
15    if (this.svgCache.has(key)) {
16      return this.svgCache.get(key);
17    }
18
19    const svg$ = this.http.get(
20      this.baseUrl + '/icons/' + slug + '?variant=' + variant + '&format=svg',
21      { responseType: 'text' }
22    ).pipe(
23      catchError(() => of('')),
24      shareReplay(1)
25    );
26
27    this.svgCache.set(key, svg$);
28    return svg$;
29  }
30
31  searchIcons(query: string): Observable<any> {
32    return this.http.get(this.baseUrl + '/icons/search?q=' + encodeURIComponent(query));
33  }
34}

Vanilla JavaScript

You don't need a framework to use IconVault effectively. With vanilla JavaScript, you can create a lightweight icon management system with caching, dynamic rendering, and search capabilities. This approach is ideal for simple websites, bookmarklets, or progressive enhancement.

iconvault.js
javascript
1// IconVault - Lightweight vanilla JS client
2const IconVault = {
3  baseUrl: 'https://iconvault-api.pages.dev/api',
4  cache: new Map(),
5  cacheExpiry: 24 * 60 * 60 * 1000, // 24 hours
6
7  async getIcon(slug, variant = 'standard') {
8    const key = slug + '-' + variant;
9    const cached = this.cache.get(key);
10
11    if (cached && Date.now() - cached.timestamp < this.cacheExpiry) {
12      return cached.svg;
13    }
14
15    const res = await fetch(this.baseUrl + '/icons/' + slug + '?variant=' + variant + '&format=svg');
16    if (!res.ok) throw new Error('Icon "' + slug + '" not found');
17
18    const svg = await res.text();
19    this.cache.set(key, { svg, timestamp: Date.now() });
20    return svg;
21  },
22
23  async renderIcon(container, slug, options = {}) {
24    const { variant = 'standard', size = 24 } = options;
25    try {
26      const svg = await this.getIcon(slug, variant);
27      container.innerHTML = svg;
28      const svgEl = container.querySelector('svg');
29      if (svgEl) {
30        svgEl.setAttribute('width', size);
31        svgEl.setAttribute('height', size);
32        svgEl.setAttribute('role', 'img');
33        svgEl.setAttribute('aria-label', slug + ' icon');
34      }
35    } catch (err) {
36      console.error('Failed to load icon ' + slug + ':', err);
37    }
38  },
39
40  async search(query) {
41    const res = await fetch(this.baseUrl + '/icons/search?q=' + encodeURIComponent(query));
42    return res.json();
43  }
44};
45
46// Usage:
47// IconVault.renderIcon(document.getElementById('icon'), 'Discord', { size: 32 });
48// const results = await IconVault.search('react');

Web Components

Web Components provide a framework-agnostic way to create reusable icon elements that work across any HTML page or framework. Create a custom element that encapsulates all the fetching and rendering logic, making it as simple to use as a native HTML element.

icon-vault-element.js
javascript
1class IconVaultElement extends HTMLElement {
2  static get observedAttributes() {
3    return ['slug', 'variant', 'size'];
4  }
5
6  constructor() {
7    super();
8    this._cache = new Map();
9  }
10
11  connectedCallback() {
12    this._render();
13  }
14
15  attributeChangedCallback() {
16    this._render();
17  }
18
19  async _render() {
20    const slug = this.getAttribute('slug');
21    const variant = this.getAttribute('variant') || 'standard';
22    const size = this.getAttribute('size') || '24';
23
24    if (!slug) return;
25
26    const key = slug + '-' + variant;
27
28    let svg = this._cache.get(key);
29    if (!svg) {
30      try {
31        const res = await fetch(
32          'https://iconvault-api.pages.dev/api/icons/' + slug + '?variant=' + variant + '&format=svg'
33        );
34        if (!res.ok) throw new Error('Not found');
35        svg = await res.text();
36        this._cache.set(key, svg);
37      } catch {
38        this.innerHTML = '<span style="color:red">&#10005;</span>';
39        return;
40      }
41    }
42
43    this.innerHTML = svg;
44    const svgEl = this.querySelector('svg');
45    if (svgEl) {
46      svgEl.setAttribute('width', size);
47      svgEl.setAttribute('height', size);
48    }
49  }
50}
51
52customElements.define('icon-vault', IconVaultElement);
53
54// Usage in any HTML:
55// <icon-vault slug="Discord" size="32"></icon-vault>
56// <icon-vault slug="React" variant="dark" size="48"></icon-vault>

Rate Limiting

Overview

IconVault API enforces rate limiting to ensure fair usage and maintain service stability for all users. The rate limit is set at 2,000 requests per IP address per 15-minute window. This means you can make approximately 2.2 requests per second on average, which is more than sufficient for most use cases including production applications with reasonable traffic.

When you exceed the rate limit, the API returns a 429 Too Many Requests response with a JSON body containing a retry_after field that tells you how many seconds to wait before making another request. The rate limit window automatically resets after 15 minutes from your first request in the current window.

2,000
Requests per window
15 min
Window duration
429
Error code when exceeded

Response Headers

Every API response includes rate limit headers that help you track your usage programmatically. These headers follow the IETF RateLimit Header standard and provide real-time information about your current rate limit status.

X-RateLimit-Limit
The maximum number of requests allowed in the current window (always 2000).
X-RateLimit-Remaining
The number of requests remaining in the current window. Decrements with each request.
X-RateLimit-Reset
ISO 8601 timestamp when the current rate limit window resets and your quota refills to 2000.
X-RateLimit-Policy
The rate limit policy in the format "2000;w=900" (2000 requests per 900 seconds).
javascript
1// Check your rate limit status from response headers
2const response = await fetch('https://iconvault-api.pages.dev/api/icons?limit=5');
3
4console.log('Limit:', response.headers.get('X-RateLimit-Limit'));
5console.log('Remaining:', response.headers.get('X-RateLimit-Remaining'));
6console.log('Resets at:', response.headers.get('X-RateLimit-Reset'));
7console.log('Policy:', response.headers.get('X-RateLimit-Policy'));

Best Practices

Implement client-side caching
Store icon data locally using localStorage, sessionStorage, or an in-memory cache. Icons rarely change, so cached data can be used for extended periods.
Use bulk endpoints efficiently
Request larger page sizes (up to 100) in a single call rather than making many small requests. This reduces your request count dramatically.
Fetch SVGs once and store locally
When using inline SVGs, fetch the SVG content once and store it. This is especially important for frequently-used icons.
Implement exponential backoff
When you receive a 429 response, wait the specified retry_after duration before making another request. Don't immediately retry.
Preload critical icons
Fetch essential icons on page load and cache them. This ensures your UI renders quickly without hitting rate limits during peak usage.

Client-Side Rate Limiting

Implementing your own client-side rate limiter helps you stay within the API limits and avoid 429 errors. Here's a practical implementation that tracks your request count and automatically throttles when approaching the limit.

rate-limiter.js
javascript
1class IconVaultRateLimiter {
2  constructor(maxRequests = 2000, windowMs = 15 * 60 * 1000) {
3    this.maxRequests = maxRequests;
4    this.windowMs = windowMs;
5    this.requests = [];
6  }
7
8  canMakeRequest() {
9    const now = Date.now();
10    // Remove requests outside the current window
11    this.requests = this.requests.filter(time => now - time < this.windowMs);
12    return this.requests.length < this.maxRequests;
13  }
14
15  async waitIfNeeded() {
16    if (this.canMakeRequest()) {
17      this.requests.push(Date.now());
18      return;
19    }
20
21    // Calculate wait time until oldest request expires
22    const oldestRequest = Math.min(...this.requests);
23    const waitTime = this.windowMs - (Date.now() - oldestRequest);
24    console.warn('Rate limit approaching. Waiting ' + Math.ceil(waitTime / 1000) + 's...');
25    await new Promise(resolve => setTimeout(resolve, waitTime + 100));
26    this.requests.push(Date.now());
27  }
28
29  getRemaining() {
30    const now = Date.now();
31    this.requests = this.requests.filter(time => now - time < this.windowMs);
32    return this.maxRequests - this.requests.length;
33  }
34}
35
36const limiter = new IconVaultRateLimiter();
37
38// Usage:
39// await limiter.waitIfNeeded();
40// const res = await fetch('https://iconvault-api.pages.dev/api/icons');
41// console.log('Remaining:', limiter.getRemaining());

Error Handling

Error Codes

The IconVault API uses standard HTTP status codes to indicate the success or failure of requests. Understanding these codes and implementing proper error handling is essential for building robust applications.

200 OK
The request was successful. Response contains the requested data.
400 Bad Request
The request was malformed. Check query parameters for invalid values.
404 Not Found
The requested icon or endpoint does not exist. Check the slug or URL.
429 Rate Limited
You have exceeded the rate limit. Wait and retry after the specified duration.
502 Bad Gateway
Failed to fetch SVG content from the source. Try again later.

Error Response Format

All error responses follow a consistent JSON structure with an error field for the error type and a message field with a human-readable description. Some errors include additional context fields.

json
1{
2  "error": "Icon not found",
3  "message": "No icon found with slug \"nonexistent\". Use the /api/icons endpoint to browse available icons.",
4  "suggestion": "GET /api/icons?search=nonexistent"
5}

Retry Strategies

When errors occur, implementing a proper retry strategy ensures your application remains resilient. Different error types require different handling approaches. Below is a comprehensive error handling implementation with exponential backoff.

error-handler.js
javascript
1async function fetchWithRetry(url, options = {}) {
2  const { maxRetries = 3, baseDelay = 1000, ...fetchOptions } = options;
3  let lastError;
4
5  for (let attempt = 0; attempt <= maxRetries; attempt++) {
6    try {
7      const response = await fetch(url, fetchOptions);
8
9      // Success
10      if (response.ok) return response;
11
12      // Rate limited - respect retry_after
13      if (response.status === 429) {
14        const data = await response.json();
15        const retryAfter = data.retry_after || 60;
16        console.warn('Rate limited. Retrying after ' + retryAfter + 's...');
17        await new Promise(r => setTimeout(r, retryAfter * 1000));
18        continue;
19      }
20
21      // Client errors (400, 404) - don't retry
22      if (response.status >= 400 && response.status < 500) {
23        const data = await response.json();
24        throw new Error(response.status + ': ' + (data.message || data.error));
25      }
26
27      // Server errors (500+) - retry with backoff
28      if (response.status >= 500) {
29        throw new Error('Server error: ' + response.status);
30      }
31    } catch (error) {
32      lastError = error;
33
34      if (attempt < maxRetries) {
35        const delay = baseDelay * Math.pow(2, attempt); // Exponential backoff
36        console.warn('Attempt ' + (attempt + 1) + ' failed. Retrying in ' + delay + 'ms...');
37        await new Promise(r => setTimeout(r, delay));
38      }
39    }
40  }
41
42  throw lastError;
43}
44
45// Usage:
46// const res = await fetchWithRetry('https://iconvault-api.pages.dev/api/icons/Discord');
47// const data = await res.json();

Icon Variants

Variant Types

Each icon in IconVault may be available in multiple variants to suit different design contexts. Understanding the available variants and when to use each one helps you create consistent, professional-looking interfaces. Not all icons have all variants — check the available_variants field in the API response.

standard
The default icon variant. Full-color brand logo suitable for most use cases. This is what you get when no variant is specified.
dark
Dark-themed variant optimized for light backgrounds. Uses darker colors and is ideal for light-mode interfaces and white backgrounds.
light
Light-themed variant optimized for dark backgrounds. Uses lighter or white colors, perfect for dark-mode interfaces and dark backgrounds.
wordmark
Brand logo with the company/product name included. Useful for hero sections, sponsor displays, or when the brand name needs to be visible alongside the icon.

Requesting Specific Variants

You can request a specific variant using the variant query parameter on the icon detail endpoint. If the requested variant is not available, the API automatically falls back to the standard variant.

bash
1# Request standard variant (default)
2curl "https://iconvault-api.pages.dev/api/icons/Discord"
3
4# Request dark variant
5curl "https://iconvault-api.pages.dev/api/icons/Anthropic?variant=dark"
6
7# Request wordmark variant as raw SVG
8curl "https://iconvault-api.pages.dev/api/icons/Claude_AI?variant=wordmark_dark&format=svg"
9
10# Filter icons list to only those with dark variants
11curl "https://iconvault-api.pages.dev/api/icons?variant=dark"

Fallback Strategies

Since not all icons have all variants, implementing a fallback strategy ensures your UI always displays an icon. The API automatically falls back to the standard variant, but you may want additional client-side fallbacks for a better user experience.

variant-fallback.js
javascript
1async function getIconWithFallback(slug, preferredVariant = 'standard') {
2  try {
3    const res = await fetch(
4      'https://iconvault-api.pages.dev/api/icons/' + slug + '?variant=' + preferredVariant
5    );
6
7    if (!res.ok) throw new Error('Icon not found');
8
9    const data = await res.json();
10
11    // Check if we got the preferred variant or a fallback
12    if (data.data.requested_variant !== data.data.selected_variant?.variant) {
13      console.info(
14        'Variant "' + preferredVariant + '" not available for ' + slug + ', ' +
15        'using "' + data.data.selected_variant?.variant + '" instead.'
16      );
17    }
18
19    return data;
20  } catch (error) {
21    console.error('Failed to load icon ' + slug + ':', error);
22    return null;
23  }
24}
25
26// Progressive variant loading: try dark -> standard -> first available
27async function getBestVariant(slug, preferredOrder = ['dark', 'standard']) {
28  const res = await fetch('https://iconvault-api.pages.dev/api/icons/' + slug);
29  const data = await res.json();
30
31  for (const variant of preferredOrder) {
32    const found = data.data.available_variants.find(
33      v => v.variant === variant
34    );
35    if (found) return found;
36  }
37
38  // Fall back to first available
39  return data.data.available_variants[0] || null;
40}

SDK & Libraries

SDK Wrapper

Creating a simple SDK wrapper around the IconVault API gives you a clean, typed interface for your application. Below is a comprehensive TypeScript SDK that handles all endpoints, caching, rate limiting, and error handling. You can use this as a starting point and extend it for your specific needs.

iconvault-sdk.ts
typescript
1interface IconVaultConfig {
2  baseUrl?: string;
3  timeout?: number;
4  cacheTTL?: number;
5}
6
7interface PaginationParams {
8  page?: number;
9  limit?: number;
10}
11
12interface IconListParams extends PaginationParams {
13  category?: string;
14  variant?: string;
15  search?: string;
16}
17
18class IconVaultSDK {
19  private baseUrl: string;
20  private timeout: number;
21  private cacheTTL: number;
22  private cache: Map<string, { data: any; timestamp: number }>;
23
24  constructor(config: IconVaultConfig = {}) {
25    this.baseUrl = config.baseUrl || 'https://iconvault-api.pages.dev/api';
26    this.timeout = config.timeout || 10000;
27    this.cacheTTL = config.cacheTTL || 86400000; // 24 hours
28    this.cache = new Map();
29  }
30
31  private async request<T>(endpoint: string, useCache = true): Promise<T> {
32    const url = this.baseUrl + endpoint;
33    const cacheKey = url;
34
35    // Check cache
36    if (useCache) {
37      const cached = this.cache.get(cacheKey);
38      if (cached && Date.now() - cached.timestamp < this.cacheTTL) {
39        return cached.data as T;
40      }
41    }
42
43    const controller = new AbortController();
44    const timeoutId = setTimeout(() => controller.abort(), this.timeout);
45
46    try {
47      const res = await fetch(url, { signal: controller.signal });
48
49      if (!res.ok) {
50        const error = await res.json().catch(() => ({ message: 'Request failed' }));
51        throw new Error('[' + res.status + '] ' + (error.message || error.error));
52      }
53
54      const data = await res.json();
55
56      // Cache the response
57      if (useCache) {
58        this.cache.set(cacheKey, { data, timestamp: Date.now() });
59      }
60
61      return data as T;
62    } finally {
63      clearTimeout(timeoutId);
64    }
65  }
66
67  async getRoot() {
68    return this.request<{ success: boolean; message: string }>('');
69  }
70
71  async getIcons(params: IconListParams = {}) {
72    const query = new URLSearchParams(
73      Object.entries(params).filter(([_, v]) => v != null).map(([k, v]) => [k, String(v)])
74    ).toString();
75    return this.request('/icons?' + query);
76  }
77
78  async getIcon(slug: string, variant = 'standard') {
79    return this.request('/icons/' + slug + '?variant=' + variant);
80  }
81
82  async getIconSvg(slug: string, variant = 'standard') {
83    const url = this.baseUrl + '/icons/' + slug + '?variant=' + variant + '&format=svg';
84    const res = await fetch(url);
85    if (!res.ok) throw new Error('Failed to fetch SVG');
86    return res.text();
87  }
88
89  async searchIcons(query: string) {
90    return this.request('/icons/search?q=' + encodeURIComponent(query));
91  }
92
93  async getCategories() {
94    return this.request('/categories');
95  }
96
97  async getStats() {
98    return this.request('/stats');
99  }
100
101  clearCache() {
102    this.cache.clear();
103  }
104}
105
106// Usage:
107// const vault = new IconVaultSDK();
108// const icons = await vault.getIcons({ category: 'Social', limit: 10 });
109// const svg = await vault.getIconSvg('Discord');
110// const results = await vault.searchIcons('react');

Caching Middleware

For server-side applications, a more sophisticated caching layer using a proper cache storage mechanism can dramatically reduce API calls and improve response times. Here's an example of a caching middleware that can be used with the SDK.

cache-middleware.ts
typescript
1interface CacheEntry<T> {
2  data: T;
3  expiresAt: number;
4}
5
6class IconVaultCache {
7  private store: Map<string, CacheEntry<any>>;
8  private defaultTTL: number;
9
10  constructor(defaultTTL = 86400000) { // 24 hours default
11    this.store = new Map();
12    this.defaultTTL = defaultTTL;
13  }
14
15  set<T>(key: string, data: T, ttl?: number): void {
16    this.store.set(key, {
17      data,
18      expiresAt: Date.now() + (ttl || this.defaultTTL),
19    });
20  }
21
22  get<T>(key: string): T | null {
23    const entry = this.store.get(key);
24    if (!entry) return null;
25    if (Date.now() > entry.expiresAt) {
26      this.store.delete(key);
27      return null;
28    }
29    return entry.data as T;
30  }
31
32  has(key: string): boolean {
33    return this.get(key) !== null;
34  }
35
36  invalidate(pattern?: string): void {
37    if (!pattern) {
38      this.store.clear();
39      return;
40    }
41    for (const key of this.store.keys()) {
42      if (key.includes(pattern)) this.store.delete(key);
43    }
44  }
45
46  stats() {
47    let valid = 0;
48    const now = Date.now();
49    for (const entry of this.store.values()) {
50      if (now <= entry.expiresAt) valid++;
51    }
52    return { total: this.store.size, valid };
53  }
54}
55
56// Usage with SDK:
57// const cache = new IconVaultCache();
58// const cacheKey = 'icons:' + category + ':' + page + ':' + limit;
59// let data = cache.get(cacheKey);
60// if (!data) {
61//   data = await sdk.getIcons({ category, page, limit });
62//   cache.set(cacheKey, data);
63// }

React Hook for Icons

A custom React hook provides a clean API for using IconVault in React applications with built-in loading states, error handling, and caching. This hook uses TanStack Query (React Query) for optimal caching and background refetching.

useIconVault.ts
tsx
1import { useQuery } from '@tanstack/react-query';
2
3// Hook for fetching a single icon's SVG
4export function useIcon(slug: string, variant = 'standard') {
5  return useQuery({
6    queryKey: ['icon', slug, variant],
7    queryFn: async () => {
8      const res = await fetch(
9        'https://iconvault-api.pages.dev/api/icons/' + slug + '?variant=' + variant + '&format=svg'
10      );
11      if (!res.ok) throw new Error('Icon not found');
12      return res.text();
13    },
14    staleTime: 24 * 60 * 60 * 1000, // 24 hours
15    gcTime: 48 * 60 * 60 * 1000, // 48 hours
16    enabled: !!slug,
17  });
18}
19
20// Hook for searching icons
21export function useIconSearch(query: string) {
22  return useQuery({
23    queryKey: ['iconSearch', query],
24    queryFn: async () => {
25      const res = await fetch(
26        'https://iconvault-api.pages.dev/api/icons/search?q=' + encodeURIComponent(query)
27      );
28      if (!res.ok) throw new Error('Search failed');
29      return res.json();
30    },
31    enabled: query.length >= 2,
32    staleTime: 5 * 60 * 1000, // 5 minutes
33  });
34}
35
36// Hook for listing icons with filters
37export function useIcons(params: {
38  page?: number; limit?: number; category?: string; variant?: string;
39}) {
40  return useQuery({
41    queryKey: ['icons', params],
42    queryFn: async () => {
43      const searchParams = new URLSearchParams(
44        Object.entries(params).filter(([_, v]) => v != null).map(([k, v]) => [k, String(v)])
45      );
46      const res = await fetch('https://iconvault-api.pages.dev/api/icons?' + searchParams);
47      if (!res.ok) throw new Error('Failed to fetch icons');
48      return res.json();
49    },
50    staleTime: 10 * 60 * 1000,
51  });
52}
53
54// Usage in component:
55// const { data: svg, isLoading } = useIcon('Discord');
56// const { data: results } = useIconSearch('react');
57// const { data: icons } = useIcons({ category: 'Social', limit: 10 });

Best Practices

Performance Optimization

Optimizing how you load and display icons can significantly improve your application's performance. Here are the key strategies for getting the best performance from IconVault, from reducing network requests to minimizing render blocking.

1
Lazy load icons below the fold
Use the loading="lazy" attribute on img tags or implement Intersection Observer to fetch icons only when they become visible in the viewport. This is especially important for pages with many icons.
2
Preload critical icons
Use link rel="preload" for icons that appear above the fold to ensure they load as quickly as possible. This eliminates the delay before the browser discovers the icon resource.
3
Use SVG sprites for frequently-used icons
Combine multiple icons into a single SVG sprite sheet and reference them with the use element. This reduces HTTP requests to a single request for all icons.
4
Minimize API calls with bulk requests
Use the list endpoint with larger page sizes instead of making individual requests for each icon. A single request with limit=100 is far more efficient than 100 individual requests.
performance.html
html
1<!-- Preload critical icons -->
2<link rel="preload" href="https://iconvault-api.pages.dev/icons/React.svg" as="image" type="image/svg+xml" />
3
4<!-- Lazy load below-fold icons -->
5<img src="https://iconvault-api.pages.dev/icons/Discord.svg" alt="Discord"
6     width="32" height="32" loading="lazy" />
7
8<!-- Intersection Observer for dynamic loading -->
9<script>
10const observer = new IntersectionObserver((entries) => {
11  entries.forEach(entry => {
12    if (entry.isIntersecting) {
13      const slug = entry.target.dataset.icon;
14      loadIcon(slug, entry.target);
15      observer.unobserve(entry.target);
16    }
17  });
18}, { rootMargin: '50px' });
19
20document.querySelectorAll('[data-icon]').forEach(el => observer.observe(el));
21</script>
22
23<div data-icon="Docker" class="icon-placeholder"></div>

Caching Strategies

Implementing a proper caching strategy is the single most impactful optimization you can make when working with the IconVault API. Icons rarely change, making them ideal candidates for aggressive caching at multiple levels of your application stack.

Browser Cache
Leverage browser caching with proper Cache-Control headers. SVG responses include max-age=86400 (24 hours). Use Service Workers for offline capability.
CDN Cache
If using a CDN like Cloudflare or Vercel, configure caching rules for /icons/ paths. Set a long TTL since icons are immutable between versions.
Application Cache
Implement in-memory or persistent caching in your application. Cache icon metadata and SVG content with 24-hour TTLs and stale-while-revalidate patterns.

Accessibility

Icons should be accessible to all users, including those using screen readers or assistive technologies. When using IconVault icons, follow these accessibility best practices to ensure your icons are perceivable, operable, and understandable by everyone.

accessibility.html
html
1<!-- Decorative icons: hide from screen readers -->
2<img src="https://iconvault-api.pages.dev/icons/React.svg" alt=""
3     width="32" height="32" role="presentation" />
4
5<!-- Meaningful icons: provide descriptive alt text -->
6<img src="https://iconvault-api.pages.dev/icons/Discord.svg"
7     alt="Join our Discord community"
8     width="32" height="32" />
9
10<!-- Inline SVG with accessibility -->
11<div role="img" aria-label="Docker containerization platform">
12  <!-- SVG content here -->
13</div>
14
15<!-- Icon with visible text label (recommended) -->
16<button class="flex items-center gap-2">
17  <img src="https://iconvault-api.pages.dev/icons/GitHub.svg" alt="" width="20" height="20" />
18  <span>View on GitHub</span>
19</button>
20
21<!-- Icon-only buttons: use aria-label -->
22<button aria-label="Share on Twitter">
23  <img src="https://iconvault-api.pages.dev/icons/X.svg" alt="" width="24" height="24" />
24</button>

SEO Optimization

When using icons on public-facing pages, proper implementation can improve SEO performance. Search engines can interpret icon usage as signals about your technology stack, partnerships, and content relevance.

Use semantic alt text
For icons that convey meaning, use descriptive alt text like "Built with React" rather than just "React icon". This helps search engines understand the context.
Implement structured data
Use Schema.org markup to describe your technology stack or partnerships. The SoftwareApplication schema can reference technologies using their icons.
Optimize icon delivery
Serve icons from the same domain when possible, or ensure CDN URLs are crawlable. Fast-loading icons contribute to Core Web Vitals scores.
Use proper image dimensions
Always specify width and height attributes to prevent layout shifts (CLS). This improves your Core Web Vitals score which is an SEO ranking factor.

Changelog

Stay up to date with the latest changes to the IconVault API. We follow semantic versioning, and all breaking changes will be communicated through this changelog.

v1.0.0Initial Release
Version 1.0.0

The inaugural release of the IconVault API. This version ships with 429+ SVG icons across 278 brands and 11 categories, complete with a RESTful API, rate limiting, multiple icon variants, and comprehensive documentation. Built by Xbibz Official using the icon-svg repository as the icon source.

Added
  • GET /api — Root endpoint with API information
  • GET /api/icons — List icons with pagination, search, and category filtering
  • GET /api/icons/{slug} — Get specific icon details with variant and format support
  • GET /api/icons/search — Search icons by name, slug, or category
  • GET /api/categories — List all categories with brand and icon counts
  • GET /api/stats — API statistics and rate limit information
  • Rate limiting: 2,000 requests per IP per 15-minute window
  • X-RateLimit headers on all responses
  • SVG format output via format=svg parameter
  • Multiple icon variants: standard, dark, light, wordmark
  • Edge Runtime compatibility for Cloudflare Pages deployment

Frequently Asked Questions

Common questions about the IconVault API. Can't find what you're looking for? Check the GitHub repository for issues and discussions.

Is IconVault API free to use?

Yes, IconVault API is completely free. There are no paid plans, API keys, or usage fees. The only limitation is the rate limit of 2,000 requests per IP per 15-minute window, which is generous enough for most production applications. If you need higher limits, consider implementing aggressive caching or hosting the API yourself.

Do I need an API key?

No, IconVault API does not require any authentication. You can start making requests immediately without signing up or generating API keys. Rate limiting is enforced per IP address rather than per API key.

How often are new icons added?

Icons are sourced from the XbibzModder777/icon-svg repository. New icons are added periodically as the source repository is updated. Check the /api/stats endpoint for the current total icon count. When new icons are added, they become immediately available through the API.

Can I use these icons in commercial projects?

The icons are brand logos and trademarks owned by their respective companies. Usage in commercial projects typically falls under fair use for purposes like showing technology stacks, integrations, or partnerships. However, you should review each brand's specific trademark guidelines. IconVault provides the icons as a service but does not grant trademark licenses.

What happens when I hit the rate limit?

When you exceed 2,000 requests in a 15-minute window, the API returns a 429 Too Many Requests response with a retry_after field indicating how many seconds to wait. Your access automatically resumes when the window resets. Implementing client-side caching and checking X-RateLimit-Remaining headers will help you avoid hitting the limit.

Can I request raw SVG content?

Yes! Add format=svg to any icon detail endpoint to receive the raw SVG content with proper Content-Type headers. This is useful for inline embedding, server-side processing, or custom styling. Example: /api/icons/Discord?format=svg

Why is an icon slug case-sensitive in the URL?

Slugs are actually case-insensitive. The API normalizes slug matching so "/api/icons/discord" and "/api/icons/Discord" both work. However, some slugs contain underscores (e.g., "Amazon_Web_Services") so you may need to URL-encode them or use the search endpoint to find the exact slug.

Can I self-host IconVault?

Yes! The IconVault API is open source and available on GitHub at XbibzModder777/icon-svg. You can clone the repository, install dependencies, and run it locally or deploy it to your own infrastructure. This removes rate limits and gives you full control over the service.

What variants are available for each icon?

Variant availability varies by icon. Common variants include: standard (default), dark (for light backgrounds), light (for dark backgrounds), and wordmark (logo with brand name). Check the available_variants field in the API response for each specific icon. Not all icons have all variants.

How do I handle icons that don't have my preferred variant?

The API automatically falls back to the standard variant when a requested variant isn't available. You can also check the available_variants array in the response and implement your own fallback logic on the client side. See the Icon Variants section for detailed fallback strategies.