The Index Public API

Public, read-only API listing every active index in theindex.fyi. Responses follow JSON:API 1.1 (`application/vnd.api+json`) and include filterable / paginated collection endpoints plus single- resource lookups by slug. Rate-limited to 60 requests / minute per IP, with standard `X-RateLimit-*` and `Retry-After` headers.

The Index Public API is published by The Index on the APIs.io network, described by a machine-readable OpenAPI specification.

Tagged areas include Indexes, Curated Directories, RSS Aggregators, Search Engines, and Random Discovery. The published artifact set on APIs.io includes API documentation and an OpenAPI specification.

OpenAPI Specification

the-index-fyi-openapi.yml Raw ↑
openapi: 3.1.0

info:
  title: theindex.fyi
  version: '1.0'
  description: |
    A public, read-only API for theindex.fyi — a maintained meta-index of indie web
    and small web index sites.

    All responses follow the [JSON:API 1.1](https://jsonapi.org/) specification and use
    the `application/vnd.api+json` content type.

    **Rate limiting:** 60 requests per minute per IP. Responses include `X-RateLimit-Limit`,
    `X-RateLimit-Remaining`, and `Retry-After` headers.

    **Versioning:** The API is currently unversioned. If a breaking change is ever necessary,
    versioning will be introduced via an `API-Version` request header rather than URL prefixes.
  contact:
    url: https://theindex.fyi/about

servers:
  - url: https://theindex.fyi/api
    description: Production

tags:
  - name: Indexes
    description: Approved indie web and small web index sites.

paths:

  /indexes:
    get:
      operationId: listIndexes
      summary: List indexes
      description: Returns a paginated, filterable list of all active indexes.
      tags: [Indexes]
      parameters:
        - $ref: '#/components/parameters/FilterCategory'
        - $ref: '#/components/parameters/FilterLanguage'
        - $ref: '#/components/parameters/PageNumber'
        - $ref: '#/components/parameters/PageSize'
      responses:
        '200':
          description: A paginated collection of index resources.
          content:
            application/vnd.api+json:
              schema:
                $ref: '#/components/schemas/IndexCollection'
              example:
                data:
                  - type: indexes
                    id: '1'
                    attributes:
                      name: ooh.directory
                      slug: ooh-directory
                      url: https://ooh.directory
                      description: A curated directory of personal websites and blogs.
                      category: curated_directories
                      language: null
                      accepts_submissions: true
                      last_checked_at: '2026-05-01T12:00:00Z'
                    links:
                      self: https://theindex.fyi/api/indexes/ooh-directory
                meta:
                  total: 84
                  per_page: 25
                  current_page: 1
                  last_page: 4
                links:
                  self: https://theindex.fyi/api/indexes?page[number]=1
                  first: https://theindex.fyi/api/indexes?page[number]=1
                  last: https://theindex.fyi/api/indexes?page[number]=4
                  prev: null
                  next: https://theindex.fyi/api/indexes?page[number]=2
        '429':
          $ref: '#/components/responses/TooManyRequests'

  /indexes/{slug}:
    get:
      operationId: getIndex
      summary: Get an index
      description: Returns a single index by its slug.
      tags: [Indexes]
      parameters:
        - name: slug
          in: path
          required: true
          description: The unique slug of the index.
          schema:
            type: string
          example: ooh-directory
      responses:
        '200':
          description: A single index resource.
          content:
            application/vnd.api+json:
              schema:
                $ref: '#/components/schemas/IndexResource'
              example:
                data:
                  type: indexes
                  id: '1'
                  attributes:
                    name: ooh.directory
                    slug: ooh-directory
                    url: https://ooh.directory
                    description: A curated directory of personal websites and blogs.
                    category: curated_directories
                    language: null
                    accepts_submissions: true
                    last_checked_at: '2026-05-01T12:00:00Z'
                  links:
                    self: https://theindex.fyi/api/indexes/ooh-directory
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'

components:

  parameters:

    FilterCategory:
      name: filter[category]
      in: query
      required: false
      description: Filter indexes by category.
      schema:
        type: string
        enum:
          - curated_directories
          - rss_feed_aggregators
          - search_engines
          - random_discovery
          - constraint_based_clubs
          - indieweb_infrastructure
      example: curated_directories

    FilterLanguage:
      name: filter[language]
      in: query
      required: false
      description: Filter by ISO 639-1 language code. Omit to return all languages.
      schema:
        type: string
        minLength: 2
        maxLength: 2
      example: es

    PageNumber:
      name: page[number]
      in: query
      required: false
      description: Page number (1-based).
      schema:
        type: integer
        minimum: 1
        default: 1

    PageSize:
      name: page[size]
      in: query
      required: false
      description: Number of results per page. Maximum 100.
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 25

  schemas:

    IndexAttributes:
      type: object
      required:
        - name
        - slug
        - url
        - description
        - category
        - accepts_submissions
      properties:
        name:
          type: string
          description: Display name of the index.
          example: ooh.directory
        slug:
          type: string
          description: URL-safe unique identifier.
          example: ooh-directory
        url:
          type: string
          format: uri
          description: The index's URL.
          example: https://ooh.directory
        description:
          type: string
          description: One-sentence description of what the index is and who it's for.
          example: A curated directory of personal websites and blogs.
        category:
          type: string
          description: The category this index belongs to.
          enum:
            - curated_directories
            - rss_feed_aggregators
            - search_engines
            - random_discovery
            - constraint_based_clubs
            - indieweb_infrastructure
          example: curated_directories
        language:
          type: ['string', 'null']
          description: ISO 639-1 language code of the index's primary language. Null if English or unknown.
          example: es
        accepts_submissions:
          type: boolean
          description: Whether this index accepts submissions from the public.
          example: true
        last_checked_at:
          type: ['string', 'null']
          format: date-time
          description: When the link was last verified as live.
          example: '2026-05-01T12:00:00Z'

    IndexResourceObject:
      type: object
      required: [type, id, attributes, links]
      properties:
        type:
          type: string
          enum: [indexes]
        id:
          type: string
          description: Unique numeric ID as a string, per JSON:API spec.
          example: '1'
        attributes:
          $ref: '#/components/schemas/IndexAttributes'
        links:
          type: object
          required: [self]
          properties:
            self:
              type: string
              format: uri
              example: https://theindex.fyi/api/indexes/ooh-directory

    IndexResource:
      type: object
      required: [data]
      properties:
        data:
          $ref: '#/components/schemas/IndexResourceObject'

    IndexCollection:
      type: object
      required: [data, meta, links]
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/IndexResourceObject'
        meta:
          type: object
          required: [total, per_page, current_page, last_page]
          properties:
            total:
              type: integer
              description: Total number of matching indexes across all pages.
              example: 84
            per_page:
              type: integer
              example: 25
            current_page:
              type: integer
              example: 1
            last_page:
              type: integer
              example: 4
        links:
          type: object
          required: [self, first, last]
          properties:
            self:
              type: string
              format: uri
            first:
              type: string
              format: uri
            last:
              type: string
              format: uri
            prev:
              type: ['string', 'null']
              format: uri
            next:
              type: ['string', 'null']
              format: uri

    ErrorObject:
      type: object
      required: [status, title]
      properties:
        status:
          type: string
          description: HTTP status code as a string.
          example: '404'
        title:
          type: string
          description: Short, human-readable summary of the problem.
          example: Not Found
        detail:
          type: string
          description: Human-readable explanation specific to this occurrence.
          example: No index exists with the slug "not-a-real-index".

    ErrorDocument:
      type: object
      required: [errors]
      properties:
        errors:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/ErrorObject'

  responses:

    NotFound:
      description: The requested resource does not exist.
      content:
        application/vnd.api+json:
          schema:
            $ref: '#/components/schemas/ErrorDocument'
          example:
            errors:
              - status: '404'
                title: Not Found
                detail: No index exists with the slug "not-a-real-index".

    TooManyRequests:
      description: Rate limit exceeded. Wait for the `Retry-After` period before retrying.
      headers:
        Retry-After:
          description: Seconds until the rate limit resets.
          schema:
            type: integer
          example: 42
        X-RateLimit-Limit:
          description: Maximum requests allowed per minute.
          schema:
            type: integer
          example: 60
        X-RateLimit-Remaining:
          description: Requests remaining in the current window.
          schema:
            type: integer
          example: 0
      content:
        application/vnd.api+json:
          schema:
            $ref: '#/components/schemas/ErrorDocument'
          example:
            errors:
              - status: '429'
                title: Too Many Requests
                detail: Rate limit of 60 requests per minute exceeded. Please slow down.