Build an Alum integration
Production API: https://api.alumweb.org. Start with synthetic data in a private test organization. OAuth discovery is enabled; a reviewed client and explicit organization consent are required to access MCP.
Authentication
Create organization API credentials in Settings → AI & developer. Select only the required scopes: manage_members for the party graph, manage_app_builder for governed configuration, or view_analytics for fixed aggregates.
- Organization keys start with
alum_sk_and work only on supported routes for their organization. - Interactive user tokens are required for integration management, consent and human approvals.
- OAuth tokens work only at
/mcp, expire in 15 minutes and cannot call the ordinary REST API.
Keep keys server-side. Never place them in browser bundles, URLs, source control or logs. Choose an expiry and revoke unused credentials.
REST quickstart
Set ALUM_TOKEN privately to a view_analytics API credential, ALUM_ORG_ID to the owning organization UUID, and ALUM_REQUEST_ID to a fresh UUID. These examples use Bash.
curl --fail-with-body "https://api.alumweb.org/v1/orgs/$ALUM_ORG_ID/analytics/analysis/catalog" -H "Authorization: Bearer $ALUM_TOKEN"
curl --fail-with-body "https://api.alumweb.org/v1/orgs/$ALUM_ORG_ID/analytics/analysis/query" -H "Authorization: Bearer $ALUM_TOKEN" -H 'Content-Type: application/json' -H "Idempotency-Key: $ALUM_REQUEST_ID" --data '{"question":"How many active members do we have?"}'API-key POSTs require an idempotency key, including the read-only analytics POST. Reuse it only for an identical retry. Replays return the original response; changed requests with the same key return 409.
REST responses use {success, data, error?, meta?}. Party lists use page/per_page; integration lists use limit/offset. Check each operation in OpenAPI rather than assuming a shared pagination shape.
OAuth and MCP
- Have an operations administrator review your integration and exact HTTPS callback ownership. Obtain the registered public client UUID. Wildcard callbacks and open dynamic registration are not supported.
- Generate a random 43–128 character PKCE verifier and random state (16–1024 characters). Save both in the client authorization session. Send the unpadded base64url SHA-256 verifier digest as the S256 challenge.
- Open
/oauth/authorizewithclient_id, exactredirect_uri,response_type=code,scope=view_analytics,resource=https://api.alumweb.org/mcp,code_challenge_method=S256,code_challengeandstate. - The human signs in and selects one organization. Approval requires integration-management and analytics permissions. Your callback must validate saved state and
iss=https://api.alumweb.org, and handle denial. - Form-POST to
/oauth/tokenwithgrant_type=authorization_code, code, original verifier, same client, exact callback and resource. No client secret. Codes expire after five minutes and are single-use.
Initialize MCP with the OAuth token:
POST https://api.alumweb.org/mcp
Authorization: Bearer <OAuth access token>
Content-Type: application/json
Accept: application/json, text/event-stream
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"your-client","version":"1.0.0"}}}Send notifications/initialized without an ID (202), then tools/list. Include MCP-Protocol-Version: 2025-11-25 on subsequent calls.
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"alum_analyze_organization","arguments":{"question":"How many active members do we have?"}}}The other tool, alum_analysis_catalog, takes no arguments. Tenant identity comes from consent, never a tool argument. Check JSON-RPC errors and isError even on HTTP 200. Tokens expire after 900 seconds; reauthorize because refresh tokens are not supported. Revoke grants in organization integration settings.
This is stateless JSON-response MCP, not a GET/SSE session. It does not support writes, approvals, arbitrary SQL, personal-record exports, confidential client secrets or dynamic registration. Provider-specific acceptance remains unverified; do not assume every AI client supports these constraints.
Webhooks
Open Settings → AI & developer → Manage webhooks and connected integrations. A human with manage_integrations can register a public HTTPS port-443 receiver. Save the signing secret immediately: it is returned once.
{
"id": "<event UUID>",
"organization_id": "<organization UUID>",
"type": "party.created.v1",
"created_at": "<RFC3339 timestamp>",
"data": { "party_id": "<party UUID>" }
}Supported types: party.created.v1 and application.changed.v1. Application data contains application ID, version ID and action. Payloads exclude personal fields. Event-list REST responses call the type field event_type.
Verify Alum-Signature: t=timestamp,v1=hex over exact raw bytes using HMAC-SHA256 of timestamp + "." + raw_body. Use constant-time comparison and reject timestamps beyond five minutes. Verify before JSON parsing.
Atomically store the event ID in a unique durable inbox and enqueue work before returning 2xx. Duplicate IDs are successful no-ops. Delivery is at-least-once and unordered, with eight attempts, exponential backoff and manual replay. Replay preserves IDs. Keep the old receiver key for 60 seconds after rotation for in-flight requests. Private addresses and redirects are blocked.
SDKs and testing
TypeScript and Python SDK source, a Postman collection, sandbox bootstrap and webhook verifier are included in the repository. They are beta source artifacts, not published npm/PyPI packages. Developers with repository access can install Python using python -m pip install -e sdk/python; TypeScript source is under sdk/typescript/src.
The clients unwrap REST data and do not automatically retry writes. TypeScript results are unknown until validated. Pagination metadata is not returned by the current convenience methods; use raw HTTP when needed.
Test on an isolated deployment with test provider accounts. The automated TLS HTTP lifecycle covers JWTs, real database permissions, credentials, idempotency, signed webhook retry/replay, OAuth consent/code exchange, real aggregate MCP queries and revocation. This does not certify a provider’s browser login flow or production receiver behavior.
Troubleshooting
- 401: check token type, expiry, revocation and active membership.
- 403: check tenant, scope and whether the endpoint requires a human.
- 409: check idempotency-key reuse or delivery replay state.
- OAuth invalid_grant: check verifier, callback, client and resource; the code may be expired or consumed.
- MCP 406/415: send both Accept types and application/json.
- Tool error: choose a supported aggregate from the catalog; do not send SQL or tenant IDs.
- Webhook failure: inspect worker and delivery status, public DNS/TLS, response code and signing key.
For support, provide UTC time, operation, request ID and sanitized error code—not credentials or member records. Health/readiness endpoints verify process and database availability, not your integration’s business outcome.