Revocation and one consent
Servers that act for many people get the standard OAuth pieces they expect: revocation, one consent for both resources, discovery that names the right resource, and a challenge header on a refused person credential.
What changed
- Token revocation.
POST /v1/oauth/revoketakes a refresh token or an access token with yourclient_idand ends that person's connection to your client, on the API and on MCP. An expired access token still works for this. It is advertised asrevocation_endpointin the authorization server metadata. - One authorization for both resources. Send
resource=https://api.layout.linkandresource=https://mcp.layout.linkon one authorize request. The person approves once, one refresh token covers both, and each token request names the one resource its access token is for. Keep one refresh token for the person, not one per resource, and refresh one at a time. - Discovery names the API.
https://api.layout.link/.well-known/oauth-protected-resourcenow describes the REST API, with"resource": "https://api.layout.link". MCP clients keep readinghttps://mcp.layout.link/.well-known/oauth-protected-resource, which has not changed. - A real
WWW-Authenticateon API refusals. A 401 from an endpoint that takes a person’s credential (places, menus, images, carts, orders, profile and whoami) now carriesWWW-Authenticateitself, withresource_metadatapointing at the API's metadata. Endpoints that take only your application secret answer 401 without it. - MCP refusals use the API's error envelope. A 401, 403 or 503 from
mcp.layout.link, before the request reaches the protocol, is now{ "error": { "code", "message" } }. TheWWW-Authenticatechallenge is unchanged. - A retried refresh keeps the connection. Retrying a refresh within 20 seconds, for instance after its response was lost, now returns a new pair instead of ending the connection.
- A disconnect stops MCP tokens at once. When a person disconnects your app, you revoke their connection, or you delete the client, an MCP access token already issued is refused on its next request, as on the API, instead of working until it expires.
curl https://api.layout.link/v1/oauth/revoke \ -d token=$REFRESH_TOKEN \ -d token_type_hint=refresh_token \ -d client_id=$CLIENT_ID 200 OK
Why it matters
When someone signs out of your product, you can end their Layout connection from your server instead of asking them to disconnect in Layout. A server that uses both the API and MCP no longer needs two consent screens. And a standard OAuth client library can now discover the API and read its challenges without special cases.
What to do
Nothing is required. To revoke on sign-out, or to ask for both resources at once, see Revoking a connection and One authorization for both. Refresh lifetimes and rotation are spelled out in Tokens and refresh.
Breaking changes
- The body of an MCP 401 was
{ "error": "unauthenticated" }and is now{ "error": { "code": "unauthorized", "message": "…" } }. If your code reads that body, switch onerror.code. MCP clients that follow theWWW-Authenticateheader are unaffected. - The API's protected resource metadata no longer names
https://mcp.layout.link. If you read MCP's metadata from the API's origin, read it fromhttps://mcp.layout.linkinstead. - An MCP access token for a disconnected person or a deleted client is now refused on its next request rather than up to ten minutes later.