CommonGrants API Optional Endpoints: Extended Routes for Advanced Grant Management
The CommonGrants API uses the custom x-status: optional OpenAPI extension to mark extended routes—including direct opportunity applications, reusable form libraries, and competition management—that implementers may support without breaking core protocol compliance.
The CommonGrants Protocol, maintained in the hhs/simpler-grants-protocol repository, provides a standardized REST interface for grant management across federal and private funders. While the specification mandates a core set of required routes for basic interoperability, it also defines optional endpoints that enable advanced workflows. These routes are explicitly tagged in the OpenAPI 3.0.3 specification (website/public/openapi/openapi.0.3.0.yaml) using the x-status extension defined in ADR 0019.
How Optional Status Is Defined
According to website/src/content/docs/governance/adr/0019-api-route-status.md, the protocol introduces a machine-readable x-status field that can be attached to any operation. This field accepts three values:
required– Core routes that every implementation must supportoptional– Extended functionality that implementations may omitexperimental– Routes under active development that may change
When an operation includes x-status: optional in the OpenAPI definition, client libraries and validation tools can detect whether an API provider supports that specific functionality without breaking existing integrations.
Complete List of Optional Endpoints
The following routes are designated as optional in the CommonGrants API v0.3.0, enabling providers to incrementally adopt advanced features.
Application Workflow Extensions
These endpoints support alternative application flows beyond the standard required routes.
Apply to an Opportunity
- Method:
POST - Path:
/common-grants/opportunities/{oppId}/apply - Purpose: Submit a grant application directly against a specific opportunity (the "JustFund" style apply flow)
- Source: Defined in
website/src/content/docs/governance/adr/0018-apply-endpoints.md
Start a New Application
- Method:
POST - Path:
/common-grants/applications/start - Purpose: Initialize a blank application object before populating form data
Submit an Application
- Method:
POST - Path:
/common-grants/applications/{appId}/submit - Purpose: Finalize and submit a completed application for review, transitioning it from draft to submitted status
Application-Specific Form Handling
These routes allow direct manipulation of individual forms within an application context.
- Get Application Form:
GET /common-grants/applications/{appId}/forms/{formId} - Update Application Form:
PUT /common-grants/applications/{appId}/forms/{formId}
Both operations require the ApplicationId and FormId parameters and return a FormResponse schema.
Reusable Form Catalog Management
These endpoints manage a library of reusable form definitions that can be referenced across multiple applications.
- List Forms:
GET /common-grants/forms - Create Form:
POST /common-grants/forms - Get Form:
GET /common-grants/forms/{formId} - Update Form:
PUT /common-grants/forms/{formId} - Delete Form:
DELETE /common-grants/forms/{formId}
Implementing these routes allows funders to maintain centralized form templates that applicants can reuse across different opportunities.
Competition Management
Competitions provide a higher-level grouping mechanism for related opportunities.
- List Competitions:
GET /common-grants/competitions - Create Competition:
POST /common-grants/competitions - Get Competition:
GET /common-grants/competitions/{compId}
These routes return CompetitionListResponse and CompetitionResponse schemas, respectively.
Detecting Optional Support in Client Code
Because optional endpoints are marked with x-status: optional in website/public/openapi/openapi.0.3.0.yaml, client implementations should verify availability before calling these routes. The following examples demonstrate how to interact with optional endpoints using the CommonGrants SDKs.
TypeScript SDK: Direct Opportunity Application
import { CommonGrantsClient } from "@common-grants/ts-sdk";
const client = new CommonGrantsClient({
baseUrl: "https://api.commongrants.org"
});
async function applyToOpportunity(oppId: string, payload: unknown) {
// Optional endpoint: Check server capabilities before calling
const response = await client.post(
`/common-grants/opportunities/${oppId}/apply`,
payload
);
return response.data;
}
Python SDK: Initialize Application
import common_grants_sdk as cg
client = cg.Client(base_url="https://api.commongrants.org")
# Optional endpoint: POST /common-grants/applications/start
new_app = client.post(
"/common-grants/applications/start",
json={"opportunityId": "12345"}
)
print(new_app.json())
cURL: List Reusable Forms
# Optional endpoint: GET /common-grants/forms
curl -s https://api.commongrants.org/common-grants/forms | jq .
Implementation Considerations
When building a CommonGrants API implementation, consider the following regarding optional endpoints:
- Backward Compatibility: Omitting optional routes does not violate protocol compliance. Required routes—such as
GET /common-grants/opportunitiesandPOST /common-grants/opportunities/search—remain mandatory. - Documentation: If you implement optional routes, include the
x-status: optionalfield in your generated OpenAPI documentation to maintain consistency with the core specification. - Client Expectations: Client applications must handle
404 Not Foundresponses gracefully when attempting to call optional endpoints that a provider has not implemented.
Summary
- The CommonGrants API defines optional endpoints using the
x-status: optionalOpenAPI extension specified in ADR 0019. - Optional routes include direct apply flows (
/opportunities/{id}/apply), application lifecycle management (/applications/start,/applications/{id}/submit), reusable form catalogs (/forms), and competition grouping (/competitions). - These routes reside in
website/public/openapi/openapi.0.3.0.yamlalongside required routes but are explicitly marked to indicate optional implementation status. - API providers may implement any subset of optional endpoints to support advanced workflows without breaking core interoperability.
Frequently Asked Questions
How do I know if a CommonGrants API instance supports optional endpoints?
Inspect the OpenAPI specification document provided by the server. Look for the x-status field on individual operations. If x-status: optional is present, the endpoint is implemented. Alternatively, attempt a GET request against the optional route and handle 404 responses as indicators of non-support.
What happens if my client calls an optional endpoint that is not implemented?
The server returns a 404 Not Found response. Because optional endpoints are not required for protocol compliance, clients must implement graceful degradation logic when these routes are unavailable.
Are optional endpoints documented differently from required ones?
Yes. According to website/src/content/docs/governance/adr/0019-api-route-status.md, optional endpoints carry the x-status: optional metadata and should be rendered in documentation with visual indicators (such as "Optional" badges) to distinguish them from required (x-status: required) or experimental (x-status: experimental) routes.
Can an implementation partially support optional endpoint groups?
Yes. You may implement, for example, the competition listing routes while omitting the reusable form catalog. Each optional endpoint is independent, allowing providers to select specific extended features that match their operational requirements without adopting the entire optional suite.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →