{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/theholisticcare/json-schema/theholisticcare-resource-list-response-schema.json",
  "title": "ResourceListResponse",
  "x-generated": "2026-10-29",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/theholisticcare-resources-api-openapi.yml#/components/schemas/ResourceListResponse",
  "type": "object",
  "properties": {
    "data": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/Resource"
      }
    },
    "pagination": {
      "$ref": "#/$defs/Pagination"
    },
    "meta": {
      "$ref": "#/$defs/Meta"
    }
  },
  "$defs": {
    "Meta": {
      "type": "object",
      "description": "Present on every successful response.",
      "properties": {
        "generated_at": {
          "type": "string",
          "format": "date-time"
        },
        "provider": {
          "type": "string"
        },
        "source": {
          "type": "string"
        }
      }
    },
    "Pagination": {
      "type": "object",
      "properties": {
        "limit": {
          "type": "integer"
        },
        "offset": {
          "type": "integer"
        },
        "total": {
          "type": "integer"
        }
      }
    },
    "Resource": {
      "type": "object",
      "description": "The common normalized shape used by /v1/resources and /v1/search across all 6 families. Fields not applicable to a given resource's type are null rather than fabricated. `id` is populated for every resource, using each family's existing stable public identifier where one already exists (mindfulness_game uses its `MG-*` api_id, guided_practice uses its `SL-*` track_id, panchavikas_* uses its `PV-*` id), or a deterministic `type:slug` pair otherwise (e.g. `blog:<slug>`, `research:<slug>`, `glossary:<slug>`) — never a raw Sanity `_id`. `slug` is populated for every type except panchavikas_pathway/panchavikas_download, which have no real slug field and are always null there. A blog-type resource still always has `category` set to null (unlike id/slug, which changed 2026-09-25 — see HANDOFF.md), matching the fact that blog posts have no equivalent taxonomy field exposed elsewhere in this API. Note this Resource shape (used only by /v1/resources and /v1/search) is intentionally richer than the dedicated /v1/blog endpoint's own response, which still omits id/slug/type/updated_at entirely per Mohan's original instruction for that endpoint specifically.\n",
      "properties": {
        "id": {
          "type": "string"
        },
        "title": {
          "type": "string"
        },
        "slug": {
          "type": [
            "string",
            "null"
          ]
        },
        "type": {
          "type": "string",
          "enum": [
            "blog",
            "mindfulness_game",
            "guided_practice",
            "research",
            "glossary",
            "panchavikas_pathway",
            "panchavikas_download"
          ]
        },
        "summary": {
          "type": [
            "string",
            "null"
          ]
        },
        "category": {
          "type": [
            "string",
            "null"
          ]
        },
        "tags": {
          "type": [
            "array",
            "null"
          ],
          "items": {
            "type": "string"
          }
        },
        "audiences": {
          "type": [
            "array",
            "null"
          ],
          "items": {
            "type": "string"
          }
        },
        "age_min": {
          "type": [
            "integer",
            "null"
          ]
        },
        "age_max": {
          "type": [
            "integer",
            "null"
          ]
        },
        "duration_minutes": {
          "type": [
            "integer",
            "null"
          ]
        },
        "skills": {
          "type": [
            "array",
            "null"
          ],
          "items": {
            "type": "string"
          }
        },
        "access": {
          "type": [
            "string",
            "null"
          ],
          "description": "e.g. \"free\". Never \"paid\" — no paid content is ever exposed by this API."
        },
        "source_url": {
          "type": "string"
        },
        "updated_at": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time"
        }
      }
    }
  }
}