Developers
OAuth sign-in
AI clients sign in to Bonnard with OAuth: a person approves access in the browser, and the client gets tokens for one connection URL. A person signs in with a workspace or customer account. No admin step comes first.
Verified 9 Nov 2026.
Endpoints
Each path is on https://app.bonnard.ai.
| Endpoint | Path | Purpose |
|---|---|---|
| Connection URL | /mcp | Serves the MCP tools |
| Protected resource metadata | /.well-known/oauth-protected-resource/mcp | Names the authorization server and scopes |
| Authorization server metadata | /.well-known/oauth-authorization-server | Gives the URL of each endpoint |
| Client registration | /reg | Registers a client |
| Authorization | /auth | Starts the sign-in |
| Token | /token | Issues and refreshes tokens |
| Public keys | /jwks | Gives the keys that sign access tokens |
| Revocation | revocation_endpoint in the metadata | Ends a token (RFC 7009) |
| UserInfo | /me | Returns the signed-in person’s claims |
| Pushed authorization | /request | Takes an authorization request before the redirect |
| Client management | /reg/<client id> | Reads, updates, or deletes a registration |
| OpenID configuration | /.well-known/openid-configuration | Gives the URL of each endpoint |
Connection URLs
| URL | Connects to |
|---|---|
https://app.bonnard.ai/mcp | The workspace or company the person selects at sign-in |
https://app.bonnard.ai/mcp/o/<org id> | One workspace, named by its id |
https://app.bonnard.ai/mcp/<slug> | One older app address |
Each URL needs its own sign-in, because Bonnard binds a token to the URL it was issued for.
Discovery
A request with no token gets HTTP 401 and this header:
WWW-Authenticate: Bearer resource_metadata="https://app.bonnard.ai/.well-known/oauth-protected-resource/mcp", scope="openid"The document at that URL gives resource, authorization_servers, bearer_methods_supported, and scopes_supported.
For /mcp/o/<org id>, the URL of that document ends in /mcp/o/<org id>. The client then reads
/.well-known/oauth-authorization-server for the endpoints.
Client registration
A client registers in one of two ways:
- Dynamic Client Registration:
POSTto/regwith no access token. The limit is 10 requests a minute for each IP address, and more returnrate_limited(HTTP 429). - Client ID Metadata Document: use an HTTPS URL as
client_id. Bonnard refuses an IP address or a local name as its host.
A redirect URI with a custom scheme or a loopback address registers as a native client. Bonnard deletes a registered client after 7 days if it has no grant.
Authorization
- Flow: authorization code. Each request must send PKCE.
resource: send one value, the connection URL. Bonnard refuses a workspace URL beside another resource withinvalid_target.- Scopes:
openid,profile,email, andoffline_access.
Tokens
| Token | Lifetime | Behaviour |
|---|---|---|
| Access | 15 minutes | A JWT bound to the connection URL |
| Refresh | 30 days | Replaced at each use. A used token works for 60 seconds more, so a client can retry a lost response |
| Grant | 30 days | Refresh does not extend it, so the person signs in again after 30 days |
A client gets a refresh token if it registered the refresh grant, with or without offline_access.
Refusals
These are the common refusals. Errors has all codes.
| Code | HTTP status | When |
|---|---|---|
invalid_token | 401 | The token or API key is not valid |
access_forbidden | 403 | The person has no access to the data source at an older /mcp/<slug> address |
workspace_forbidden | 403 | The person is not in this workspace, or the token is for another workspace |
Protocol errors
The authorization and token endpoints answer with these OAuth codes.
| Code | Endpoint | When |
|---|---|---|
invalid_target | /auth, /token | resource names an unknown URL, or a workspace URL beside another resource |
invalid_request | /token | HTTP 400. Bonnard cannot read the body, for example a body over 56 KB |
invalid_grant | /token | The refresh token or the grant ended. The person signs in again |