# Examples in Fern Definition

> Use Fern Definition to add API examples that are shown in comments of SDKs, API Reference documentation, and a Postman collection.

You can add examples for types and endpoints. Examples are shown as
comments in your SDKs, in the request & response of your documentation,
and in a Postman Collection.

## Validation

The Fern CLI validates that your examples match the expected types. The following won't compile:

```yaml
types:
  UserId:
    type: integer
    examples:
      - value: hello # not an integer
```

```bash CLI Error Message
[api]: example.yml -> types -> UserId -> examples[0]
       Expected example to be an integer. Example is: "hello"
```

## Referencing examples

You can reference an example from another type, endpoint, or error.

Just like types, you can compose examples. To reference an example from another
type, use `$`.

```yaml {14}
types:
  UserId:
    type: integer
    examples:
      - name: Example1
        value: user-id-123

  User:
    properties:
      id: UserId
      name: string
    examples:
      - value:
          id: $UserId.Example1
          name: Jane Smith
```

## Examples for types

### Objects

```yml
types:
  ShipTo:
    properties:
      street1: string
      street2: optional<string>
      city: string
      state: string
      postalCode: string
      country: Country
      isResidential: boolean
    examples:
      - name: WhiteHouse
        value:
          street1: 1600 Pennsylvania Avenue NW
          city: Washington DC
          state: Washington DC
          postalCode: "20500"
          country: US
          isResidential: true
      - name: EmpireStateBuilding
        value:
          street1: 350 5th Ave
          street2: Attn: Maintenance Department
          city: New York
          state: NY
          postalCode: "10118"
          country: US
          isResidential: false
```

<CodeBlock title="Generated TypeScript SDK">
  ```typescript
  /**
   * Represents a shipping address.
   * 
   * The White House address
   * @example {
   *  street1: "1600 Pennsylvania Avenue NW",
   *  city: "Washington DC",
   *  state: "Washington DC",
   *  postalCode: "20500",
   *  country: "US",
   *  isResidential: true
   * }
   * 
   * * The Empire State Building address
   * @example {
   *  street1: "350 5th Ave",
   *  street2: "Attn: Maintenance Department",
   *  city: "New York",
   *  state: "NY",
   *  postalCode: "10118",
   *  country: "US",
   *  isResidential: false
   * }
   */
  type ShipTo = {
    street1: string;
    street2?: string;
    city: string;
    state: string;
    postalCode: string;
    country: Country;
    isResidential: boolean;
  };
  ```
</CodeBlock>

### Lists

```yml
 Shipments:
    type: list<ShipmentStatus>
    examples:
      - name: Default
        value:
          - status: "InTransit"
            estimatedDeliveryDate: "2024-01-11"
          - status: "Delivered"
            estimatedDeliveryDate: "2024-01-13"
```

### Unions

#### Discriminated union

```yml
types:
  Animal:
    union:
      dog: Dog
      cat: Cat
    examples:
      - value:
          type: dog
          likesToWoof: true
  Dog:
    properties:
      likesToWoof: boolean
  Cat:
    properties:
      likesToMeow: boolean
```

<CodeBlock title="Generated TypeScript SDK">
  ```typescript
  /**
   * Represents an animal, which can be either a Dog or a Cat.
   *
   * Example of a Dog:
   * @example {
   *  type: "dog",
   *  likesToWoof: true
   * }
   */
  type Animal = Dog | Cat;
  ```
</CodeBlock>

#### Undiscriminated union

```yml
types:
  Animal:
    discriminated: false
    union:
      - Dog
      - Cat
    examples:
      - value:
          likesToMeow: true
  Dog:
    properties:
      likesToWoof: boolean
  Cat:
    properties:
      likesToMeow: boolean
```

<CodeBlock title="Generated TypeScript SDK">
  ```typescript
  /**
   * Represents an Animal, which can be either a Dog or a Cat.
   *
   * Example of an Animal as a Cat:
   * @example {
   *  likesToMeow: true
   * }
   */
  type Animal = Dog | Cat;
  ```
</CodeBlock>

### Aliases

```yml
types:
  UserId:
    docs: A unique identifier for a user
    type: string
    examples:
      - value: user-id-123
```

<CodeBlock title="Generated TypeScript SDK">
  ```typescript
  /** 
  * A unique identifier for a user * 
  * @example "user-id-123" 
  */ 
  type UserId = string; 
  ```
</CodeBlock>

## Examples for endpoints

You can add examples of successful and error responses for your endpoints.
Examples can reference the examples of types to avoid duplication.

```yml
service:
  auth: true
  base-path: ""
  endpoints:
    CreateShippingLabel:
      docs: Create a new shipping label.
      method: POST
      path: /shipping
      request: CreateShippingLabelRequest
      response: ShippingLabel
      errors:
        - NotAuthorized
        - InsufficientFunds
      examples:
        # A successful response that doesn't reference other examples.
        - request:
            orderId: "online_789"
            weightInOunces: 5
          response:
            body:
              orderId: "online_789"
              weightInOunces: 5
              trackingNumber: "1Z26W8370303469306"
              price: 2.50

        # A successful response that uses references.
        - request: $CreateShippingLabelRequest.SuccessfulRequest
          response:
            body: $ShippingLabel.Default

        # An error response.
        - request: $CreateShippingLabelRequest.InsufficientFundsRequest
          response:
            error: InsufficientFunds
            body: $InsufficientFundsBody.Default

types:
  CreateShippingLabelRequest:
    properties:
      orderId: string
      weightInOunces: integer
    examples:
      - name: SuccessfulRequest
        value:
          orderId: "online_123"
          weightInOunces: 13
      - name: InsufficientFundsRequest
        value:
          orderId: "online_456"
          weightInOunces: 2000

  ShippingLabel:
    properties:
      orderId: string
      weightInOunces: integer
      trackingNumber: string
      price: double
    examples:
      - name: Default
        value:
          orderId: "online_123"
          weightInOunces: 13
          trackingNumber: "1Z12345E0205271688"
          price: 12.35

  InsufficientFundsBody:
    properties:
      message: string
    examples:
      - name: Default
        value:
          message: "Insufficient funds to create shipping label."

errors:
  NotAuthorized:
    status-code: 401
  InsufficientFunds:
    status-code: 422
    type: InsufficientFundsBody
```

### Examples with headers

When you have [global headers defined in your `api.yml`](/api-definitions/ferndef/api-yml/global-headers#global-headers), you must include them in your examples:

```yml {15-16}
service:
  auth: true
  base-path: ""
  endpoints:
    CreateShippingLabel:
      docs: Create a new shipping label.
      method: POST
      path: /shipping
      request: CreateShippingLabelRequest
      response: ShippingLabel
      errors:
        - NotAuthorized
        - InsufficientFunds
      examples:
        - headers:
            X-App-Id: "app_12345"
          request:
            orderId: "online_789"
            weightInOunces: 5
          response:
            body:
              orderId: "online_789"
              weightInOunces: 5
              trackingNumber: "1Z26W8370303469306"
              price: 2.50
```

## Examples for path parameters

```yml
service:
  auth: true
  base-path: ""
  endpoints:
    TrackShipment:
      docs: Track the status of a shipment.
      method: GET
      path: /shipping/{trackingNumber}
      path-parameters: 
        trackingNumber: string
      response: ShipmentStatus
      examples:
        - path-parameters: 
            trackingNumber: "1Z26W8370303469306"
          response:
            body:
              status: "InTransit"
              estimatedDeliveryDate: "2024-01-11"
```