Authentication

One identity system across the platform and this portal: HS256 JWTs issued by ivorycom-auth.

Developer account auth

stependpointnotes
Sign upPOST /api/auth/registerSend source: "developer-portal" so the verification email links back to this portal. Requires email, password (≥8), tenantName, tenantSlug.
Verify emailPOST /api/auth/verify-email{ token } from the email link; the response auto-logs you in (access + refresh tokens).
Sign inPOST /api/auth/loginMay return { mfaRequired, mfaToken } — complete with the next row.
MFAPOST /api/auth/mfa/verify{ mfaToken, code } (6-digit email code by default; new accounts have MFA on for compliance).
RefreshPOST /api/auth/refresh{ refreshToken } → new access token. Access tokens live 15 minutes; refresh 7 days.
Resend verificationPOST /api/auth/resend-verification{ email, source }; rate-limited to 3/hour.

Calling APIs

curl -H "Authorization: Bearer $TOKEN" https://app.ivorycomcrm.com/api/marketplace/developer/apps

The JWT carries tenantId, sub (user), role, plan and plan_features. Downstream authorization (RBAC objects + plan gates) is enforced from those verified claims — never from anything you put in headers.

Tenant-side API keys

Tenants integrating their systems (Zapier, custom scripts) use API keys from Settings → API Keys against the public surface (/api/crm/v1/public/…). Marketplace developer APIs are JWT-only.

Never embed shared provider credentials in an app. Connectors run on the tenant's own OAuth grants / API keys — the platform's provider-credential scanner blocks shared-key patterns at certification and in CI.