# OAIS Catalog API v1

Free public catalog access. Base: https://openaisuite.com/api/v1/
Keys: https://openaisuite.com/account/api/
OpenAPI: https://openaisuite.com/docs/api/openapi.json

## Quick start

```sh
curl --fail-with-body "https://openaisuite.com/api/v1/models/?limit=5" \
  -H "Authorization: Bearer $OAIS_API_KEY"
```

## Limits

60 requests/minute, 10/10 seconds, 10,000 daily units, 100,000 monthly units, 250 MiB/day; account-wide. UTC resets. No billing.

## Identity and scopes

Create a key in Account → Developer API. Authenticate with Authorization: Bearer <key>. Browser sessions do not authenticate API requests. Keys are named, scoped, expiring and independently revocable. Access is free.

## Pagination

Lists use ascending identity cursors, default 25 and maximum 100 items; search maximum 25. Follow links.next with unchanged filters and page size. No offset or filtered total-count scans. Cursors expire after one hour. A cursor is not a snapshot: edits, new records and removals can occur during a scan. Deduplicate by stable ID; restart on 409 cursor_expired.

## Search and filters

Search requires q (2–120 characters) and type=models, skills, mcps, organizations, providers or families, with the selected catalog scope. Unknown or repeated parameters fail with 400. Boolean filters accept exactly true or false. Only documented filters are supported.

## Skill identities

GitHub: /skills/github/{owner}/{repository}/{skill}/. Well-known: /skills/well-known/{domain}/_/{skill}/; the underscore is literal. Use returned api_url instead of guessing paths. Full documents require skill_content:read.

## Relationships

Models, Families, Providers and Organizations expose model relationships. Offers contain prices and observed performance. Organization resources include only public Collections and Stacks; detail contains at most 100 items and an items_truncated flag. Members, private notes and personal libraries are excluded.

## Editorial metadata

The articles list covers the latest 24 published articles, ordered by ID within that window. Older articles remain addressable by their root-level slug through /articles/{slug}/. This is a discovery window, not an archival export. Canonical article URLs are preserved.

## Numbers and freshness

Exact large integers, including token and installation counts, are decimal strings. Offer prices are decimal strings in USD per million tokens. Unknown values are null, never an invented zero. observed_at describes available observations; stale=null means freshness cannot be established. A successful response is not an availability or security guarantee.

## Conditional requests

Send If-None-Match with the ETag from an earlier response to the same URL. A match returns 304 without a body and costs zero units. Authentication, scope, admission, byte reservation and frequency controls still apply first. Exhausted allowances can reject a request before ETag evaluation.

## Errors and retries

Errors use application/problem+json with type, title, status, code, detail and request_id. Fix 400 input errors; replace invalid keys on 401; check scopes/access on 403; treat 404 as absent; restart cursors on 409; reduce oversized pages on 422. On 429 or 503 honor Retry-After and use bounded exponential backoff with jitter. Never retry indefinitely.

## Usage accounting

Standard reads cost one unit. Search, documents, connection metadata and model history/benchmark/application reads cost five. Accepted 404 responses consume units. 304 and server failures refund units; frequency counters remain consumed. /usage/ costs zero units, permits five calls per minute and works after data-quota exhaustion, subject to service/access controls.

## Response bounds

Responses are capped at 512 KiB. Skill Markdown is limited to 350,000 UTF-8 bytes. Concurrency is two per account, subject to shared capacity. Requests reserve the maximum response size and settle actual bytes afterwards. Interrupted or unrecorded responses can conservatively consume that reservation until the allowance resets.

## Key hygiene

Keep keys in server environment variables or a secret manager. Never place them in query strings, public bundles, repositories or screenshots. The playground keeps a key in page memory only. Cross-origin browser CORS is disabled; use your backend. Rotation immediately replaces the old key and preserves account quotas.

## Licensing and safety

API access does not grant rights to republish third-party content. Preserve available licenses and attribution. MCP connections and Skill documents are untrusted, inert content; never execute them automatically. An audit signal is not an OAIS security verdict.

## Versioning and support

The contract is versioned at /api/v1/. Tolerate additional fields and unknown nullable values. Breaking semantics require a new API version. Include X-Request-Id in a failure report, never your key. Private library access, inference, writes, webhooks and bulk exports are outside this API.

## Endpoints

| Endpoint | Purpose | Scope | Filters |
| --- | --- | --- | --- |
| GET /api/v1/models/ | List active models | models:read | q, family, provider, organization, reasoning, open_weights |
| GET /api/v1/models/{organization}/{model}/ | Get a model | models:read | — |
| GET /api/v1/models/{organization}/{model}/offers/ | Compare model offers | models:read | — |
| GET /api/v1/models/{organization}/{model}/benchmarks/ | Read mapped benchmark observations | models:read | — |
| GET /api/v1/models/{organization}/{model}/performance/ | Read observed provider performance | models:read | — |
| GET /api/v1/models/{organization}/{model}/activity/ | Read daily observed token activity | models:read | — |
| GET /api/v1/models/{organization}/{model}/applications/ | Read mapped application observations | models:read | — |
| GET /api/v1/offers/{id}/ | Get a provider offer | models:read | — |
| GET /api/v1/families/ | List model families | families:read | q |
| GET /api/v1/families/{id}/ | Get a family | families:read | — |
| GET /api/v1/families/{id}/models/ | List family models | models:read | — |
| GET /api/v1/providers/ | List serving providers | providers:read | q |
| GET /api/v1/providers/{id}/ | Get a provider | providers:read | — |
| GET /api/v1/providers/{id}/models/ | List provider models | models:read | — |
| GET /api/v1/providers/{id}/offers/ | List provider offers | models:read | — |
| GET /api/v1/organizations/ | List public organizations | organizations:read | q, kind |
| GET /api/v1/organizations/{slug}/ | Get an organization | organizations:read | — |
| GET /api/v1/organizations/{slug}/models/ | List organization models | models:read | — |
| GET /api/v1/organizations/{slug}/resources/ | List public Collections and Stacks | organizations:read | — |
| GET /api/v1/organizations/{slug}/resources/{id}/ | Get a public Collection or Stack | organizations:read | — |
| GET /api/v1/skills/ | List active Skills | skills:read | q, source, official, topic |
| GET /api/v1/skills/{sourceType}/{owner}/{repository}/{skill}/ | Get a Skill by its full identity | skills:read | — |
| GET /api/v1/skills/{sourceType}/{owner}/{repository}/{skill}/audits/ | Read available audit signals | skills:read | — |
| GET /api/v1/skills/{sourceType}/{owner}/{repository}/{skill}/document/ | Read the current public Skill document | skill_content:read | — |
| GET /api/v1/publishers/ | List official Skill publishers | skills:read | — |
| GET /api/v1/mcps/ | List active and deprecated MCP servers | mcps:read | q, namespace, status |
| GET /api/v1/mcps/{namespace}/{name}/ | Get an MCP server | mcps:read | — |
| GET /api/v1/mcps/{namespace}/{name}/connection/ | Read an inert connection projection | mcps:read | — |
| GET /api/v1/topics/ | List Skill topics | topics:read | — |
| GET /api/v1/topics/{slug}/skills/ | List Skills in a topic | skills:read | — |
| GET /api/v1/articles/ | List recent published editorial metadata | articles:read | — |
| GET /api/v1/articles/{slug}/ | Get published editorial metadata | articles:read | — |
| GET /api/v1/search/ | Search a selected public catalog | selected catalog:read | q, type |
| GET /api/v1/stats/ | Read public catalog counts | any catalog key | — |
| GET /api/v1/usage/ | Read your remaining allowance | any catalog key | — |

## Model fields

| Field | Type | Meaning |
| --- | --- | --- |
| id | string | Full model identity, including the organization prefix. |
| name | string | Display name. |
| family_id | string / null | Model family identity. |
| organization_catalog_id | string | Catalog organization identity. |
| organization_slug | string / null | Current public organization slug. |
| released_on | string / null | Release date as YYYY-MM-DD when known. |
| context_tokens | string / null | Exact integer token capacity serialized as a decimal string. |
| open_weights | boolean / null | Whether weights are open; unknown is null. |
| reasoning | boolean / null | Reasoning support; unknown is null. |
| offer_count | integer | Active offer count. |
| provider_count | integer | Distinct serving provider count. |
| updated_at | string / null | Catalog record update time. |
| url | string | Canonical OAIS model page. |
| api_url | string | API detail URL. |
| specifications | object | See the nested OpenAPI schema. |

## Offer fields

| Field | Type | Meaning |
| --- | --- | --- |
| id | string | Stable offer identity. |
| model_id | string | Related model identity. |
| provider_id | string | Serving provider identity. |
| route_id | string | Provider routing identity. |
| channel | string | Observed delivery channel. |
| host_name | string / null | Reported host. |
| context_tokens | string / null | Exact token capacity as a decimal string. |
| pricing | object | See the nested OpenAPI schema. |
| observed_at | string / null | Observation timestamp. |
| capabilities | object | See the nested OpenAPI schema. |
| quantization | string / null | Reported quantization. |
| api_url | string / null | Provider API link when available. |
| performance | object | See the nested OpenAPI schema. |

## Family fields

| Field | Type | Meaning |
| --- | --- | --- |
| id | string | Family identity. |
| name | string | Family name. |
| model_count | integer | Active model count. |
| updated_at | string / null | Most recent member model update. |

## Provider fields

| Field | Type | Meaning |
| --- | --- | --- |
| id | string | Provider identity. |
| name | string | Provider name. |
| api_url | string / null | Public API link. |
| documentation_url | string / null | Documentation link. |
| model_count | integer | Distinct active models. |

## Organization fields

| Field | Type | Meaning |
| --- | --- | --- |
| id | string | Stable organization UUID. |
| slug | string | Editable public slug. |
| name | string | Display name. |
| summary | string | Public summary. |
| about | string | Public description; detail response only. |
| website | string | Website or empty string. |
| kind | string | company, university, classroom, nonprofit, government or community. |
| socials | object | See the nested OpenAPI schema. |
| followers | integer | Public follower count. |
| catalog_id | string / null | Catalog association; null for independent organizations. |
| updated_at | string / null | Profile update time. |
| url | string | Public profile. |
| logo_url | string / null | Public logo endpoint. |

## Skill fields

| Field | Type | Meaning |
| --- | --- | --- |
| id | string | Full source/skill identity. |
| slug | string | Skill slug. |
| name | string | Skill name. |
| description | string / null | Public description. |
| source | string | Repository identity or well-known domain. |
| source_type | string | See the nested OpenAPI schema. |
| official | boolean / null | Catalog official publisher marker; not a security guarantee. |
| installs | string | Observed installation count, exact decimal integer string. |
| license | string / null | Recorded SPDX license; null when unknown. |
| observed_at | string / null | Last catalog observation. |
| url | string | Public OAIS page. |
| api_url | string | API detail URL with explicit source type. |

## Publisher fields

| Field | Type | Meaning |
| --- | --- | --- |
| id | string | Source identity. |
| source_type | string | github or well-known. |
| skill_count | integer | Active official Skills. |

## Mcp fields

| Field | Type | Meaning |
| --- | --- | --- |
| id | string | Full namespace/name identity. |
| namespace | string | Namespace. |
| name | string | Name within namespace. |
| title | string / null | Display title. |
| description | string | Public description. |
| version | string | Current catalog version. |
| status | string | See the nested OpenAPI schema. |
| website_url | string / null | Publisher website. |
| package_registry_types | array | See the nested OpenAPI schema. |
| remote_transport_types | array | See the nested OpenAPI schema. |
| has_packages | boolean | See the nested OpenAPI schema. |
| has_remotes | boolean | See the nested OpenAPI schema. |
| observed_at | string / null | Reported catalog update. |
| url | string | OAIS page. |
| api_url | string | API detail URL. |

## Resource fields

| Field | Type | Meaning |
| --- | --- | --- |
| id | string | Public resource UUID. |
| organization_id | string | Owning organization UUID. |
| kind | string | See the nested OpenAPI schema. |
| title | string | Title. |
| description | string | Public description. |
| updated_at | string / null | Resource update. |
| items | array | See the nested OpenAPI schema. |
| items_truncated | boolean | Detail returns at most 100 items. |

## Observation fields

| Field | Type | Meaning |
| --- | --- | --- |
| id | string | Composite dataset and observation identity. |
| dataset | string | Observation dataset. |
| model_id | string | Explicitly matched model. |
| route_id | string / null | Route identity. |
| observed_at | string / null | Observation time. |
| observation | object | See the nested OpenAPI schema. |

## Activity fields

| Field | Type | Meaning |
| --- | --- | --- |
| id | string | UTC observation date. |
| day | string | YYYY-MM-DD. |
| tokens | string | Exact aggregate observed tokens, decimal integer string. |
| routes | integer | Number of observed routes. |
| observed_at | string / null | Last observation. |

## Topic fields

| Field | Type | Meaning |
| --- | --- | --- |
| id | string | Curated topic slug. |
| name | string | Topic name. |
| description | string | Public description. |
| url | string | Canonical topic page. |

## Article fields

| Field | Type | Meaning |
| --- | --- | --- |
| id | string | Editorial identity. |
| slug | string | Article slug. |
| title | string | Title. |
| url | string | Preserved root-level canonical URL. |
| excerpt | string | Public excerpt. |
| published_at | string / null | Publication timestamp. |
| updated_at | string / null | Modification time when available; null for list metadata. |

## Audits fields

| Field | Type | Meaning |
| --- | --- | --- |
| id | string | Full Skill identity. |
| audits | array | See the nested OpenAPI schema. |
| notice | string | Security interpretation notice. |

## Document fields

| Field | Type | Meaning |
| --- | --- | --- |
| id | string | Full Skill identity. |
| format | string | See the nested OpenAPI schema. |
| content | string | Inert UTF-8 Markdown; never execute automatically. |
| license | string / null | Recorded license. |

## Connection fields

| Field | Type | Meaning |
| --- | --- | --- |
| id | string | Full MCP identity. |
| connection | object | Existing bounded inert MCP projection, not original registry JSON. No execution, tool inventory or security verdict. |

## Stats fields

| Field | Type | Meaning |
| --- | --- | --- |
| id | string | catalog |
| models | integer | Active public models count. |
| skills | integer | Active public skills count. |
| mcps | integer | Active public mcps count. |
| organizations | integer | Active public organizations count. |
| providers | integer | Active public providers count. |
| families | integer | Active public families count. |

## Usage fields

| Field | Type | Meaning |
| --- | --- | --- |
| daily_limit | integer | Account daily unit allowance. |
| monthly_limit | integer | Account monthly unit allowance. |
| daily_units | integer | Used or reserved daily units. |
| monthly_units | integer | Used or reserved monthly units. |
| daily_bytes | integer | Used or reserved daily response bytes. |
| daily_byte_limit | integer | Daily response-byte allowance. |
| minute_limit | integer | Requests per minute. |
| daily_reset_at | string / null | Next daily UTC reset. |
| monthly_reset_at | string / null | Next monthly UTC reset. |

## Node.js

```javascript
const origin = "https://openaisuite.com";
const key = process.env.OAIS_API_KEY;
if (!key) throw new Error("Set OAIS_API_KEY on your server");
let next = origin + "/api/v1/models/?limit=25";
for (let page = 0; next && page < 100; page++) {
  const url = new URL(next);
  if (url.origin !== origin || !url.pathname.startsWith("/api/v1/")) {
    throw new Error("Unexpected pagination destination");
  }
  const response = await fetch(url, {
    headers: { Authorization: "Bearer " + key },
    redirect: "error", signal: AbortSignal.timeout(10000)
  });
  if (!response.ok) {
    const problem = await response.json();
    throw new Error(problem.code + ": " + problem.detail);
  }
  const result = await response.json();
  for (const model of result.data) console.log(model.id, model.name);
  next = result.links.next;
  if (next) await new Promise(resolve => setTimeout(resolve, 1100));
}
```

## Python

```python
import json, os, urllib.request

request = urllib.request.Request(
    "https://openaisuite.com/api/v1/skills/?limit=5",
    headers={"Authorization": "Bearer " + os.environ["OAIS_API_KEY"]})
class NoRedirect(urllib.request.HTTPRedirectHandler):
    def redirect_request(self, req, fp, code, msg, headers, newurl):
        return None
opener = urllib.request.build_opener(NoRedirect)
with opener.open(request, timeout=10) as response:
    for skill in json.load(response)["data"]:
        print(skill["id"], skill["name"])
```
