# CommonGrants Protocol Specification: Key Features and Implementation Guide

> Explore the CommonGrants protocol specification a stable API contract for sharing grant data. Learn its key features and implementation guide for flexible compliance.

- Repository: [U.S. Department of Health & Human Services/simpler-grants-protocol](https://github.com/hhs/simpler-grants-protocol)
- Tags: how-to-guide
- Published: 2026-03-03

---

**The CommonGrants protocol defines a stable, versioned API contract for sharing grant-related data across the grants ecosystem, balancing strict compliance with flexible implementation extensions.**

The `hhs/simpler-grants-protocol` repository provides the canonical reference for standardizing how grant opportunities, applications, and awards are exchanged between systems. This specification ensures interoperability while providing clear extension points for domain-specific requirements.

## Versioned RFC-Style Specification

The protocol follows **Semantic Versioning** (`Major.Minor.Patch`) and uses BCP 14 keywords for requirement levels, as defined in [`website/src/content/docs/protocol/specification/v0_1_0.md`](https://github.com/hhs/simpler-grants-protocol/blob/main/website/src/content/docs/protocol/specification/v0_1_0.md).

- **Major** increments indicate breaking changes, such as new required routes or fields.
- **Minor** increments add backward-compatible features like optional routes or enum values.
- **Patch** increments cover non-functional changes including documentation updates.

This versioning strategy ensures that API consumers can depend on stable contracts while implementers can track compliance requirements against specific specification versions.

## Route Stability Levels

The specification categorizes API routes into three distinct stability levels to clarify implementation obligations:

| Stability | Meaning |
|-----------|---------|
| **Required** | Must be implemented for full compliance. |
| **Optional** | May be implemented as useful extensions. |
| **Experimental** | Unstable features intended for feedback only. |

The route definitions, including `GET /opportunities`, `GET /opportunities/{id}`, and `POST /opportunities/search`, are specified in [`website/src/content/docs/protocol/specification/v0_1_0.md`](https://github.com/hhs/simpler-grants-protocol/blob/main/website/src/content/docs/protocol/specification/v0_1_0.md).

## Canonical Data Schemas

All data exchanged through the protocol follows **Zod-derived JSON schemas** defined in [`lib/ts-sdk/src/schemas.ts`](https://github.com/hhs/simpler-grants-protocol/blob/main/lib/ts-sdk/src/schemas.ts). These schemas enforce type safety and generate corresponding TypeScript types exported from [`lib/ts-sdk/src/types.ts`](https://github.com/hhs/simpler-grants-protocol/blob/main/lib/ts-sdk/src/types.ts).

The schema architecture includes:

- **Base Types** – Fundamental primitives including UUIDs, URLs, dates, and arrays.
- **Core Fields** – Reusable components such as `Money`, `Event`, `CustomField`, and `SystemMetadata`.
- **Domain Models** – Grant-specific entities including `OpportunityBase`, `OppStatus`, `OppFunding`, and `OppTimeline`.

TypeScript consumers can import these types directly for compile-time safety:

```typescript
import { OpportunityBase, OpportunityResponse } from "@common-grants/sdk/types";

```

## Query Capabilities

### Pagination and Sorting

List endpoints **SHOULD** support pagination using `page` and `pageSize` query parameters, returning a `paginationInfo` object containing total counts and navigation links.

Sorting capabilities include `sortBy`, `customSortBy`, and `sortOrder` parameters, with responses including `sortInfo` metadata. These features allow clients to navigate large datasets efficiently while maintaining protocol compliance.

### Advanced Filtering

The protocol defines a comprehensive **filter language** supporting operators including `eq`, `neq`, `gt`, `lt`, `in`, and `between`. Filters are submitted within a `filters` object in search requests (such as `POST /opportunities/search`) and returned in a `filterInfo` wrapper.

The filter schemas are enforced through Zod validation in [`lib/ts-sdk/src/schemas.ts`](https://github.com/hhs/simpler-grants-protocol/blob/main/lib/ts-sdk/src/schemas.ts), ensuring type safety across implementations.

## Implementation Extensions

The specification provides four primary extension mechanisms to accommodate domain-specific requirements without breaking core compliance:

| Extension | Purpose | Implementation |
|-----------|---------|----------------|
| **Custom fields** | Add arbitrary attributes to models | `customFields` array on `OpportunityBase` |
| **Custom enum values** | Extend standard enums | `custom` sentinel value in enums |
| **Custom filters** | Domain-specific query criteria | `customFilters` parameter |
| **Custom routes** | Non-standard endpoints | Outside `/common-grants/` path prefix |

These mechanisms are documented in [`website/src/content/docs/protocol/specification/v0_1_0.md`](https://github.com/hhs/simpler-grants-protocol/blob/main/website/src/content/docs/protocol/specification/v0_1_0.md) and ensure that agencies can model local business rules while maintaining interoperability with standard consumers.

## Developer Tooling

### Validation and Compliance

The `@common-grants/cli` package provides command-line tools to validate OpenAPI documents against the protocol specification. This ensures that implementations meet compliance requirements before deployment.

### TypeScript SDK Integration

The reference implementation includes a TypeScript SDK (`lib/ts-sdk/`) that provides compile-time type safety through Zod-derived schemas. Developers can import types such as `OpportunityResponse` and `OpportunitiesListResponse` from [`lib/ts-sdk/src/types.ts`](https://github.com/hhs/simpler-grants-protocol/blob/main/lib/ts-sdk/src/types.ts), ensuring that client code adheres to protocol contracts.

The following example demonstrates how to interact with a compliant API using the SDK types:

```typescript
import {
  OpportunityResponse,
  OpportunitiesListResponse,
  OppSearchRequest,
  OppFilters,
  OppSorting,
  PaginatedBodyParams,
} from "@common-grants/sdk/types";

/** GET a single opportunity (required route) */
async function getOpportunity(id: string): Promise<OpportunityResponse> {
  const resp = await fetch(`/common-grants/opportunities/${id}`);
  return (await resp.json()) as OpportunityResponse;
}

/** Search opportunities with filters, sorting, and pagination (optional route) */
async function searchOpportunities(req: OppSearchRequest) {
  const resp = await fetch(`/common-grants/opportunities/search`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(req),
  });
  return (await resp.json()) as OpportunitiesListResponse;
}

/* Example request payload */
const request: OppSearchRequest = {
  search: "climate",
  filters: {
    title: { value: "climate", operation: "like" },
    closedDateRange: {
      value: { min: "2024-01-01", max: "2024-12-31" },
      operation: "between",
    },
  } as OppFilters,
  sorting: { sortBy: "lastModifiedAt", sortOrder: "desc" } as OppSorting,
  pagination: { page: 1, pageSize: 20 } as PaginatedBodyParams,
};

```

This implementation compiles against the TypeScript types defined in [`lib/ts-sdk/src/types.ts`](https://github.com/hhs/simpler-grants-protocol/blob/main/lib/ts-sdk/src/types.ts), guaranteeing that request bodies and responses adhere to the protocol contracts.

### OpenAPI-First Design

The protocol supports authoring APIs in **TypeSpec**, compiling to OpenAPI specifications, and generating SDKs automatically. This workflow provides IntelliSense support and compile-time validation throughout the development lifecycle, as implemented in the reference repository.

## Summary

- The CommonGrants protocol uses **Semantic Versioning** (`Major.Minor.Patch`) to manage breaking and non-breaking changes.
- Routes are classified as **Required**, **Optional**, or **Experimental** to clarify implementation obligations.
- **Zod-derived JSON schemas** in [`lib/ts-sdk/src/schemas.ts`](https://github.com/hhs/simpler-grants-protocol/blob/main/lib/ts-sdk/src/schemas.ts) enforce type safety for all data exchange.
- Rich **query capabilities** include pagination, sorting, and advanced filtering with operators like `eq`, `gt`, and `between`.
- **Implementation extensions** (custom fields, enums, filters, routes) allow flexibility without sacrificing compliance.
- Developer tooling includes a **CLI validator**, **TypeScript SDK**, and **OpenAPI-first** TypeSpec workflow.

## Frequently Asked Questions

### What versioning scheme does the CommonGrants protocol use?

The protocol follows **Semantic Versioning** (`Major.Minor.Patch`) as defined in [`website/src/content/docs/protocol/specification/v0_1_0.md`](https://github.com/hhs/simpler-grants-protocol/blob/main/website/src/content/docs/protocol/specification/v0_1_0.md). Major version increments indicate breaking changes such as new required routes, while minor versions add backward-compatible features like optional fields. Patch versions cover non-functional updates including documentation corrections.

### How does the protocol handle custom data fields?

The specification provides a **custom fields** extension mechanism through the `customFields` array property on models like `OpportunityBase`. This allows implementers to add arbitrary domain-specific attributes without breaking core protocol compliance. Custom fields are defined in the canonical data schemas within [`lib/ts-sdk/src/schemas.ts`](https://github.com/hhs/simpler-grants-protocol/blob/main/lib/ts-sdk/src/schemas.ts) and documented in the specification.

### What filtering capabilities are available in the CommonGrants protocol?

The protocol defines a comprehensive **filter language** supporting operators including `eq`, `neq`, `gt`, `lt`, `in`, and `between`. These filters are submitted via the `filters` object in search requests (such as `POST /opportunities/search`) and returned in a `filterInfo` wrapper. The filter schemas are enforced through Zod validation in the TypeScript SDK.

### How can developers validate their API implementation against the protocol?

Developers can use the **@common-grants/cli** package to validate OpenAPI documents against the protocol specification. Additionally, the TypeScript SDK (`lib/ts-sdk/`) provides compile-time type safety through Zod-derived schemas exported from [`lib/ts-sdk/src/types.ts`](https://github.com/hhs/simpler-grants-protocol/blob/main/lib/ts-sdk/src/types.ts). The protocol also supports an OpenAPI-first workflow using TypeSpec, enabling validation during the API design phase.