> For the complete documentation index, see [llms.txt](https://docs.floral.fun/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.floral.fun/authentication/floral-connect.md).

# Floral Connect (OAuth 2.0)

Floral Connect uses the OAuth 2.0 authorization code flow with mandatory PKCE.

1. Your site redirects the user to `GET /oauth/authorize`.
2. The user signs in on `auth.floral.fun`, if needed, and approves or cancels. They don't need the Floral app installed, and someone new to Floral can create an account there. Floral asks for approval every time, even if the user connected before.
3. Floral redirects to your `redirect_uri` with `code` and `state`, or with `error=access_denied` if they cancelled.
4. Your server exchanges the code at `POST /oauth/token`.

Server metadata for OAuth libraries is at `https://api.floral.fun/.well-known/oauth-authorization-server`.

## Authorization parameters

| Parameter               | Required    | Notes                                                                                                                    |
| ----------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------ |
| `response_type`         | Yes         | `code`                                                                                                                   |
| `client_id`             | Yes         |                                                                                                                          |
| `redirect_uri`          | Yes         | Must exactly match a registered URL                                                                                      |
| `code_challenge`        | Yes         | Base64url SHA-256 of your verifier, 43 characters. The verifier is 43 to 128 characters of letters, digits and `- . _ ~` |
| `code_challenge_method` | Yes         | `S256`. `plain` isn't supported                                                                                          |
| `scope`                 | No          | Space-separated. Defaults to `profile:read`                                                                              |
| `state`                 | Recommended | Returned unchanged. Use it to protect against CSRF. Up to 1024 characters: a longer value isn't returned                 |

If the `client_id` or `redirect_uri` is invalid, Floral returns `400` with `invalid_client` or `invalid_redirect_uri` and doesn't redirect. Other problems return to your `redirect_uri` with `error`, `error_description` and `state`.

## Client authentication

**Confidential clients** send `client_id` and `client_secret` to `/oauth/token` and `/oauth/revoke`, using HTTP Basic or body parameters.

**Public clients** run in a browser or mobile app and can't keep a secret. They send only `client_id` in the body, and PKCE protects the exchange. Sending a secret from a public client returns `invalid_client`, and they can't use `client_credentials`.

```bash
curl https://api.floral.fun/oauth/token \
  -d grant_type=authorization_code \
  -d client_id="$CLIENT_ID" \
  -d code="$CODE" \
  -d redirect_uri=https://yourapp.example/callback \
  -d code_verifier="$VERIFIER"
```

Requests may be form-encoded or JSON.

## Grant types

| `grant_type`         | Parameters                                 | Returns                                                                                    |
| -------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------ |
| `authorization_code` | `code`, `redirect_uri`, `code_verifier`    | Access and refresh tokens for the user                                                     |
| `refresh_token`      | `refresh_token`, optional narrower `scope` | A new access and refresh token                                                             |
| `client_credentials` | None                                       | An [app token](/authentication/scopes-and-tokens.md#app-tokens). Confidential clients only |

## Refresh a token

```bash
curl https://api.floral.fun/oauth/token \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d grant_type=refresh_token \
  -d refresh_token="$REFRESH_TOKEN"
```

The response has the same shape as the first token response, with a new `refresh_token`. Replace your stored one. See [Refresh token rotation](/authentication/scopes-and-tokens.md#refresh-token-rotation).

## Get an app token

```bash
curl https://api.floral.fun/oauth/token \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d grant_type=client_credentials
```

```json
{ "access_token": "flr_ct_...", "token_type": "Bearer", "expires_in": 3600, "scope": "" }
```

The response has no `refresh_token`, and `scope` is empty because an app token isn't tied to a user. Request a new one when it expires.

## Revoke a token

```bash
curl https://api.floral.fun/oauth/revoke \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d token="$REFRESH_TOKEN"
```

## Disconnection

Users can disconnect your platform at any time at [floral.fun/connected-apps](https://floral.fun/connected-apps). All your tokens for that user stop working immediately, and refreshing returns `invalid_grant`. Treat that as "not connected" and offer Connect Floral again.

To stop using a connection from your side, send the refresh token to `POST /oauth/revoke`. It returns `200` with an empty object whether or not the token existed. Revoking a refresh token also ends the access tokens from that sign-in, while revoking an access token ends only that token.

This doesn't remove your platform from the user's Connected Apps, so an app token can still verify that user until they disconnect. To get new user tokens, send the user through Floral Connect.

See [Errors](/developer-resources/errors.md#oauth-errors) for what each OAuth error means.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.floral.fun/authentication/floral-connect.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
