Custom connections (not yet available)¶
If you're integrating your own organisation's LuciBook — no third-party end user, no consent screen — a custom connection using the OAuth 2.0 client-credentials grant is designed to be the lighter-weight option. It is not available yet.
Not yet available — contact support to register interest
Custom connections (client-credentials) are not live in this release:
there is no self-service way to register a client-credentials
application today, and no request against /oauth/token/ with
grant_type=client_credentials can currently be turned into a working
connection to an organisation. This page describes the intended design
so you can plan for it. Contact support if you want to register
interest or be notified when it ships — this page will be updated at
that point.
How it's designed to work¶
An OWNER or ADMIN of the one organisation you're integrating consents once
(no per-scope end-user picker — a custom connection either exists for the
org or it doesn't). If a custom connection already exists for that (app,
org) pair, granting a second one is designed to fail with
custom_connection_exists; if none exists yet and something expects one,
custom_connection_missing.
Getting a token (preview — not usable yet, see the callout above)¶
The intended request shape, once this ships:
POST /oauth/token/
Authorization: Basic base64(client_id:client_secret)
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
scope=<space-separated scopes>
curl -s https://api.lucibook.co.uk/oauth/token/ \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-d grant_type=client_credentials \
-d scope="bills:read invoices:read"
A successful response is the same token-response shape every grant type returns:
{
"access_token": "…",
"token_type": "Bearer",
"expires_in": 1800,
"scope": "bills:read invoices:read"
}
There is no refresh token for client-credentials — request a new access
token when the old one expires. As with the authorization-code flow,
authenticate with HTTP Basic (-u client_id:client_secret); body-post
credentials work as a fallback, same as
described for authorization-code.
The grantor hostage warning¶
Whoever granted the custom connection is now load-bearing: if they leave the
organisation or are demoted below a granted scope's minimum role tier, calls
using that scope start failing insufficient_role — live, not at token
issue (see Connections — effective scope).
An organisation should not let its only OWNER be the sole grantor of a
business-critical custom connection.
There is no "replace the grantor" operation planned. A connection records who granted it, and that cannot be repointed to a different user after the fact — only its granted scopes can be updated, by the same grantor consenting again. If the grantor's own access changes and you need a new one, the fix is a fresh consent by the new grantor, not an edit to the existing connection.
Two-secret rotation with grace¶
Rotating your client secret never invalidates a token already issued, and
never causes a mid-rotation outage: the OLD secret keeps authenticating
alongside the NEW one until a grace window elapses
(developer.secret_rotation_grace_days, see the
rate limits / policy defaults table). Rotate, deploy the
new secret everywhere, then let the old one lapse — no downtime window to
coordinate.