Authentication & API keys

Mint API keys, understand scopes, rate-limit tiers, and enable write access.

Requests to the JOGL Network API are authenticated one of two ways: a personal API key (for REST, and for MCP clients that are not connected over OAuth), or a short-lived OAuth access token issued through the WorkOS AuthKit connector (the one-click MCP connector path, see MCP server). Keys are minted by you, for you, and inherit your rights at the time each call is made.

Minting a key

Go to Settings → API/MCP in the app and create a key. A key belongs to your personal billing owner and carries exactly your own rights, which are not the same for reading and writing:

  • Reading — every non-archived community you belong to, in any role, plus any non-archived community owned by an organization you manage. Ordinary membership is enough; you do not have to be an admin. Archiving a community takes it out of the key's reach even though your membership row survives, so a read against it returns 403 and scope: "all" simply omits it.
  • Writing — only where you are an admin or owner of the community, directly or through an organization that owns it. See Enabling write access below.

A new key always reaches that whole set: attaching a community allowlist to narrow it is no longer supported, and a create request that carries one is rejected with 400. A key created earlier with an allowlist keeps it, and it still narrows that key (never expands it).

Keys are always personal. Organization-owned keys can no longer be created; a legacy org-owned key that already exists keeps working until you revoke it, but it never inherits its minter's personal community-admin rights (it acts on ownership only).

The full secret is shown once, at creation, and is never recoverable afterwards. Store it somewhere safe. Only a hash and a display prefix (e.g. jogl_live_AbCd1234) are kept. Revoke a leaked key in Settings; revocation takes effect on the next request.

Keys are prefixed jogl_live_ (live) or jogl_test_ (test). The prefix is a label, not a boundary — a jogl_test_ key reads and writes the same data as a live one on the deployment that minted it. See the warning on the API keys page.

Presenting a key

Send the key on every request as either header:

Authorization: Bearer jogl_live_…
X-API-Key: jogl_live_…

Scopes

Scopes are chosen at mint time. Most come in two tiers; self:enrich, contact:write, notes:read, notes:write and settings:write, described after the tables, are in neither.

Read tier — mintable by any signed-in user, no attestation:

ScopeGrants
search:readExpert search
profile:readRead your own profile, the people you know, and a community's roster, members, event attendee lists and analytics
enrich:readPoll enrichment run status
history:readRead your own past searches, including searches made in the app

Write tier — needs the community billing owner's Write access on, which it is by default (see below):

ScopeGrants
member:writeAdd people to a community you control, and community-scoped erasure
enrich:writeStart enrichment on members of a community you control
community:writeCreate a community you own and pay for
crm:writeMap and run the syncs of the CRMs connected to a community you control (creating the community fields a mapping needs and choosing who sees them), and make a link to connect one (never a CRM key)

self:enrich (enrich your own profile, target-locked) is also mintable by any signed-in user with no attestation, but because it starts a billable side effect it is not part of the one-click Read preset in the create-key UI — select it explicitly under Advanced. A plain "Read" key can't call POST /v1/me/enrich.

contact:write (send members direct messages in JOGL as you, and ask attendees of events you attend for meetings, each one previewed before it is sent; see Direct messages and Meeting requests) is the same: mintable by any signed-in user with no attestation, in neither preset, selected under Advanced. It needs a key of your own; a legacy organization-owned key cannot send, since a message or a request goes out under a person's name. Of the write checks below, it needs only your own account's Write access (check 2, read for your account rather than a community's owner): while it is off, every send, preview and slot listing returns 422 unprocessable. The community checks do not apply, since a send changes no community's data: whether a member can be messaged follows their own message settings, and whether an attendee can be asked for a meeting follows the event, as in the app (a block between you and them, made by either of you, refuses both), so turning a community's API writes off does not stop it.

community:write creates a community owned by you and billed to you, as the app's New community page does (see Creating a community). It needs a key of your own with no community allowlist, and of the write checks below only your own account's Write access (check 2, read for your account), since the community does not exist yet: while it is off, the call returns 422 unprocessable. Your free trial or plan must cover the new community. The API cannot start a trial, so without one the call returns 402 coverage_required with a link to the app.

crm:write maps and runs the syncs of the CRMs (Airtable, HelloAsso, Odoo) a community admin connected in the app, on the key that connection saved (see CRM syncs). It takes the same write checks as adding members. No route or tool takes or returns a CRM key: connecting a CRM, or reconnecting one whose key no longer works, is done by an admin of the community who types the key on a JOGL page, in the app or on the page a connect link opens.

notes:read and notes:write (read the private notes you keep on people's profile pages in the app, and add one as you; see Private notes) are the same again: mintable by any signed-in user with no attestation, in neither preset, selected under Advanced, and only on a key of your own. They reach only the people you can see in JOGL, and a note in which AI structuring marked a detail as sensitive comes back withheld. A note never run through AI structuring comes back as you wrote it, so tick notes:read only for an agent you would show your notes to. Adding a note needs only your own account's Write access, as contact:write does.

settings:write (change some of your own settings as you: who can see your profile, who can message you or send you connection requests, the notification and admin-reminder emails JOGL sends you, and turning on the use of your notes as context; see Account settings) is the same again: mintable by any signed-in user with no attestation, in neither preset, selected under Advanced, and only on a key of your own. It changes nobody else's settings, and none of those that stay in the app (write access itself, data residency, billing, keys, deleting your account). A profile can be made public only once JOGL has verified your account. Like adding a note, a change needs only your own account's Write access. Reading those settings needs profile:read, and the notes switch notes:read. Turning your notes as context off needs only notes:write; turning it on needs settings:write as well.

Enabling write access (attestation)

Carrying member:write or enrich:write is not enough. Those writes are gated at use time by three checks:

  1. Ownership or community-admin — your billing owner must be the target community's billing owner, or — for a personal (user-owned) key only — your owner must be an admin of the community. A legacy organization-owned key never gets that second path (see above): it acts on ownership alone, so it still gets 403 for a community its organization does not own, even when the person who minted it administers that community. The delegated-admin path applies to all three community writes — adding members (member:write), starting enrichment (enrich:write), and member erasure — unless the community's billing owner has turned off check 2 or check 3.
  2. Write access — the community's billing owner's Write access must be on. It is on by default, and an owner can turn it off; turning it back on records a versioned, auditable attestation.
  3. The community's admin switch, when you reach the community as an admin rather than as its owner. Its switch, Admins can write through the API, is on by default for every community; its owner can turn it off in the API & AI tools section of the community's admin dashboard or under Settings → API/MCP → Write access → Community admins. While it is off, an admin's write call returns 422 unprocessable; the owner's own calls do not need it.

The owners and admins of the organization that pays for a community act as its owner while they hold one of the organization's seats, so they need only check 2. Write access is in Settings → API/MCP → Write access. While it is off, write calls return 422 unprocessable. When the just-in-time consent feature is switched on for your account, a call refused by check 2 returns 422 owner_consent_required instead and queues a consent request the owner can approve under API write requests in Settings → API/MCP; retrying the same call after approval then succeeds. A call refused by check 3 is not queued: approval would not change the community's admin switch.

Rate limits

Each key has a per-minute token bucket. For an API key, the tier is decided when the key is minted and stored on the key, so upgrading your plan later does not change an existing key — mint a new one. An OAuth connector follows your account instead: its tier is read again at every call, so it moves to the standard tier on the next call once you are privileged, and back to the restricted tier if you stop being privileged (calls you already made that UTC day still count, so past the 20th you wait until midnight UTC). You never need to reconnect for it.

  • Restricted (free) tier — 2 requests/min, burst 5, and a hard 20/day cap (the day is UTC). This is the default for an owner who is not privileged.
  • Standard tier — the requested rate (default 60/min), full burst, and no daily cap. You are privileged when any of these holds (for an API key, at mint time): your billing owner is an organization; your owner has an active paid plan (a free trial does not count); you are the owner or admin of at least one community; or you are an owner or admin of an organization that owns at least one community, which carries the same tier your retired org-owned key used to get. An OAuth connector is also on the standard tier, at 60/min, when you are a member of a community whose owner has bought a plan (a free trial or a complimentary plan does not count, nor does an archived community or one that anyone can join without approval). An API key is not tiered that way.

Every REST request counts against the limit. Over MCP only a tool call counts: connecting, listing tools and other protocol messages are free, so a new chat does not spend part of the day's calls before the first tool runs. GET /v1/me and the MCP get_me tool return your limits and today's count under limits.

Don't hardcode a rate — read the RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset headers on every authenticated response and pace off RateLimit-Remaining. Exceeding the limit returns 429 with a Retry-After header.

OAuth (one-click connectors)

Instead of a static key, an MCP client can connect via OAuth (WorkOS AuthKit). The bearer token is then a short-lived JWT rather than a jogl_* key. Authorization is always re-checked against live key state, so revoking a grant takes effect immediately. See MCP server.

A connector approved on its consent screen gets the read scopes and the write tier (member:write, enrich:write, community:write, which every connector that already held the write tier also received when it was added, and crm:write, which a connector made before it was added gains only from its card, below): the screen lists them and the write attestation, and approving it accepts that attestation for your personal account, which turns API write access on for that account. Its read scopes include history:read only when it was approved after that scope was switched on for connections (see MCP server), and a connector never carries self:enrich: self-enrichment needs a static key. A connector approved on a consent screen that also lists sending members messages and meeting requests, as every screen has since that permission was added, carries contact:write beside the write tier; one approved on an earlier screen does not, and a reconnect may keep the original approval. Its card under Settings → API/MCP → Connected apps then offers Add new permissions, which adds contact:write, while write is on for the connector, once you approve; revoking it there and connecting the client again also works. The same card offers crm:write, while write is on, to a connector made before that scope was added. The private notes work the same way: a connector approved on a screen that lists reading and adding your private notes carries notes:read, and notes:write beside the write tier; one approved on an earlier screen carries neither until you add them from its card, or revoke it and connect again. A connector approved on a screen that lists changing your own settings carries settings:write beside the write tier; one approved on an earlier screen gains it from its card, while write is on for it. Its writes are still gated at use time by the three checks above. To make a connector read-only, turn write off on it under Settings → API/MCP → Connected apps once it has connected; that takes contact:write, notes:write and settings:write off too, and keeps notes:read. Turning write back on gives back each of those three the connector held when you turned it off, including one you added from its card. A connector approved before, or in the hour after, full access became the default stays read-only until you turn write on there. The assistant can tell you when its connection can be given more: get_me lists those permissions under connection.new_permissions with a link, connection.add_permissions_url, that opens the connector's Add new permissions dialog in JOGL, where you approve them with one click. The assistant cannot add them itself.

Sur cette page