Not a bolted-on integrations tab — the engine itself.
Most CRMs expose a thin, lagging API next to the “real” product. GENECRM's web app, mobile app, and API are three clients of one backend — so the API can never fall behind what you see on screen.
Nothing in the app is walled off from the API — the same records, validation, and automations power the UI and every /v1 call.
Web, the native iOS/Android app, and your integrations all speak to the same backend — build once and it behaves identically everywhere.
Every response is grounded in your real, tenant-isolated data. No hidden AI rewriting of records — automation and the GENE copilot only act on what you allow.
OAuth 2.0 client-credentials plus a user-exchange grant were designed for partner apps that embed GENECRM headlessly behind their own UI.
A key you mint yourself, scoped how you need it
Generate a key from Settings → Developers — no support ticket, no waiting. Scope it read-only for a reporting integration or read+write for something that creates and updates records, and revoke it instantly if it leaks.
- Self-service — create, rotate, and revoke keys from in-app settings
- Scoped to read or read+write; each key resolves to a tenant and a service identity
- Sent as an X-API-Key header on every request — no session, no cookies
- Every key's usage is broken out separately in GET /v1/usage
Client-credentials for apps that act on their own behalf
Register an OAuth client, exchange its client_id/secret for a short-lived, rotating access token, then use it as a normal Bearer token on any /v1 endpoint — the enterprise-friendly alternative to a static API key living in a partner's codebase.
- POST /oauth/token — grant_type=client_credentials + client_id + client_secret
- Returns a short-lived, scoped JWT: { access_token, token_type: "Bearer", expires_in }
- Use it as Authorization: Bearer <token> on any /v1 resource
- For embedded/partner apps, exchange it again for a real user's identity — see below
One shape, one boundary, every resource under /v1.
Every resource below shares the same request and response shape, the same pagination (?limit=&offset=), and the same row-level-security boundary — list and create return only your tenant's rows, full stop. Write coverage varies by resource; the OpenAPI spec is the exact list.
Signed events, a delivery log, and nothing lost
Subscribe a URL to the events you care about — crm.contact.create, crm.lead.create, crm.opportunity.update, and more. Every delivery is HMAC-signed so you can trust the payload, every attempt is logged, and failures land in a dead-letter queue you can replay.
- POST /v1/webhooks — { url, events: [...] } returns a signing secret, shown once
- Every delivery carries X-GeneCRM-Signature: sha256=<hmac> over the raw body
- Full delivery history at GET /v1/webhooks/deliveries
- Failed deliveries retry up to 5×, then sit in GET /v1/webhooks/events/failed for replay
Metered by plan, visible in real time.
Per-minute rate limits are tiered by plan and enforced at the edge; a separate monthly call quota is metered per tenant. Both are queryable, so nothing about your usage is a surprise.
Premium ≈ 120 req/min, Pro ≈ 600 req/min — exceed it and you get 429 with a Retry-After header, not a silent drop.
A separate monthly call quota is metered per tenant. Once it's spent, further calls return HTTP 402 Payment Required until the period resets or you upgrade.
Current period's usage against your plan limit, broken down per API key — build your own dashboard or just check before you ship.
Your plan's limits and which gated features are on — including api_access itself, which is available from Pro.
A spec you can generate a client from, in any language
The full API is described by an OpenAPI/Swagger spec generated from the same schema serving the API — it can't drift out of sync. Pair it with a getting-started guide and self-service key management, and you're making your first call in minutes.
- Machine-readable OpenAPI spec at /openapi.json — generate a client for any language
- Python and TypeScript reference clients, plus a webhook-verification helper
- A getting-started guide walks through your first key, first call, and first webhook
- Manage keys and OAuth clients yourself: Settings → Developers, no support ticket
Run GENECRM inside your own product.
Partner and platform integrations don't have to share a single service account. Exchange your OAuth app token for a real user's identity, and every action is attributed to that person — with the full tenant isolation guarantee intact.
The three-step embed handshake
- 1. App-level token. Your backend exchanges its OAuth client_id/secret for an app-scoped Bearer token via
POST /oauth/token. - 2. User exchange. Your backend calls
POST /v1/auth/exchangewith the app token plus the signed-in user's external ID and email — GENECRM finds or creates that user and returns their own access token. - 3. Proxy, per user. Your UI calls
/v1/**through your own proxy with that user's token — every write is attributed to the real person, scoped to their firm by row-level security.
One versioned API, two ways in — API keys or OAuth 2.0 — every resource under a single path, signed webhooks you can trust, and usage you can see before you hit a wall.
Questions developers actually ask.
API keys are the fast path for your own scripts and internal tools: mint one in Settings → Developers and send it as X-API-Key. OAuth 2.0 client-credentials is for a partner app or integration acting on its own behalf — a rotating, short-lived Bearer token instead of a static secret in every request.
Per-minute rate limits are tiered by plan (Premium ≈ 120 req/min, Pro ≈ 600 req/min) and return 429 with a Retry-After header. The separate monthly API-call quota is metered independently — once it's exhausted, further calls return 402 Payment Required until the period resets or you upgrade.
Every delivery is signed: the X-GeneCRM-Signature header carries sha256=<hmac>, an HMAC-SHA256 of the raw request body using your endpoint's secret (shown once at creation). Recompute it and compare with a constant-time check before trusting the payload — never trust an unsigned or mismatched delivery.
Deliveries retry automatically up to 5 times with backoff. If they still fail, the event lands in the dead-letter queue (GET /v1/webhooks/events/failed) and you can replay it on demand once your endpoint is back — no lost events.
Every workspace you create is already an isolated tenant, so a second workspace is your development environment — build and test against it with its own keys, then point your integration at your production workspace when you're ready. There is no separate test/live key split to reason about.
Every resource lives under /v1. We add fields and endpoints in a backward-compatible way within a version; a breaking change gets a new version rather than silently changing /v1 under you.
Mobile uses its own password grant: POST /v1/auth/token with email + password returns a short-lived access token plus a rotating refresh token, refreshed without asking the user to sign in again. It's a separate flow from API keys and OAuth apps, scoped to the signed-in user.
GET /v1/usage returns your current period's usage against your plan's limit, broken down per API key, and GET /v1/entitlements returns your plan's limits and which gated features — like api_access itself — are enabled.