> For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://buildwithfern.com/learn/llms.txt.

# What is an OpenAPI specification?

> OpenAPI is a standard for documenting REST APIs

The OpenAPI Specification (OAS) is a framework used by developers to document REST APIs. The specification is
written in JSON or YAML and contains all of your endpoints, parameters, schemas, and authentication schemes.
Fern is compatible with the latest OAS release, which is currently [v3.1.1](https://spec.openapis.org/#openapi-specification).

Below is an example of an OpenAPI file:

```yaml title="openapi.yml" maxLines=10
openapi: 3.0.2
info:
  title: Petstore - OpenAPI 3.0
  description: |-
    This is a sample Pet Store Server based on the OpenAPI 3.0 specification.
paths:
  "/pet":
    put:
      tags:
      - pet
      summary: Update an existing pet
      description: Update an existing pet by Id
      operationId: updatePet
      requestBody:
        description: Update an existent pet in the store
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/Pet"
        required: true
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Pet"
        '400':
          description: Invalid ID supplied
        '404':
          description: Pet not found
        '405':
          description: Validation exception
      security:
      - api_key
components:
  schemas:
    Category:
      type: object
      properties:
        id:
          type: integer
          format: int64
          example: 1
        name:
          type: string
          example: Dogs
    Tag:
      type: object
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
    Pet:
      required:
      - name
      - photoUrls
      type: object
      properties:
        id:
          type: integer
          format: int64
          example: 10
        name:
          type: string
          example: doggie
        category:
          "$ref": "#/components/schemas/Category"
        photoUrls:
          type: array
          items:
            type: string
        tags:
          type: array
          items:
            "$ref": "#/components/schemas/Tag"
        status:
          type: string
          description: pet status in the store
          enum:
          - available
          - pending
          - sold
  securitySchemes:
    api_key:
      type: apiKey
      name: api_key
      in: header
```

## Best practices

Follow these best practices to ensure your OpenAPI specification generates high-quality SDKs and documentation:

* **Organize with proper project structure.** Follow the instructions at [Project structure](/learn/api-definitions/overview/project-structure) to clearly organize the directories that contain your definition and other related files.
* **Add `operationId` to endpoints.** Include a clear `operationId` for each endpoint to control the function names generated in your SDKs. (Or use [extensions to customize group and method names](/learn/api-definitions/openapi/extensions/method-names).)
* **Reference schemas instead of inlining.** Define reusable schemas in the `components/schemas` section and reference them with `$ref`. This promotes consistency, reduces duplication, and makes maintenance easier.
  #### Example of referencing schemas
  ```yaml title="openapi.yml" {8, 14, 17-25}
  paths:
    /pets:
      post:
        requestBody:
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Pet'  # Clean reference
        responses:
          '200':
            content:
              application/json:
                schema:
                  $ref: '#/components/schemas/Pet'  # Reused easily
  components:
    schemas:
      Pet:                        # Defined once, used everywhere
        type: object
        properties:
          name:
            type: string
          status:
            type: string
            enum: [available, pending, sold]
  ```
* **Use overlays and Fern extensions for customization.** Customize your specification using Fern [extensions](/learn/api-definitions/openapi/extensions/overview) housed in an [overlay file](/learn/api-definitions/openapi/overlays). This lets you modify generation behavior without changing your core OpenAPI definition.

Once your OpenAPI spec follows these practices, you're ready to set up your fern folder.

## Set up your fern folder

Start by initializing your fern folder with an OpenAPI spec

```sh file
fern init --openapi ./path/to/openapi
```

```sh url
fern init --openapi https://host/path/to/openapi
```

This will initialize a directory like the following: