# Agent API

> Run the security headers and email security checks over HTTP, with or without an API key, and handle rate limits, quotas and errors.

Source: https://docs.vigilbase.com/tools/developers/agent-api

The Agent API runs the two non-intrusive tools, [Security headers](https://docs.vigilbase.com/tools/security-headers) and [Email security](https://docs.vigilbase.com/tools/email-security), over HTTP. It needs no Turnstile check and no email verification, and works without an API key. All paths are on `https://vigilbase.com`.

## Endpoints

| Method and path | Purpose |
| --- | --- |
| `GET /api/v1/agent/tools` | The tool catalog, auth options and current rate limits |
| `POST /api/v1/agent/tools/security-headers/execute` | Grade a URL's HTTP security headers |
| `POST /api/v1/agent/tools/email-security/execute` | Grade a domain's email authentication records |

Other tools are not on this API. `website-security`, `react2shell` and `fortibleed-check` run in the browser with email verification, or through Vigilbase One with a signed-in [CLI](https://docs.vigilbase.com/tools/cli/install-and-sign-in). Asking for them returns `404` with a message that says so.

## Run a check

Send a JSON body with one field, `target`, for example `{"target":"https://example.com"}`. For `security-headers` it is a URL or domain (`https://` is assumed when you leave out the scheme); for `email-security` it is a domain.

```exchange
POST /api/v1/agent/tools/security-headers/execute HTTP/1.1
Host: vigilbase.com
Content-Type: application/json

HTTP/1.1 200 OK
Content-Type: application/json
API-Version: 1
RateLimit-Limit: 10
RateLimit-Remaining: 9
```

A successful response looks like this:

```json
{
  "success": true,
  "apiVersion": "1",
  "toolName": "security-headers",
  "target": "https://example.com",
  "grade": "B",
  "gradeScore": 72,
  "result": { "status": "warnings", "message": "...", "details": { } },
  "error": null,
  "uiUrl": "https://vigilbase.com/tools/security-headers",
  "skillUrl": "https://vigilbase.com/agent-skills/security-headers.md"
}
```

`result` holds the full scan result, in the same shape the tool page uses. The body may be at most 8 KiB and `target` at most 2,048 characters.

:::code-group
```bash filename=curl
curl -sS -X POST https://vigilbase.com/api/v1/agent/tools/email-security/execute \
  -H 'content-type: application/json' \
  -d '{"target":"example.com"}'
```

```ts filename=fetch.ts
const response = await fetch(
  "https://vigilbase.com/api/v1/agent/tools/email-security/execute",
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ target: "example.com" }),
  },
);
const data = (await response.json()) as { success: boolean; grade: string | null };
```
:::

## Authentication

You can call the API anonymously, or send a developer API key to raise the rate limit. Put the key in either header:

```http
Authorization: Bearer <api_key>
X-Api-Key: <api_key>
```

An invalid or expired key returns `401`; it does not fall back to anonymous access. Create keys in Vigilbase One; see [API keys](https://docs.vigilbase.com/tools/developers/api-keys).

## Rate limits and quotas

Two limits apply.

| Limit | Anonymous | With an API key |
| --- | --- | --- |
| Requests per minute | 10, per client IP | 30, per key |
| Scans per hour | 20 per client IP and 20 per target, 1,000 overall | Same |

The scan quota is shared with the browser tools and counts the same way with or without a key. `GET /api/v1/agent/tools` returns both limits in its `rateLimit` field.

Every response carries rate limit headers: `RateLimit`, `RateLimit-Policy`, `RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset` and the `X-RateLimit-*` equivalents.

When a limit is used up, the API returns `429` with code `rate_limit_exceeded`, a `Retry-After` header and `retryAfterSec` in the body. Wait that many seconds before trying again. A spent scan quota can mean a wait of up to an hour, and no scan ran.

## Errors

Errors use `application/problem+json`:

```json
{
  "success": false,
  "error": { "code": "rate_limit_exceeded", "message": "...", "hint": "..." },
  "type": "https://vigilbase.com/developers/errors/rate-limit-exceeded",
  "title": "Rate Limit Exceeded",
  "status": 429,
  "detail": "...",
  "code": "rate_limit_exceeded",
  "retryAfterSec": 1800
}
```

| Status | Code | Meaning |
| --- | --- | --- |
| 400 | `bad_request` | Invalid JSON, or a missing or invalid `target` |
| 401 | `unauthorized` | Invalid or expired API key |
| 403 | `forbidden` | The key lacks the scope this endpoint needs (`tools:read` or `tools:execute`) |
| 404 | `not_found` | The tool is unknown or not on this API |
| 413 | `payload_too_large` | The body is over 8 KiB |
| 422 | `unprocessable_entity` | The scan ran but could not assess the target, for example because of a bot challenge; `grade` is `null` and `result` explains why |
| 429 | `rate_limit_exceeded` | A rate limit or the scan quota is used up |
| 503 | `service_unavailable` | Scan storage is down and no scan ran; retry after `Retry-After` (30 seconds) |

## Versioning

Responses carry `API-Version: 1`. The older unversioned paths under `/api/agent/tools` still work but send `Deprecation` and `Sunset` headers; they are due to be retired on 1 September 2027. Use the `/api/v1/` paths.

## Reference

See the [API reference](https://docs.vigilbase.com/tools/developers/api-reference) for every field, or fetch the OpenAPI document at `https://vigilbase.com/openapi.json`.
