> For the complete documentation index, see [llms.txt](https://herd-security.gitbook.io/herd-security-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://herd-security.gitbook.io/herd-security-docs/api-documentation/quickstart.md).

# Quickstart

An integration guide for the Herd API: make your first requests with curl, page through results, and handle the standard error format.

This guide walks through a typical integration: authenticate, pull your core resources, page through results, and handle errors. You'll need an API key — see [Authentication](/herd-security-docs/api-documentation/authentication.md).

## 1. Make your first request

List the users in your organization:

```shellscript
curl -H "X-API-Key: herd_..." \
  "https://api.herdsecurity.io/api/v1/users"
```

```json
{
  "status": "success",
  "data": [
    {
      "user_id": "usr_cluser789xyz",
      "first_name": "Jane",
      "last_name": "Smith",
      "email": "jane.smith@company.com",
      "status": "Active"
    }
  ],
  "pagination": {
    "total_records": 250,
    "current_page": 1,
    "total_pages": 5,
    "per_page": 50,
    "next_page_url": "https://api.herdsecurity.io/api/v1/users?page=2&per_page=50"
  }
}
```

All list responses share this envelope: a `status` field, a `data` array, and a `pagination` object.

## 2. Pull training completions

Enrollments are the primary feed for tracking who has completed which training:

```shellscript
curl -H "X-API-Key: herd_..." \
  "https://api.herdsecurity.io/api/v1/enrollments?per_page=100"
```

Each row links a `user_id` to a `training_id` with an `enrollment_date`, a nullable `completion_date`, and a `status` of `Not started`, `In Progress`, or `Passed`.

## 3. Pull compliance evidence

If you're building a GRC or compliance connector, the evidence feed returns per-user, per-item completion rows for a specific compliance framework — for example, all completed SOC 2 items in the first half of 2026:

```shellscript
curl -H "X-API-Key: herd_..." \
  "https://api.herdsecurity.io/api/v1/integration/frameworks/SOC2/completions?status=completed&completed_after=2026-01-01T00:00:00Z&completed_before=2026-06-30T23:59:59Z"
```

Add `format=csv` to download every filtered row (no pagination) as a CSV attachment — handy for handing evidence straight to an auditor. See the [Endpoint Reference](/herd-security-docs/api-documentation/endpoint-reference.md#compliance-evidence) for the full parameter list.

## Pagination

All list endpoints accept the same two query parameters:

| Parameter  | Type    | Default | Description                               |
| ---------- | ------- | ------- | ----------------------------------------- |
| `page`     | integer | 1       | Page number (1-indexed, minimum 1)        |
| `per_page` | integer | 50      | Records per page (minimum 1, maximum 100) |

The `pagination` object in each response tells you where you are; `next_page_url` is present only when another page exists, and it preserves any active filters. To fetch everything, follow `next_page_url` or increment `page` until `current_page` reaches `total_pages`:

```javascript
async function fetchAllEnrollments(apiKey) {
  let allEnrollments = [];
  let page = 1;
  let hasMore = true;

  while (hasMore) {
    const response = await fetch(
      `https://api.herdsecurity.io/api/v1/enrollments?page=${page}&per_page=100`,
      { headers: { "X-API-Key": apiKey } }
    );

    const result = await response.json();
    allEnrollments = allEnrollments.concat(result.data);

    hasMore = page < result.pagination.total_pages;
    page++;
  }

  return allEnrollments;
}
```

## Error format

Errors return a non-2xx HTTP status code. Error bodies generated by the API follow this shape:

```json
{
  "status": "error",
  "error": {
    "code": 404,
    "message": "Tag not found"
  }
}
```

The `error` object carries the HTTP status `code`, a human-readable `message`, and occasionally an additional `details` field.

| Code | Meaning               | What to do                                                                                                                    |
| ---- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| 400  | Bad Request           | Check path and query parameter values (for example, an unknown framework or a malformed date filter)                          |
| 401  | Unauthorized          | Verify the API key is present in `X-API-Key`, correctly copied, and still active                                              |
| 404  | Not Found             | The resource doesn't exist (for example, an unknown `tag_id`)                                                                 |
| 429  | Too Many Requests     | Back off and retry after the `Retry-After` interval — see [Rate Limits](/herd-security-docs/api-documentation/rate-limits.md) |
| 500  | Internal Server Error | Retry with backoff; contact <support@herdsecurity.io> if it persists                                                          |

{% hint style="info" %}
Always branch on the HTTP status code rather than parsing error message strings — messages may change, status codes won't.
{% endhint %}
