# Docs

Resource class for the documentation endpoints. Instantiated internally by the GunSpec client and exposed as `client.docs`.

Source: https://docs.gunspec.io/en/sdk/docs

## client.docs.getOperations()

`GET /v1/docs/operations`

Auth: API key required  
Tier: Explorer+

Look up what the reference documents for an operation: parameters, the plan it needs, caching, every failure with its `error.reason` values, and the languages a sample is printed in.

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `path` | string | yes | The operation's path: a documented template, a concrete path or a full URL. A path that names no operation is matched as a prefix. |
| `method` | string | no | Narrow to one HTTP method. Omitted returns every method the path answers. |

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object | The response payload. |
| `data.matched` | string | `exact` when the path named an operation, `prefix` when it did not and these are the operations under it (at most 25). |
| `data.specVersion` | string | The version of this document the reference was rendered from. |
| `data.operations` | object[] | The matching operations. |
| `data.operations[].method` | string | HTTP method. |
| `data.operations[].path` | string | The documented path template. |
| `data.operations[].title` | string | The operation's title in the reference. |
| `data.operations[].description` | string | What the operation does, as the reference states it. |
| `data.operations[].tier` | string | The lowest plan that may call it: `public`, `account` (a key attached to a user account), `explorer`, `builder`, `studio` or `enterprise`. |
| `data.operations[].auth` | string | Whether a key is `required`, `optional` or not used (`none`). |
| `data.operations[].cacheable` | boolean | Whether it answers `304 Not Modified` to an `If-None-Match` carrying the ETag it sent. |
| `data.operations[].docsUrl` | string | The operation's page in the reference. |
| `data.operations[].parameters` | object[] | Path, query and header parameters, as the reference lists them. |
| `data.operations[].requestBody` | object \| null | The request body, or null for an operation that takes none. |
| `data.operations[].success` | object | What success looks like. |
| `data.operations[].errors` | object[] | Every failure the operation documents. |

```json
{
  "success": true,
  "data": {
    "matched": "exact",
    "specVersion": "1.0.0",
    "operations": [
      {
        "method": "GET",
        "path": "/v1/firearms/{id}",
        "title": "Get Firearm",
        "description": "Returns the full specification of one firearm.",
        "tier": "builder",
        "auth": "required",
        "cacheable": true,
        "docsUrl": "https://docs.gunspec.io/en/api/firearms/get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "type": "string",
            "required": true,
            "description": "Firearm slug",
            "accepts": [
              "string"
            ],
            "default": "20",
            "minimum": 1,
            "maximum": 100
          }
        ],
        "requestBody": {
          "contentType": "application/json",
          "example": "{\"name\": \"Glock 19\"}"
        },
        "success": {
          "status": 200,
          "contentType": "application/json"
        },
        "errors": [
          {
            "status": 404,
            "message": "Not found",
            "code": "NOT_FOUND",
            "reasons": [
              "RESOURCE_NOT_FOUND"
            ]
          }
        ],
        "notes": [
          "string"
        ],
        "sampleLanguages": [
          "python"
        ],
        "sdk": [
          {
            "typescript": "client.firearms.get(id)",
            "python": "client.firearms.get(id: str)"
          }
        ]
      }
    ]
  }
}
```

### Errors

| Status | Code | Message |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Validation error |
| 401 | `UNAUTHORIZED` | API key required |
| 403 | `FORBIDDEN` | Valid key, not permitted |
| 404 | `NOT_FOUND` | Resource not found |
| 429 | `RATE_LIMITED` | Rate limit exceeded |
| 500 | `INTERNAL_ERROR` | Unexpected server error |

### Example

```bash
curl --request GET \
  --url 'https://api.gunspec.io/v1/docs/operations?path=%2Fv1%2Ffirearms%2F%7Bid%7D' \
  --header 'X-API-Key: your_key'
```

## client.docs.getSample()

`GET /v1/docs/samples`

Auth: API key required  
Tier: Explorer+

Get the sample the reference prints for an operation in one language, exactly as printed, with the result of the last run that checked it.

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `path` | string | yes | The operation's path: a documented template, a concrete path or a full URL. |
| `method` | string | no | The HTTP method. Needed only when the path answers more than one. |
| `language` | string | yes | `curl`, `javascript` (TypeScript with `fetch`), `python` (`requests`), `unity`, `unreal`, `godot`, or `sdk-typescript` / `sdk-python` for the SDKs. |

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object | The response payload. |
| `data.method` | string | HTTP method of the operation. |
| `data.path` | string | Its documented path template. |
| `data.tier` | string | The lowest plan that may call it. |
| `data.docsUrl` | string | The operation's page in the reference. |
| `data.language` | string | The language asked for. |
| `data.keyNote` | string \| null | How to fill in the key placeholder, or null for an operation that takes no key. |
| `data.samples` | object[] | One sample, or one per SDK method for an operation more than one method calls. |
| `data.samples[].label` | string | What the sample is: the tab name, or the SDK call. |
| `data.samples[].code` | string | The sample, exactly as the reference prints it. |
| `data.samples[].verification` | object \| null | The last run that checked this sample, or null when none has. |
| `data.samples[].note` | string \| null | Anything to know before using it, such as why it is not executed, or null. |

```json
{
  "success": true,
  "data": {
    "method": "GET",
    "path": "/v1/firearms",
    "tier": "explorer",
    "docsUrl": "https://docs.gunspec.io/en/api/firearms/list",
    "language": "python",
    "keyNote": "Replace your_key with a GunSpec API key, sent as the X-API-Key header.",
    "samples": [
      {
        "label": "Python (requests)",
        "code": "import requests",
        "verification": {
          "status": "passed",
          "checkKind": "executed",
          "ranAt": "2026-09-17T08:50:16.655Z"
        },
        "note": null
      }
    ]
  }
}
```

### Errors

| Status | Code | Message |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Validation error |
| 401 | `UNAUTHORIZED` | API key required |
| 403 | `FORBIDDEN` | Valid key, not permitted |
| 404 | `NOT_FOUND` | Resource not found |
| 429 | `RATE_LIMITED` | Rate limit exceeded |
| 500 | `INTERNAL_ERROR` | Unexpected server error |

### Example

```bash
curl --request GET \
  --url 'https://api.gunspec.io/v1/docs/samples?path=%2Fv1%2Ffirearms&language=python' \
  --header 'X-API-Key: your_key'
```

## client.docs.getLimits()

`GET /v1/docs/limits`

Auth: API key required  
Tier: Explorer+

What each plan allows: requests per minute, day and month, MCP calls per day, paging depth, and how long to wait after a 429.

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object | The response payload. |
| `data.plans` | object[] | Every plan, cheapest first. |
| `data.plans[].tier` | string | Plan id. |
| `data.plans[].name` | string | Plan name. |
| `data.plans[].priceUsdCentsPerMonth` | integer | Monthly price in US cents. |
| `data.plans[].requestsPerMinute` | integer | Requests allowed per minute, per key. |
| `data.plans[].requestsPerDay` | integer | Requests allowed per day, per key. |
| `data.plans[].requestsPerMonth` | integer | Requests included per month. |
| `data.plans[].mcpCallsPerDay` | integer | Calls through the hosted MCP server allowed per day, inside the daily request allowance. |
| `data.plans[].maxPage` | integer \| null | The deepest page a list may be read to, or null for no limit. |
| `data.plans[].totalCountInLists` | boolean | Whether paginated responses include the total count. |
| `data.withoutKey` | object | Limits on a caller that sends no key. |
| `data.withoutKey.requestsPerDay` | integer | Requests allowed per day to the endpoints that need no key. |
| `data.withoutKey.maxPage` | integer \| null | The deepest page a list may be read to without a key. |
| `data.paginationBurst` | object | How fast a list may be paged through before `PAGINATION_BURST` is returned. |
| `data.paginationBurst.pages` | integer | Pages that may be read in quick succession. |
| `data.paginationBurst.windowSeconds` | integer | The window those pages are counted over. |
| `data.retryAfterSeconds` | object | How long to wait after a 429. |
| `data.retryAfterSeconds.rateLimited` | integer | The `Retry-After` sent with a per-minute refusal. |
| `data.retryAfterSeconds.dailyCapReached` | integer | The `Retry-After` sent when the daily allowance is spent. |
| `data.keyHeaders` | string[] | The headers a key may be sent in. |
| `data.docsUrl` | string | The rate limits page in the docs. |

```json
{
  "success": true,
  "data": {
    "plans": [
      {
        "tier": "builder",
        "name": "Builder",
        "priceUsdCentsPerMonth": 2900,
        "requestsPerMinute": 60,
        "requestsPerDay": 2000,
        "requestsPerMonth": 25000,
        "mcpCallsPerDay": 500,
        "maxPage": 25,
        "totalCountInLists": true
      }
    ],
    "withoutKey": {
      "requestsPerDay": 50,
      "maxPage": 5
    },
    "paginationBurst": {
      "pages": 10,
      "windowSeconds": 90
    },
    "retryAfterSeconds": {
      "rateLimited": 60,
      "dailyCapReached": 3600
    },
    "keyHeaders": [
      "X-API-Key: <key>"
    ],
    "docsUrl": "https://docs.gunspec.io/en/rate-limits"
  }
}
```

### Errors

| Status | Code | Message |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Validation error |
| 401 | `UNAUTHORIZED` | API key required |
| 403 | `FORBIDDEN` | Valid key, not permitted |
| 429 | `RATE_LIMITED` | Rate limit exceeded |
| 500 | `INTERNAL_ERROR` | Unexpected server error |

### Example

```bash
curl --request GET \
  --url 'https://api.gunspec.io/v1/docs/limits' \
  --header 'X-API-Key: your_key'
```

## client.docs.listGuides()

`GET /v1/docs/guides`

Auth: API key required  
Tier: Explorer+

Every guide the documentation renders, with the headings each is divided into: what is documented, and the ids and anchors to read it by.

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object | The response payload. |
| `data.total` | integer | How many guides there are. |
| `data.guides` | object[] | Every guide, in the order the documentation lists them. |
| `data.guides[].id` | string | The guide's id, passed to the read endpoint. |
| `data.guides[].title` | string | The page's title. |
| `data.guides[].url` | string | The page a reader would open. |
| `data.guides[].summary` | string | The opening prose: what the page is about. |
| `data.guides[].sizeBytes` | integer | The whole page in Markdown, so a caller can tell what reading it costs. |
| `data.guides[].sections` | object[] | Every heading on the page, in order. |

```json
{
  "success": true,
  "data": {
    "total": 32,
    "guides": [
      {
        "id": "caching",
        "title": "Caching and refreshing",
        "url": "https://docs.gunspec.io/en/caching",
        "summary": "You are encouraged to keep a local copy of the catalog.",
        "sizeBytes": 10038,
        "sections": [
          {
            "anchor": "caching-policy",
            "title": "How long you may keep it",
            "trail": "How long you may keep it"
          }
        ]
      }
    ]
  }
}
```

### Errors

| Status | Code | Message |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Validation error |
| 401 | `UNAUTHORIZED` | API key required |
| 403 | `FORBIDDEN` | Valid key, not permitted |
| 429 | `RATE_LIMITED` | Rate limit exceeded |
| 500 | `INTERNAL_ERROR` | Unexpected server error |

### Notes

- Not yet in the Python SDK.

### Example

```bash
curl --request GET \
  --url 'https://api.gunspec.io/v1/docs/guides' \
  --header 'X-API-Key: your_key'
```

## client.docs.searchGuides()

`GET /v1/docs/guides/search`

Auth: API key required  
Tier: Explorer+

The sections of the guides that answer a question, best first. The entry point: search, then read the one section you need rather than a whole page. A question the guides do not cover returns no results rather than the nearest paragraph.

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `q` | string | yes | The question, in the words it would be asked in. |
| `limit` | integer | no | How many sections to return. |

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object | The response payload. |
| `data.query` | string | The question as it was asked. |
| `data.total` | integer | How many sections matched, of which `results` carries the best. |
| `data.results` | object[] | The matching sections, best first. |
| `data.results[].guideId` | string | The guide the section is on. |
| `data.results[].guideTitle` | string | That guide's title. |
| `data.results[].anchor` | string | The section's anchor. |
| `data.results[].title` | string | The heading. |
| `data.results[].trail` | string | The heading with the ones above it. |
| `data.results[].url` | string | The page, opened at that heading. |
| `data.results[].snippet` | string | The opening of the section, so a caller can judge it without reading it. |

```json
{
  "success": true,
  "data": {
    "query": "how do I handle a 429",
    "total": 34,
    "results": [
      {
        "guideId": "rate-limits",
        "guideTitle": "Rate Limits & Plans",
        "anchor": "rate-limits-retry",
        "title": "What to do when you are limited",
        "trail": "What to do when you are limited",
        "url": "https://docs.gunspec.io/en/rate-limits#rate-limits-retry",
        "snippet": "A 429 carries Retry-After in seconds."
      }
    ]
  }
}
```

### Errors

| Status | Code | Message |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Validation error |
| 401 | `UNAUTHORIZED` | API key required |
| 403 | `FORBIDDEN` | Valid key, not permitted |
| 429 | `RATE_LIMITED` | Rate limit exceeded |
| 500 | `INTERNAL_ERROR` | Unexpected server error |

### Notes

- Not yet in the Python SDK.

### Example

```bash
curl --request GET \
  --url 'https://api.gunspec.io/v1/docs/guides/search?q=how%20do%20I%20handle%20a%20429' \
  --header 'X-API-Key: your_key'
```

## client.docs.getGuide()

`GET /v1/docs/guides/{id}`

Auth: API key required  
Tier: Explorer+

One guide as Markdown: the whole page, or with `anchor` only that heading.

### Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes | The guide's id, as the list endpoint gives it. |

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `anchor` | string | no | Return only the section this heading anchor names. Omitted, the whole page comes back. |

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object | The response payload. |
| `data.id` | string | The guide's id. |
| `data.title` | string | The page's title. |
| `data.url` | string | The page, opened at the section when one was named. |
| `data.summary` | string | The opening prose. Sent with a whole page only. |
| `data.markdown` | string | The whole page as Markdown. Sent when no anchor was given. |
| `data.sections` | object[] | The page's headings, or the named section - one anchor can hold several headings where a page deep-links only the outer one. |
| `data.sections[].anchor` | string | The heading's anchor. |
| `data.sections[].title` | string | The heading. |
| `data.sections[].trail` | string | The heading with the ones above it. |
| `data.sections[].markdown` | string | The section's prose. Sent when an anchor was given. |

```json
{
  "success": true,
  "data": {
    "id": "caching",
    "title": "Caching and refreshing",
    "url": "https://docs.gunspec.io/en/caching#caching-policy",
    "summary": "You are encouraged to keep a local copy of the catalog.",
    "markdown": "## How long you may keep it\n\nEvery lifetime below…",
    "sections": [
      {
        "anchor": "caching-policy",
        "title": "How long you may keep it",
        "trail": "How long you may keep it",
        "markdown": "Every lifetime below is the value the API sends…"
      }
    ]
  }
}
```

### Errors

| Status | Code | Message |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Validation error |
| 401 | `UNAUTHORIZED` | API key required |
| 403 | `FORBIDDEN` | Valid key, not permitted |
| 404 | `NOT_FOUND` | Resource not found |
| 429 | `RATE_LIMITED` | Rate limit exceeded |
| 500 | `INTERNAL_ERROR` | Unexpected server error |

### Notes

- Not yet in the Python SDK.

### Example

```bash
curl --request GET \
  --url 'https://api.gunspec.io/v1/docs/guides/caching' \
  --header 'X-API-Key: your_key'
```
