# Mooncakes Public API Audit

Audit date: 2026-08-21 (Asia/Shanghai)

All checks used unauthenticated HTTPS requests. No credential was sent or
stored.

## Endpoint results

| Request | Status | Content type | Observed schema / behavior |
| --- | ---: | --- | --- |
| `GET https://mooncakes.io/api/v0/modules` | 200 | `application/json` | JSON array; 2,062 module rows; response size 620,675 bytes |
| `GET https://mooncakes.io/api/v0/modules/statistics` | 200 | `application/json` | Object with `total_modules`, `total_packages`, `total_lines`, `total_downloads` |
| `GET https://mooncakes.io/api/v0/manifest/moonbitlang/parser` | 200 | `application/json` | Manifest envelope containing latest metadata, downloads, build status and versions |
| `GET .../manifest/not-a-real-owner/not-a-real-module` | 404 | `application/json` | `{"detail":"Package not found"}` |

Observed statistics sample:

```json
{
  "total_modules": 2062,
  "total_packages": 18872,
  "total_lines": 28543625,
  "total_downloads": 5909240
}
```

Observed module-row shape:

```json
{
  "name": "moonbitlang/parser",
  "version": "0.3.17",
  "license": "Apache-2.0",
  "repository": "https://github.com/moonbitlang/parser",
  "keywords": ["parser", "lexer", "AST", "MoonBit"],
  "description": "AST and parsers for the MoonBit programming language",
  "is_new": false,
  "created_at": "..."
}
```

Observed manifest dependency excerpt:

```json
{
  "name": "moonbitlang/parser",
  "version": "0.3.17",
  "metadata": {
    "deps": {
      "moonbitlang/x": "0.4.39",
      "moonbitlang/lexer": "0.3.15",
      "moonbitlang/moon_config": "0.3.14",
      "moonbitlang/async": "0.20.3",
      "moonbit-community/prettyprinter": "0.4.10"
    }
  }
}
```

## Dependency representation

Across all 2,062 live manifests, `metadata.deps` was either absent or a JSON
object. It was present in 1,058 manifests and non-empty in 989.

Dependency keys normally use `owner/module`. Values were:

- 2,511 strings, normally version constraints;
- 5 objects: two `{alias, version}` records and three `{path}` records.

Four dependency keys used `Yoorkin/example/list`, a three-segment coordinate
that does not resolve to a registry module. Raw values and source manifests are
retained in the snapshot rather than normalized away.

The registry itself contains two case-insensitive coordinate collisions:
`xunyoyo/permutation` / `xunyoyo/Permutation` and
`youyong5/moontetris` / `youyong5/MoonTetris`. Snapshot and graph processing
must therefore treat coordinates as case-sensitive strings.

## Pagination

The endpoint returned the full 2,062-row array for all of:

- `/modules?limit=2`
- `/modules?page=2&limit=2`
- `/modules?offset=2&limit=2`

The first two rows and response length were unchanged. No working pagination
contract was observed; consumers must currently accept the full registry
response.

## Rate and reliability behavior

- A 20-request sequential probe of the parser manifest returned 20 HTTP 200
  responses and no 429.
- Latency in that probe: minimum 884 ms, maximum 2,855 ms, mean 1,137.2 ms.
- Staged ingestion used 4 workers for 100 and 500 modules, then 8 workers only
  after both stages achieved 100% success.
- Full result: 2,062 successful manifest requests, 0 recorded failures.
- The PoC supports timeout, exponential retry, per-coordinate cache, resume,
  and failure preservation.

This is evidence of current practical stability, not a promise of an official
rate limit or availability SLA. No rate-limit headers or pagination contract
were inferred where none was observed.

## Missing metadata

In the registry module list:

- empty repository: 314
- empty license: 14
- empty description: 355
- empty keywords: 479

These gaps do not prevent dependency-graph construction because dependency
edges come from manifest metadata, but they constrain any optional correlation
analysis involving repository, license, description, or keywords.
