- Organization API keys for server automation owned by one church. This is the fastest way to test the production API.
- OAuth 2.1 (Sign in with Grain) for applications that act on behalf of individual users, including Grain-managed OAuth apps that can connect many churches.
MCP access requires Growth or Scale. Organization API keys and unmanaged OAuth sessions require an active Scale plan for the church you are accessing. Grain-managed OAuth apps with an active grant may call
/api/v1 on Starter and Growth; Draft apps are limited to their publisher organization.Organization API keys
An Owner, Admin, or custom role with Manage API access can create a key in Settings → API. Give the key a descriptive name, choose the smallest required scope set, and select an expiry. The secret is displayed only once. Production organizations receive keys beginning withgrain_live_. Sandbox, demo, and test organizations receive grain_test_ keys.
X-Organization-Id is optional. If you include the header, it must match the key’s organization. API keys work only under /api/v1; they cannot sign in to the Grain app, call tRPC or MCP, or authenticate directly with the identity provider.
API key scopes
Write access includes the corresponding read access. Donor and household scopes can expose personal information. Contribution and pledge responses include donor IDs but never embed donor identity; use a donor read scope to retrieve the related donor separately.
Rotation and revocation
Rotating a key displays a new secret once. The previous secret remains valid for up to 24 hours, or until its original expiry if sooner, so you can update automation without downtime. You can revoke the previous secret immediately after deployment. Full revocation permanently disables both secrets; the named key stays visible for audit history. Grain-managed OAuth client secrets are different: rotating a confidential app secret replaces it immediately. The previous secret stops working as soon as rotation succeeds.OAuth 2.1 flow
1
Redirect to authorize
Send the user to
https://auth.grainledger.com/auth/v1/oauth/authorize with your client ID, redirect URI, scopes, and PKCE parameters (code_challenge and code_challenge_method=S256).2
User consents
The user signs in (if needed) and approves access at
https://app.grainledger.com/oauth/consent.3
Receive authorization code
Grain redirects back to your
redirect_uri with an authorization code and state parameter.4
Exchange for tokens
POST the code to
https://auth.grainledger.com/auth/v1/oauth/token with your code_verifier to receive access and refresh tokens. Confidential clients also authenticate with HTTP Basic using their client ID and secret.5
Call the API
Include
Authorization: Bearer <access_token> and X-Organization-Id on resource requests. Grain-managed apps may first call GET /api/v1/organizations without that header to discover churches the user authorized for this client.Grain-managed OAuth apps
Publisher organizations register apps in Settings → API → Apps. Connecting churches complete org and Grain-scope consent athttps://app.grainledger.com/oauth/consent. Effective permission is the intersection of the app’s maximum scopes, the user’s consented scopes, and the user’s current role.
Use PKCE S256 for both public and confidential clients. A Draft app can connect only its publisher organization, which supports localhost integration testing before publication. Grain checks app status, the installation, and the grant on every /api/v1 request. Disabling the app or revoking a grant takes effect on the next API call.
If the user has SMS two-factor authentication enrolled, Grain requires a fresh challenge while the connection is authorized. OAuth access tokens returned by both the code exchange and refresh remain truthfully marked aal1; Grain records the separate, server-verified MFA result on the managed app grant. Integrators should not reject an otherwise valid token solely because its aal is aal1.
If Grain returns Reconnect this application and complete two-factor authentication., start a new authorization-code flow so the user can complete the fresh challenge. Grain also requires reconnection if the verified phone factor used to authorize the grant is later removed.
Rate limits are 100 requests per minute per target organization and 100 requests per minute per application.
OAuth endpoints
MCP (AI agents)
Grain exposes a read-only MCP server athttps://api.grainledger.com/mcp for ChatGPT and other MCP clients. MCP uses the same OAuth identity and organization permissions; org scoping is via organizationId in tool arguments instead of X-Organization-Id. See MCP.
MCP is read-only because it exposes only read tools. OAuth tokens still identify the signed-in user, and Grain checks organization permissions on each tool call.
Authorization request example
The authorization server’s
scope parameter accepts standard OIDC scopes such as openid email profile. Do not send Grain resource scopes such as donors:read there. Grain resource scopes come from the app registration and the user’s Grain consent selection.Token exchange
X-Organization-Id header with OAuth
Every OAuth API request must include the organization (church) whose data you are accessing:OAuth scopes
Standard OIDC scopes control user profile data in tokens:
API access for unmanaged OAuth follows the signed-in user’s role. Grain-managed apps also intersect that role with the app’s maximum scopes and the scopes the user consented to.
Rate limits
/api/v1 allows 100 requests per minute per target organization. Grain-managed OAuth apps have a second budget of 100 requests per minute per application so one client cannot fan out across installations.
Diagnose API errors
Every Grain API response includes a server-generatedX-Request-Id header. Save it with your integration logs and include it in support requests. The same ID links authenticated API activity to any resulting audit records.
Schema validation failures return safe field names and machine-readable validation codes:
details.fields contains up to 20 issues. A field reported as request refers to an unlisted or nested field. Submitted values are omitted. Authenticated scope denials and rate-limit responses are recorded in API activity; rejections before authentication are recorded in server diagnostics without trusting a supplied organization ID. Organization discovery is not included in per-organization activity.
For contribution retry behavior, see Retry contribution creates safely.