Skip to main content
4D has four credential types. Which one you use depends on where the call is made from:

Organization API keys

Every partner API call authenticates with a bearer header:
The key is bound to your organization. There is no org id parameter anywhere in the API - your key is the tenancy. Isolation is enforced with row-level security at the database layer, so a request can only ever read or write rows belonging to your organization.
Treat org_ keys like passwords: server-side only, never in client bundles, rotate if exposed. Issue one from an authenticated partner admin session as described in the Quickstart.
An org_ key authenticates a service identity scoped to one organization. It cannot publish a module, install a module, issue a module credential, or mint another org_ key. Use a partner admin session for those operations. When setting up a private module, author and publish it with the admin session, then mint the org_ key afterward for any service that needs partner reads.

Admin session tokens

Key management and module authoring need a partner admin session rather than an org_ key. A session token comes from signing in, either in the console or over the email OTP endpoints:
  1. POST /v1/auth/email-otp/request with {"email": "<admin email>"} sends a one-time code to that address.
  2. POST /v1/auth/email-otp/verify with {"email": "<admin email>", "otp": "<code>"} returns a token.
  3. Administrators must complete the second factor before any admin operation: POST /api/auth/two-factor/verify-totp with {"code": "<authenticator code>"} and the token as a bearer. Until then, admin routes answer 401 with the reason 2FA_REQUIRED.
  4. POST /v1/session/active-organization with {"organizationId": "<organization id>"} and the token as a bearer makes that organization the session’s active one. Sign-in picks the admin’s earliest seat on its own, so an administrator with seats on more than one organization does this before minting a key or publishing a module, or the key or module lands in the other organization.
Send the token as Authorization: Bearer <token> on the key and module endpoints. A session belongs to the admin who signed in and acts on the session’s active organization; a key response carries that organization as organization_id and a module response as owner_organization_id, so check the one you meant. The token is not a credential to store or share.

Publishable tracking keys

Browser event tracking and publisher ad slots can’t hide a secret, so they don’t use one. POST /v1/track and GET /v1/ads/serve authenticate with a publishable ek_live_… key that ships in client code, like an analytics measurement id. Abuse is bounded by two controls on the key itself, not by secrecy:
  • a per-key origin allowlist - tracking and ad requests are only accepted from browser origins you configured for the key;
  • per-key rate limiting.
You issue and revoke tracking keys with your organization API key - see Trigger an event.

Content keys

Reading a club’s published articles from its own website has the same problem and the same answer: a publishable ck_live_… key in the page, with a per-key origin allowlist as the control. You issue content keys in the console rather than over the API. See Content API authentication.

Module credentials

Installed modules push events server-to-server via POST /v1/ingest with an mk_live_... bearer credential plus an HMAC signature header (x-4d-signature) and an Idempotency-Key. Issue this credential from an admin session after installing a private module. See Publish a private module.

Error envelope

All authenticated surfaces return errors in one envelope:
Missing or invalid credentials are a 401; a valid credential without permission for the operation is a 403 or, where the resource’s existence shouldn’t be revealed, a 404. code values are the stable contract to program against.