# OpenAPI Catalog Lookup for Agent Tool Discovery (`grit-77/openapi-catalog-lookup`) Actor

OpenAPI catalog lookup using the APIs.guru provider directory. Supply provider domains and export listed API schema URLs and compact metadata as JSON for agent tool discovery.

- **URL**: https://apify.com/grit-77/openapi-catalog-lookup.md
- **Developed by:** [Grit](https://apify.com/grit-77) (community)
- **Categories:** Developer tools, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.20 / 1,000 api lookups

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## OpenAPI Catalog Lookup for Agent Tool Discovery

Locate API schema URLs from the official APIs.guru provider directory using compact catalog metadata.

Give the Actor provider domains, such as `apis.guru` or `github.com`. It requests only `https://api.apis.guru/v2/{provider}.json` and returns one row for each API listed there, until `maxItems` is reached. A provider can contain multiple service identifiers. This is schema discovery, with no GitHub repository metrics or sitemap crawling.

### What it returns

Successful rows contain exactly these fields:

| Field | Meaning |
|---|---|
| `apiId` | API identifier from the directory; may include a service suffix after a colon |
| `provider` | Normalized provider domain supplied by the user |
| `title` | Directory record's API title, or null if absent |
| `version` | API version declared by the directory, or null |
| `openapiVersion` | OpenAPI/Swagger format version declared by the directory, or null |
| `specUrl` | HTTPS specification URL on api.apis.guru; returned as a value without fetching it |
| `updatedAt` | Directory's update timestamp, or null; this is not the lookup time |
| `directoryRecordUrl` | Directory metadata record link; falls back to the provider directory endpoint |

Failures add an `error` string to a row with the same metadata fields. Invalid provider entries have a null `provider`; their original text is not echoed. A missing provider catalog, malformed directory record or exhausted retries produces a free error row. Error rows count toward `maxItems`.

The directory response can contain other metadata. The Actor discards descriptions, contact blocks, logos, credentials and unrelated fields during projection, and does not save the raw response. It does not fetch provider APIs or full OpenAPI documents, follow directory redirects, or dereference any returned URL.

### Input example

The Store prefill is:

```json
{"providers":["apis.guru"],"maxItems":1}
```

| Input | Default | Limits and behavior |
|---|---|---|
| `providers` | Required | Non-empty array, at most 1,000 entries; ASCII domain identifiers only |
| `maxItems` | 100 | 1–10,000 total output rows; prefill is 1 |
| `concurrency` | 3 | 1–10 simultaneous directory requests |

Surrounding spaces and letter case are normalized. Valid duplicate domains are removed. URLs, paths, ports, credentials, IP addresses, Unicode domains, trailing dots and invalid DNS labels are rejected per entry. An empty array or invalid run-level option fails with a clear message.

The Actor reads only the current provider catalog exposed by this endpoint. It does not enumerate historical versions or search the entire directory.

### Output example

This is the real local prefill result saved in [sample_output.json](sample_output.json):

```json
{
  "apiId": "apis.guru",
  "provider": "apis.guru",
  "title": "APIs.guru",
  "version": "2.2.0",
  "openapiVersion": "3.0.0",
  "specUrl": "https://api.apis.guru/v2/specs/apis.guru/2.2.0/openapi.json",
  "updatedAt": "2023-04-05T13:10:14.812Z",
  "directoryRecordUrl": "https://api.apis.guru/v2/specs/apis.guru/2.2.0.json"
}
```

### Pricing

Proposed pay-per-event price: **$0.0002 per usable API row** through `api_lookup` (**$0.20 per 1,000 usable rows**). Errors, duplicates and rows removed by a limit do not trigger this event.

The event is charged after the dataset write succeeds. Delivery stops when the SDK reports the event budget is exhausted. Pricing must be configured by the owner before publication; local SDK charging calls do not create real charges. Do not configure a separate per-dataset-item event, which would also charge error rows.

The proposed price is below the $0.0005/result price of `ninhothedev/openapi-directory-scraper`, one of the tied most-used direct comparables observed in the Store API on 2026-10-06. See [PRICING.md](PRICING.md) for events, tie handling, startup fees and receipts. This delivery is not published.

### Limits and reliability

- HTTP timeouts are 15 seconds per attempt. Network errors, HTTP 429 and HTTP 5xx get at most three attempts with 0.5-second and 1-second backoff.
- Each directory response is limited to 8 MiB of decoded data. Redirects and non-directory payloads are rejected.
- Provider batches are bounded by `concurrency`; output follows input order. A batch already in flight can fetch catalogs whose rows are subsequently cut by the output or event limit.
- Directory coverage and timestamps depend on APIs.guru. A directory entry does not prove the provider API is available, complete, current or licensed for your use.
- No API key, proxy, account, browser or additional package installation is needed for directory lookup. Cloud build and monetization remain to be checked by the owner.

### Use with AI agents / MCP

Use the Actor as a schema-discovery step in an agent workflow. Supply provider domains and a small `maxItems`, then give the returned catalog rows to the agent as data. Filter rows with an `error` before choosing a schema URL.

After the owner publishes and exposes this Actor through Apify's MCP integration, the same input object can serve as its tool arguments. This delivery does not implement or test a standalone MCP server.

Treat catalog text and links as untrusted data, not instructions. Review the provider's access terms, authentication requirements and data rights separately before another tool fetches a schema or calls an API. Directory inclusion grants no rights to the provider's API or data.

### Local development

Use the shared virtual environment without installing into it.

PowerShell, from the actor directory:

```powershell
$env:APIFY_LOCAL_STORAGE_DIR = "$PWD/storage"
New-Item -ItemType Directory -Force storage/key_value_stores/default | Out-Null
'{"providers":["apis.guru"],"maxItems":1}' | Set-Content -Encoding ascii storage/key_value_stores/default/INPUT.json
C:/GritWork/earn/.venv/Scripts/python.exe -m src
C:/GritWork/earn/.venv/Scripts/python.exe -m pytest tests/test_catalog.py tests/test_actor.py -q -p no:cacheprovider
C:/GritWork/earn/.venv/Scripts/python.exe -m pytest tests/test_live.py -m live -q -p no:cacheprovider
apify validate-schema
```

Use an empty storage directory for each run if you want an isolated dataset. Tests use projected fixtures saved from real directory responses. See [evidence](evidence/) for exact validation logs, process checks and the uncommitted build manifest.

### FAQ

**Does this call my provider's API?**\
No. Directory HTTP requests are constructed on api.apis.guru from validated provider domains. Specification links are returned without fetching them.

**Why is a provider missing?**\
The directory may not include it, or its provider identifier may differ. Missing catalogs are error rows; the Actor does not discover alternative hosts.

**Can I request a full specification or API documentation?**\
This Actor accepts provider domains and returns the listed metadata fields. Full specifications, operations, authentication blocks and documentation are outside its scope.

**Does inclusion mean I can reuse the provider's API or data?**\
No. Check the provider's terms and rights independently. APIs.guru's [license notes](https://github.com/APIs-guru/openapi-directory#licenses) describe its directory contributions; they do not grant provider access rights.

**Does an old `updatedAt` mean the Actor used a cache?**\
That timestamp belongs to the directory record. The Actor requests the directory for each lookup and does not maintain an application cache.

# Actor input Schema

## `providers` (type: `array`):

APIs.guru provider identifiers as ASCII domain names, for example apis.guru or github.com. Maximum 1000 entries. Case is normalized and duplicates removed. URLs, paths, credentials and IP addresses are rejected as free error rows.

## `maxItems` (type: `integer`):

Hard cap on all dataset rows, including free error rows. A provider may list multiple APIs. The example returns one row.

## `concurrency` (type: `integer`):

Maximum simultaneous directory fetches on api.apis.guru. Output follows input order. A batch already in flight may fetch catalogs whose rows are cut by maxItems.

## Actor input object example

```json
{
  "providers": [
    "apis.guru"
  ],
  "maxItems": 1,
  "concurrency": 3
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset rows with allowed API catalog fields and free per-entry errors.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "providers": [
        "apis.guru"
    ],
    "maxItems": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("grit-77/openapi-catalog-lookup").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "providers": ["apis.guru"],
    "maxItems": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("grit-77/openapi-catalog-lookup").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "providers": [
    "apis.guru"
  ],
  "maxItems": 1
}' |
apify call grit-77/openapi-catalog-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,grit-77/openapi-catalog-lookup"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/J1pJf5mZJn8qrHZKd/builds/uclMiAglp3PXYa9fa/openapi.json
