# Endpoints in Fern Definition

> Organize related API endpoints into a service in Fern Definition and define each endpoint's URL, HTTP method, request, response, errors, and more.

In Fern, you organize related endpoints into a **Service**. This grouping
improves clarity and makes the generated SDKs more idiomatic.

## Service definition

Each service defines:

1. A **base-path**: A common prefix for all the endpoints' HTTP paths
2. Whether the service requires [authentication](/learn/api-definition/fern/authentication)
3. **Endpoints**

<CodeBlock title="user.yml">
  ```yaml
    service: 
      base-path: /users 
      auth: false 
      endpoints: {}
  ```
</CodeBlock>

<Info>
  To define a service with an empty base path use the empty string: `base-path: ""`
</Info>

### Section display name

By default, section names in your API Reference come from service file names (e.g., `user.yml` becomes "User"). To override the display name of a section, [use the `section` property in your `docs.yml`](/docs/api-references/customize-api-reference-layout#renaming-sections).

## Endpoints

An endpoint includes:

* A **URL path** *(Optionally including path parameters)*
* A **Display Name** *(Optional)*
* An **HTTP Method**
* **Request information** *(Optional)*
  * **Query-parameters**
  * **Headers**
  * **Request body**
* **Successful (200) response** information *(Optional)*
* **Error (non-200) responses** that this endpoint might return *(Optional)*

### URL path

Each endpoint has a URL path.

<CodeBlock title="user.yml">
  ```yaml {6}
  service:
    base-path: /users
    auth: false
    endpoints:
      getAllUsers:
        path: /all
        method: GET
  ```
</CodeBlock>

The full path for the endpoint is the concatenation of:

* The [environment](/learn/api-definition/fern/api-yml/environments) URL
* The service `base-path`
* The endpoint `path`

### Endpoint display name

The display name will appear as the title of an endpoint. By default, the display name is equal to the 'Title Case' of the endpoint name. If you would like to customize the endpoint name, you can **set the display name**.

In the example below, ["Add a new plant to the store"](https://plantstore.dev/api-reference/plant-store-api/plants/add-plant) displays as the title of the endpoint page within the API Reference.

<CodeBlock title="user.yml">
  ```yaml {7}
  service:
    base-path: /v3
    auth: false
    endpoints:
      addPlant:
        path: /plant
        display-name: Add a new plant to the store
        method: POST
  ```
</CodeBlock>

### Path parameters

Supply path parameters for your endpoints to create dynamic URLs.

<CodeBlock title="user.yml">
  ```yaml {6-8}
  service:
    base-path: /users
    auth: false
    endpoints:
      getUser:
        path: /{userId} 
        path-parameters: 
          userId: string
        method: GET
  ```
</CodeBlock>

Services can also have path-parameters:

<CodeBlock title="project.yml">
  ```yaml {2-4}
  service: 
    base-path: /projects/{projectId}
    path-parameters: 
      projectId: string 
    auth: false 
    endpoints: 
      ...
  ```
</CodeBlock>

### Query parameters

Each endpoint can specify query parameters:

<CodeBlock title="user.yml">
  ```yaml
  service:
    base-path: /users
    auth: false
    endpoints:
      getAllUsers:
        path: /all
        method: GET
        request:
          # this name is required for idiomatic SDKs
          name: GetAllUsersRequest
          query-parameters:
            limit: optional<integer>
  ```
</CodeBlock>

#### `allow-multiple`

Use `allow-multiple` to specify that a query parameter is allowed
multiple times in the URL, as in `?filter=jane&filter=smith`. This will alter
the generated SDKs so that consumers can provide multiple values for the query
parameter.

<CodeBlock title="user.yml">
  ```yaml {5}
    ...
    query-parameters:
      filter:
        type: string
        allow-multiple: true
  ```
</CodeBlock>

### Auth

Each endpoint can override the auth behavior specified in the service.

<CodeBlock title="user.yml">
  ```yaml
  service: 
    base-path: /users 
    auth: false 
    endpoints: 
      getMe: 
        path: "" 
        method: GET 
        # This endpoint will be authed 
        auth: true 
        docs: Return the current user based on Authorization header. 
  ```
</CodeBlock>

### Headers

Each endpoint can specify request headers:

<CodeBlock title="user.yml">
  ```yaml
  service: 
    base-path: /users 
    auth: false 
    endpoints: 
      getAllUsers: 
        path: /all
        method: GET 
        request: 
          # this name is required for idiomatic SDKs name:
          name: GetAllUsersRequest 
          headers: 
            X-Endpoint-Header: string
  ```
</CodeBlock>

Services can also specify request headers. These headers will cascade to the service's endpoints.

<CodeBlock title="user.yml">
  ```yaml {4-5} 
  service: 
    base-path: /users 
    auth: false 
    headers: 
      X-Service-Header: string 
    endpoints: 
      getAllUsers: 
        path: /all 
        method: GET 
        request: 
          # this name is required for idiomatic SDKs 
          name: GetAllUsersRequest 
          headers: 
            X-Endpoint-Header: string
  ```
</CodeBlock>

### Request body

Endpoints can specify a request body type.

<CodeBlock title="user.yml">
  ```yaml {10}
  service:
    base-path: /users
    auth: false
    endpoints:
      setUserName:
        path: /{userId}/set-name
        path-parameters:
          userId: string
        method: POST
        request: string
  ```
</CodeBlock>

#### Inlining a request body

If the request body is an object, you can **inline the type declaration**. This
makes the generated SDKs a bit more idiomatic.

<CodeBlock title="user.yml">
  ```yaml
  service: 
    base-path: /users 
    auth: false 
    endpoints: 
      createUser: 
        path: /create 
        method: POST 
        request: 
          # this name is required for idiomatic SDKs 
          name: CreateUserRequest 
          body: 
            properties: 
              userName: string
  ```
</CodeBlock>

### Success response

Endpoints can specify a `response`, which is the type of the body that will be
returned on a successful (200) call.

<CodeBlock title="user.yml">
  ```yaml
  service:
    base-path: /users
    auth: false
    endpoints:
      getAllUsers:
        path: /all
        method: GET
        response: list<User>

  types:
    User:
      properties:
        userId: string
        name: string
  ```
</CodeBlock>

### Response status codes

You can also use the `status-code` field to specify a custom status code
for a success response.

<CodeBlock title="user.yml">
  ```yaml {11}
  service:
    base-path: /users
    auth: false
    endpoints:
      create: :
        path: ""
        method: POST
        request: CreateUserRequest
        response: 
          type: User
          status-code: 201

  types:
    User:
      properties:
        userId: string
        name: string
  ```
</CodeBlock>

### Error responses

Endpoints can specify error responses, which detail the non-200 responses that
the endpoint might return.

<CodeBlock title="user.yml">
  ```yaml
  service:
    base-path: /users
    auth: false
    endpoints:
      getUser:
        path: /{userId}
        path-parameters:
          userId: string
        method: GET
        response: User
        errors:
          - UserNotFoundError

  types:
    User:
      properties:
        userId: string
        name: string

  errors:
    UserNotFoundError:
      status-code: 404
  ```
</CodeBlock>

You can learn more about how to define errors on the [Errors](/learn/api-definition/fern/errors) page.

## Specifying examples

When you declare an example, you can also specify some examples of how that
endpoint might be used. These are used by the compiler to enhance the generated
outputs. Examples will show up as comments in your SDKs, API documentation, and Postman collection.

You may add examples for endpoints, types, and errors.

<CodeBlock title="user.yml">
  ```yaml {13-19}
  service:
    base-path: /users
    auth: false
    endpoints:
      getUser:
        path: /{userId}
        path-parameters:
          userId: string
        method: GET
        response: User
        errors:
          - UserNotFoundError
        examples:
          - path-parameters:
              userId: alice-user-id
            response:
              body:
                userId: alice-user-id
                name: Alice

  types:
    User:
      properties:
        userId: string
        name: string

  errors:
    UserNotFoundError:
      status-code: 404
  ```
</CodeBlock>

If you're adding an example to an endpoint and the type already has an example, you can reference it using `$`.

```yaml
service:
  auth: true
  base-path: /address
  endpoints:
    create:
      method: POST
      path: ""
      request: CreateAddress
      response: Address
      examples:
        - request: $CreateAddress.WhiteHouse
          response:
            body: $Address.WhiteHouseWithID

  CreateAddress:
    properties:
      street1: string
      street2: optional<string>
      city: string
      state: string
      postalCode: string
      country: string
      isResidential: boolean
    examples:
      - name: WhiteHouse
        value:
          street1: 1600 Pennsylvania Avenue NW
          city: Washington DC
          state: Washington DC
          postalCode: "20500"
          country: US
          isResidential: true

  Address:
    extends: CreateAddress
    properties:
      id:
        type: uuid
        docs: The unique identifier for the address.
    examples:
      - name: WhiteHouseWithID
        value:
          id: 65ce514c-41e3-11ee-be56-0242ac120002
          street1: 1600 Pennsylvania Avenue NW
          city: Washington DC
          state: Washington DC
          postalCode: "20500"
          country: US
          isResidential: true
```

Examples contain all the information about the endpoint call, including
the request body, path parameters, query parameters, headers, and response body.

<CodeBlock title="user.yml">
  ```yaml
  examples: 
    - path-parameters: 
        userId: some-user-id 
      query-parameters:
        limit: 50 
      headers: 
        X-My-Header: some-value 
      response: 
        body: 
          response-field: hello
  ```
</CodeBlock>

#### Failed examples

You can also specify examples of failed endpoints calls. Add the `error`
property to a response example to designate which failure you're demonstrating.

<CodeBlock title="user.yml">
  ```yaml {5}
  examples:
    - path-parameters:
        userId: missing-user-id
      response:
        error: UserNotFoundError

  errors:
    UserNotFoundError:
      status-code: 404
  ```
</CodeBlock>

If the error has a body, then you must include the body in the example.

<CodeBlock title="user.yml">
  ```yaml {6, 11}
  examples:
    - path-parameters:
        userId: missing-user-id
      response:
        error: UserNotFoundError
        body: "User with id `missing-user-id` was not found"

  errors:
    UserNotFoundError:
      status-code: 404
      type: string
  ```
</CodeBlock>

#### Referencing examples from types

To avoid duplication, you can reference examples from types using `$`.

<CodeBlock title="user.yml">
  ```yaml {12}
  service:
    base-path: /users
    auth: true
    endpoints:
      getUser:
        method: GET
        path: /{userId}
        path-parameters:
          userId: UserId
        examples:
          - path-parameters:
              userId: $UserId.Example1

  types:
    UserId:
    type: integer
    examples: 
      - name: Example1
        value: user-id-123
  ```
</CodeBlock>