> For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://buildwithfern.com/learn/llms.txt. # Authentication > Configure API authentication in Fern Definition. Set up bearer tokens, basic auth, custom headers, and OAuth for your API endpoints. Fern Definition isn't recommended for new customers and Fern isn't accepting feature requests for this format. It remains supported for existing users. Configuring authentication schemes happens in the `api.yml` file. All Fern-generated SDKs support both direct configuration and environment variables for authentication credentials. ```bash {5} fern/ ├─ fern.config.json # root-level configuration ├─ generators.yml # generators you're using └─ definition/ ├─ api.yml # API-level configuration └─ imdb.yml # endpoints, types, and errors ``` To add an authentication scheme, specify the authentication method under the `auth-schemes` section. **`api.yml`** ```yaml api.yml {1-2} auth-schemes: AuthScheme: ... ``` Every scheme accepts `docs`, which appears in the API Reference's Authorization section, and `playground-docs`, which appears only beneath the scheme's input in the [API Explorer](/learn/docs/api-references/api-explorer#authentication): **`api.yml`** ```yaml api.yml {4-5} auth-schemes: Bearer: scheme: bearer docs: Use your account API token. playground-docs: Generate a short-lived token in the [dashboard](https://plantstore.example.com/tokens). ``` To apply an authentication scheme across all endpoints, reference the `auth-scheme` within the `auth` section of your `api.yml` file. **`api.yml`** ```yaml api.yml {1} auth: AuthScheme auth-schemes: AuthScheme: ... ``` ## Bearer authentication Start by defining a `Bearer` authentication scheme in `api.yml`: **`api.yml`** ```yaml api.yml auth: Bearer auth-schemes: Bearer: scheme: bearer ``` This will generate an SDK where the user would have to provide a mandatory argument called `token`. **`index.ts`** ```ts index.ts const client = new Client({ token: "ey34..." }) ``` If you want to control variable naming and the environment variable to scan, use the configuration below: **`api.yml`** ```yaml title="api.yml" {5-7} auth: Bearer auth-schemes: Bearer: scheme: bearer token: name: apiKey env: PLANTSTORE_API_KEY ``` The generated SDK would look like: **`index.ts`** ```ts index.ts // Uses process.env.PLANTSTORE_API_KEY let client = new Client(); // token has been renamed to apiKey client = new Client({ apiKey: "ey34..." }) ``` ## Basic authentication Start by defining a `Basic` authentication scheme in `api.yml`: **`api.yml`** ```yaml api.yml auth: Basic auth-schemes: Basic: scheme: basic ``` This will generate an SDK where the user would have to provide a mandatory arguments called `username` and `password`. **`index.ts`** ```ts index.ts const client = new Client({ username: "joeschmoe" password: "ey34..." }) ``` If you want to control variable naming and environment variables to scan, use the configuration below: **`api.yml`** ```yaml title="api.yml" {5-11} auth: Basic auth-schemes: Basic: scheme: basic username: name: clientId env: PLANTSTORE_CLIENT_ID password: name: clientSecret env: PLANTSTORE_CLIENT_SECRET ``` The generated SDK would look like: **`index.ts`** ```ts index.ts // Uses process.env.PLANTSTORE_CLIENT_ID and process.env.PLANTSTORE_CLIENT_SECRET let client = new Client(); // parameters have been renamed client = new Client({ clientId: "joeschmoe", clientSecret: "ey34..." }) ``` ## Custom header (e.g. API key) You can also create your own authentication scheme with customized headers. **`api.yml`** ```yaml title="api.yml" {3-5} auth: ApiKeyAuthScheme auth-schemes: ApiKeyAuthScheme: header: X-API-Key type: string ``` This will generate an SDK where the user would have to provide a mandatory argument called `apiKey`. **`index.ts`** ```ts index.ts const client = new Client({ xApiKey: "ey34..." }) ``` If you want to control variable naming and environment variables to scan, use the configuration below: **`api.yml`** ```yaml title="api.yml" {7-8} auth: ApiKeyAuthScheme auth-schemes: ApiKeyAuthScheme: header: X-API-Key type: string name: apiKey env: PLANTSTORE_API_KEY ``` The generated SDK would look like: **`index.ts`** ```ts index.ts // Uses process.env.PLANTSTORE_API_KEY let client = new Client(); // parameters have been renamed client = new Client({ apiKey: "ey34..." }) ``` ## OAuth client credentials If your API uses OAuth, you can specify an oauth scheme in `api.yml` and define a token retrieval endpoint in a separate `auth.yml` file ([example](https://github.com/fern-api/fern/blob/3137938b70e058f3691ddef34d5c1cc29acc4b80/test-definitions/fern/apis/oauth-client-credentials/definition/api.yml)). **`api.yml`** ```yaml api.yml name: api imports: auth: auth.yml auth: OAuthScheme auth-schemes: OAuthScheme: scheme: oauth type: client-credentials client-id-env: YOUR_CLIENT_ID client-secret-env: YOUR_CLIENT_SECRET get-token: endpoint: auth.getTokenWithClientCredentials request-properties: client-id: $request.client_id # Format: parameter-name: $request.property_name client-secret: $request.client_secret # Format: parameter-name: $request.property_name response-properties: access-token: $response.access_token # Format: parameter-name: $response.property_name expires-in: $response.expires_in # Format: parameter-name: $response.property_name ``` The `request-properties` and `response-properties` map OAuth standard parameters to your actual endpoint's request and response field names defined in `auth.yml`. If the `expires-in` property is set, the generated OAuth token provider will automatically refresh the token when it expires. Otherwise, it's assumed that the access token is valid indefinitely. The corresponding `auth.yml` file ([example](https://github.com/fern-api/fern/blob/3137938b70e058f3691ddef34d5c1cc29acc4b80/test-definitions/fern/apis/oauth-client-credentials/definition/auth.yml)) defines the token endpoint: **`auth.yml`** ```yaml title="auth.yml" types: TokenResponse: docs: | An OAuth token response. properties: access_token: string expires_in: integer refresh_token: optional service: auth: false base-path: / endpoints: getTokenWithClientCredentials: path: /token method: POST request: name: GetTokenRequest body: properties: client_id: string client_secret: string audience: literal<"https://api.example.com"> grant_type: literal<"client_credentials"> scope: optional response: TokenResponse ``` If your OAuth server is hosted at a different URL than your main API, you can use [multi-URL environments](/learn/api-definitions/ferndef/api-yml/environments#multiple-urls-per-environment) to specify separate base URLs for authentication and API calls. With this, all of the OAuth logic happens automatically in the generated SDKs. As long as you configure these settings, your client will automatically retrieve an access token and refresh it as needed. When using the docs playground, `token-header` and `token-prefix` can optionally be set to customize the header key name and header value prefix, to match the expected format of the API auth scheme. For example, the following would produce a header `Fern-Authorization: Fern-Bearer `: **`api.yml`** ```yaml api.yml {5-6} auth-schemes: OAuthScheme: scheme: oauth type: client-credentials token-header: Fern-Authorization token-prefix: Fern-Bearer get-token: ... ``` > Configure API authentication in Fern Definition. Set up bearer tokens, basic auth, custom headers, and OAuth for your API endpoints.