# Install Safe API documentation

> Developer and agent documentation for Install Safe: the OpenAPI specification, the public dependency-scanner API, the JSON error format, registry configuration, and every machine-readable file this site publishes.

Human version: https://installsafe.io/docs

## Machine-readable resources

- [OpenAPI specification](https://installsafe.io/openapi.json) — `application/json`. OpenAPI 3.1 description of the public API. Generated from the same module the route handlers are checked against.
- [API catalog](https://installsafe.io/.well-known/api-catalog) — `application/linkset+json`. RFC 9727 linkset naming the API description, its documentation and its metadata.
- [llms.txt](https://installsafe.io/llms.txt) — `text/markdown`. Short orientation file (llmstxt.org): what the product is, how it works, what it costs.
- [llms-full.txt](https://installsafe.io/llms-full.txt) — `text/markdown`. Everything in llms.txt plus the complete FAQ, for agents that prefer one fetch.
- [pricing.md](https://installsafe.io/pricing.md) — `text/markdown`. Plans, prices and billing questions as markdown, for a buying agent that will not render a page.
- [security.txt](https://installsafe.io/.well-known/security.txt) — `text/plain`. RFC 9116 contact details for reporting a vulnerability.
- [Sitemap](https://installsafe.io/sitemap.xml) — `application/xml`. Indexable pages served by this app. The blog has its own at /blog/sitemap.xml.
- [robots.txt](https://installsafe.io/robots.txt) — `text/plain`. Crawl rules, including the explicitly named AI search crawlers that are allowed.

## Public API

One endpoint on this host is public and unauthenticated: `POST https://installsafe.io/api/scan`. It takes the text of a `package.json`, `package-lock.json`, `pnpm-lock.yaml` or `bun.lock` and returns every known vulnerability or malware advisory affecting the exact versions it names. Nothing about the manifest is stored or logged.

Rate limit: 10 scans per IP per 10 minutes. Maximum body: 8 MB.

```bash
curl -sS https://installsafe.io/api/scan \
  -H 'content-type: application/json' \
  -d '{"manifest": "{\"dependencies\":{\"lodash\":\"4.17.20\"}}"}'
```

The request and response schemas are in the OpenAPI document at https://installsafe.io/openapi.json; that file is the authority, not this paragraph.

Everything else under `/api/` is session-scoped product surface — it answers to a signed-in browser, is disallowed in robots.txt, and is deliberately absent from the OpenAPI document.

## Errors

Every machine-facing error is JSON, never an HTML page. The envelope is:

```json
{
  "error": "Provide a \"manifest\" string.",
  "code": "invalid_request",
  "hint": "POST {\"manifest\": \"<file text>\"} with content-type: application/json.",
  "docs": "https://installsafe.io/docs"
}
```

`error` is a sentence for a human, `code` is the stable identifier to branch on, `hint` says what to do differently, `docs` points here.

| Code | HTTP | Meaning |
| --- | --- | --- |
| `invalid_request` | 400 | The body is not JSON, or a required field is missing or the wrong type. |
| `unauthorized` | 401 | No valid session or registry token was presented. |
| `forbidden` | 403 | Authenticated, but not allowed to do this. |
| `not_found` | 404 | No such endpoint, or no such record. |
| `method_not_allowed` | 405 | Wrong HTTP method. The Allow header lists the right ones. |
| `payload_too_large` | 413 | The manifest exceeded 8 MB. |
| `rate_limited` | 429 | Too many requests from this IP. Wait and retry. |
| `internal_error` | 500 | A fault on our side. Safe to retry once. |
| `upstream_unavailable` | 503 | Advisory data could not be reached. Retry shortly. |

## Content negotiation

Every indexable page on this site has a markdown twin. Send `Accept: text/markdown` and you get markdown at the same URL, with `Vary: Accept` on the response:

```bash
curl -H 'Accept: text/markdown' https://installsafe.io/pricing
```

An unknown path asked for in markdown answers `404` with a markdown body pointing at the sitemap and this page, so a wrong URL is recoverable without parsing HTML. A client whose `Accept` header names nothing this site can serve gets `406`.

## Registry configuration

The product itself is an npm registry proxy, not an HTTP API — you point a package manager at it rather than calling it. It requires a registry token, so setup is two lines:

```bash
npm config set registry https://r.installsafe.io
npm config set //r.installsafe.io/:_authToken <your-token>
```

Create a token in the dashboard at https://installsafe.io/dashboard/tokens. yarn, pnpm and bun read the same `.npmrc`, or take the equivalent settings in their own config. Requests without a valid token are refused with `401` and a message naming this page.
