{"openapi":"3.1.0","info":{"title":"ModelLens Public API","version":"v1","description":"Agent-friendly REST API for discovering AI models across providers with filtering, pagination, and stable JSON responses."},"servers":[{"url":"https://modellens.pages.dev"}],"tags":[{"name":"Discovery","description":"Entry points and machine-readable API metadata."},{"name":"Models","description":"Model discovery endpoints."},{"name":"Providers","description":"Provider summary endpoints."},{"name":"Stats","description":"Aggregate statistics endpoints."}],"paths":{"/api/v1":{"get":{"tags":["Discovery"],"summary":"Discover the public API","description":"Returns a human-friendly API index with endpoint descriptions, parameters, and example URLs.","responses":{"200":{"description":"API index","content":{"application/json":{"example":{"data":{"name":"ModelLens Public API","version":"v1","description":"Agent-friendly REST API for discovering AI models across providers with filtering, pagination, and stable JSON responses.","base_url":"https://modellens.pages.dev/api/v1","openapi_url":"https://modellens.pages.dev/api/v1/openapi.json","markdown_url":"https://modellens.pages.dev/api/v1/README.md","resource_types":["models","providers","stats"],"endpoints":[{"name":"markdown_docs","method":"GET","url":"https://modellens.pages.dev/api/v1/README.md","description":"Raw Markdown documentation for agents and lightweight clients."},{"name":"list_models","method":"GET","url":"https://modellens.pages.dev/api/v1/models","description":"List models with filtering, sorting, and pagination.","query_parameters":{"page":{"type":"integer","default":1,"minimum":1},"limit":{"type":"integer","default":50,"minimum":1,"maximum":100},"provider":{"type":"string","format":"comma-separated","allowed_values":["openai","anthropic","deepseek","google","mistral","groq","together"]},"type":{"type":"string","format":"comma-separated","allowed_values":["chat","embedding","image","audio","video"]},"status":{"type":"string","format":"comma-separated","allowed_values":["active","deprecated","unlisted"]},"search":{"type":"string","description":"Substring match against id, provider, name, and description."},"sort":{"type":"string","default":"updated","allowed_values":["updated","name","provider"]},"order":{"type":"string","default":"desc","allowed_values":["asc","desc"]}},"examples":["https://modellens.pages.dev/api/v1/models?provider=openai&limit=10","https://modellens.pages.dev/api/v1/models?provider=anthropic,google&type=chat&status=active","https://modellens.pages.dev/api/v1/models?search=vision&sort=name&order=asc&limit=25"]},{"name":"get_model","method":"GET","url_template":"https://modellens.pages.dev/api/v1/models/{provider}/{model_id}","description":"Fetch a single model by provider and model id returned by list_models.","path_parameters":{"provider":{"type":"string","allowed_values":["openai","anthropic","deepseek","google","mistral","groq","together"]},"model_id":{"type":"string"}},"example":"https://modellens.pages.dev/api/v1/models/{provider}/{model_id}"},{"name":"list_providers","method":"GET","url":"https://modellens.pages.dev/api/v1/providers","description":"List providers with model counts."},{"name":"get_stats","method":"GET","url":"https://modellens.pages.dev/api/v1/stats","description":"Get aggregate model counts by provider, type, and status."}],"response_shapes":{"collection":{"data":"array","meta":{"total":"integer","page":"integer","limit":"integer","pages":"integer"}},"single_resource":{"data":"object"},"error":{"error":{"code":"string","message":"string"}}}}}}}}}}},"/api/v1/README.md":{"get":{"tags":["Discovery"],"summary":"Get Markdown API documentation","description":"Returns agent-friendly Markdown documentation for the public API.","responses":{"200":{"description":"Markdown documentation","content":{"text/markdown":{"example":"# ModelLens Public API\n\nAgent-friendly REST API for discovering AI models across providers with filtering, pagination, and stable JSON responses.\n\n- Version: v1\n- Base URL: https://modellens.pages.dev/api/v1\n- Discovery JSON: https://modellens.pages.dev/api/v1\n- OpenAPI: https://modellens.pages.dev/api/v1/openapi.json\n- Markdown: https://modellens.pages.dev/api/v1/README.md\n\n## When to use this API\n\nUse this public API for coding agents, scripts, SDK generation, and external integrations.\nThe website's internal endpoints are separate and are not the public contract.\n\n## Recommended agent flow\n\n1. Call `https://modellens.pages.dev/api/v1` to discover available endpoints and filter values.\n2. Call `https://modellens.pages.dev/api/v1/models?provider=<provider>&limit=<n>` to list candidate models.\n3. Read `https://modellens.pages.dev/api/v1/models/{provider}/{model_id}` for one exact model when needed.\n4. Use `https://modellens.pages.dev/api/v1/openapi.json` if your tooling prefers OpenAPI.\n\n## Supported filter values\n\n- Providers: openai, anthropic, deepseek, google, mistral, groq, together\n- Types: chat, embedding, image, audio, video\n- Statuses: active, deprecated, unlisted\n- Sort fields: updated, name, provider\n- Sort orders: asc, desc\n\n## markdown_docs\n\n- Method: GET\n- URL: https://modellens.pages.dev/api/v1/README.md\n- Description: Raw Markdown documentation for agents and lightweight clients.\n\n## list_models\n\n- Method: GET\n- URL: https://modellens.pages.dev/api/v1/models\n- Description: List models with filtering, sorting, and pagination.\n\n### Query parameters\n\n- `page`: integer; default=1; min=1\n- `limit`: integer; default=50; min=1; max=100\n- `provider`: string; comma-separated; allowed=openai, anthropic, deepseek, google, mistral, groq, together\n- `type`: string; comma-separated; allowed=chat, embedding, image, audio, video\n- `status`: string; comma-separated; allowed=active, deprecated, unlisted\n- `search`: string; Substring match against id, provider, name, and description.\n- `sort`: string; default=updated; allowed=updated, name, provider\n- `order`: string; default=desc; allowed=asc, desc\n\n### Examples\n\n- https://modellens.pages.dev/api/v1/models?provider=openai&limit=10\n- https://modellens.pages.dev/api/v1/models?provider=anthropic,google&type=chat&status=active\n- https://modellens.pages.dev/api/v1/models?search=vision&sort=name&order=asc&limit=25\n\n## get_model\n\n- Method: GET\n- URL template: https://modellens.pages.dev/api/v1/models/{provider}/{model_id}\n- Description: Fetch a single model by provider and model id returned by list_models.\n\n### Path parameters\n\n- `provider`: string; allowed=openai, anthropic, deepseek, google, mistral, groq, together\n- `model_id`: string\n\n### Example\n\n- https://modellens.pages.dev/api/v1/models/{provider}/{model_id}\n\n## list_providers\n\n- Method: GET\n- URL: https://modellens.pages.dev/api/v1/providers\n- Description: List providers with model counts.\n\n## get_stats\n\n- Method: GET\n- URL: https://modellens.pages.dev/api/v1/stats\n- Description: Get aggregate model counts by provider, type, and status.\n\n## Response conventions\n\n- Collection endpoints return `data` and `meta`.\n- Single-resource endpoints return `data`.\n- Errors return `error.code` and `error.message`.\n\n## Notes\n\n- Prefer provider filters and small limits when an agent only needs a narrow set of models.\n- Do not assume specific model ids remain current over time; discover them from `GET https://modellens.pages.dev/api/v1/models`.\n"}}}}}},"/api/v1/models":{"get":{"tags":["Models"],"summary":"List models","description":"Returns models with optional filtering by provider, type, status, and search query.","parameters":[{"name":"page","in":"query","description":"1-based page number.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Results per page. Maximum 100.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"provider","in":"query","description":"Comma-separated provider ids.","schema":{"type":"string","example":"openai,anthropic"}},{"name":"type","in":"query","description":"Comma-separated model types.","schema":{"type":"string","example":"chat,image"}},{"name":"status","in":"query","description":"Comma-separated statuses.","schema":{"type":"string","example":"active,deprecated"}},{"name":"search","in":"query","description":"Substring match against id, provider, name, and description.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Sort field.","schema":{"type":"string","enum":["updated","name","provider"],"default":"updated"}},{"name":"order","in":"query","description":"Sort direction.","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}}],"responses":{"200":{"description":"Paginated model list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelListResponse"}}}},"400":{"description":"Invalid request parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/models/{provider}/{model_id}":{"get":{"tags":["Models"],"summary":"Get a model","description":"Returns a single model for the given provider and model id.","parameters":[{"name":"provider","in":"path","required":true,"description":"Provider id.","schema":{"type":"string","enum":["openai","anthropic","deepseek","google","mistral","groq","together"]}},{"name":"model_id","in":"path","required":true,"description":"Provider-specific model identifier.","schema":{"type":"string"}}],"responses":{"200":{"description":"Single model","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SingleModelResponse"}}}},"400":{"description":"Invalid provider","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Model not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/providers":{"get":{"tags":["Providers"],"summary":"List providers","description":"Returns providers sorted by model count.","responses":{"200":{"description":"Provider summaries","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvidersResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/stats":{"get":{"tags":["Stats"],"summary":"Get model statistics","description":"Returns aggregate counts by provider, type, status, and the last successful sync timestamp.","responses":{"200":{"description":"Aggregate stats","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatsResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"schemas":{"ApiModel":{"type":"object","required":["id","provider","name","description","type","context_length","status","deprecated","updated_at","last_seen_at"],"properties":{"id":{"type":"string"},"provider":{"type":"string","enum":["openai","anthropic","deepseek","google","mistral","groq","together"]},"name":{"type":["string","null"]},"description":{"type":["string","null"]},"type":{"type":"string","enum":["chat","embedding","image","audio","video"]},"context_length":{"type":"string"},"status":{"type":"string","enum":["active","deprecated","unlisted"]},"deprecated":{"type":"boolean"},"updated_at":{"type":"string","format":"date-time"},"last_seen_at":{"type":"string","format":"date-time"}}},"ApiMeta":{"type":"object","required":["total","page","limit","pages"],"properties":{"total":{"type":"integer","minimum":0},"page":{"type":"integer","minimum":1},"limit":{"type":"integer","minimum":1,"maximum":100},"pages":{"type":"integer","minimum":0}}},"ErrorPayload":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"}}},"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"$ref":"#/components/schemas/ErrorPayload"}}},"ModelListResponse":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ApiModel"}},"meta":{"$ref":"#/components/schemas/ApiMeta"}}},"SingleModelResponse":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/ApiModel"}}},"ProviderSummary":{"type":"object","required":["id","name","model_count"],"properties":{"id":{"type":"string","enum":["openai","anthropic","deepseek","google","mistral","groq","together"]},"name":{"type":"string"},"model_count":{"type":"integer","minimum":0}}},"ProvidersResponse":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ProviderSummary"}}}},"StatsPayload":{"type":"object","required":["total_models","by_provider","by_type","by_status","last_sync"],"properties":{"total_models":{"type":"integer","minimum":0},"by_provider":{"type":"object","additionalProperties":{"type":"integer","minimum":0}},"by_type":{"type":"object","additionalProperties":{"type":"integer","minimum":0}},"by_status":{"type":"object","required":["active","deprecated","unlisted"],"properties":{"active":{"type":"integer","minimum":0},"deprecated":{"type":"integer","minimum":0},"unlisted":{"type":"integer","minimum":0}}},"last_sync":{"type":["string","null"],"format":"date-time"}}},"StatsResponse":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/StatsPayload"}}}}}}