# What is an API definition?

> Describes the contract between the API provider and API consumer

An API definition is a machine-readable specification of your API's structure, including **endpoints**, **request and response schemas**, and **authentication** requirements. Instead of manually keeping SDKs and documentation in sync with API changes, an API definition enables automatic generation of these artifacts.

Fern integrates with several API definition formats:

<AccordionGroup>
  <Accordion title="OpenAPI (REST & Webhook APIs)">
    Formerly known as Swagger, [OpenAPI](https://swagger.io/specification/) is the most popular API definition format.
    OpenAPI can be used to document RESTful APIs and is defined in a YAML or JSON file.

    Check out an example OpenAPI Specification for the Petstore API [here](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml)

    ```yaml maxLines={0}
    openapi: 3.0.2
    tags:
      - name: pet
        description: Everything about your Pets
    paths:
      /pet:
        post:
          tags:
            - pet
          summary: Add a new pet to the store
          description: Add a new pet to the store
          operationId: addPet
          requestBody:
            description: Create a new pet in the store
            required: true
            content:
              application/json:
                schema:
                  $ref: '#/components/schemas/Pet'
              application/xml:
                schema:
                  $ref: '#/components/schemas/Pet'
              application/x-www-form-urlencoded:
                schema:
                  $ref: '#/components/schemas/Pet'
          responses:
            '200':
              description: Successful operation
              content:
                application/xml:
                  schema:
                    $ref: '#/components/schemas/Pet'
                application/json:
                  schema:
                    $ref: '#/components/schemas/Pet'
            '405':
              description: Invalid input
        components:
          schemas:
            Pet:
              required:
                - name
                - photoUrls
              properties:
                id:
                  type: integer
                  format: int64
                  example: 10
                name:
                  type: string
                  example: doggie
                category:
                  $ref: '#/components/schemas/Category'
                photoUrls:
                  type: array
                  xml:
                    wrapped: true
                  items:
                    type: string
                    xml:
                      name: photoUrl
                tags:
                  type: array
                  xml:
                    wrapped: true
                  items:
                    $ref: '#/components/schemas/Tag'
                    xml:
                      name: tag
                status:
                  type: string
                  description: pet status in the store
                  enum:
                    - available
                    - pending
                    - sold
              xml:
                name: pet
              type: object
    ```
  </Accordion>

  <Accordion title="AsyncAPI (WebSocket APIs)">
    [AsyncAPI](https://v2.asyncapi.com/docs) is a specification for defining event-driven APIs. It is used to document APIs that use
    WebSockets, MQTT, and other messaging protocols.

    Check out an example AsyncAPI spec for a chat application below:

    ```yaml maxLines={0}
    asyncapi: 2.0.0
    info:
      title: Chat server
      version: 1.0.0

    servers:
      Production:
        url: chat.com
        protocol: ws

    channels:
      "/application":
        bindings:
          ws:
            query:
              type: object
              properties:
                apiKey:
                  type: string
                  description: The API key for the client
                  minimum: 1
            bindingVersion: 0.1.0
        subscribe:
          operationId: sendMessage
          message:
            $ref: '#/components/messages/SendMessage'
        publish:
          operationId: receiveMessage
          message:
            $ref: '#/components/messages/ReceiveMessage'

    components:
      messages:
        SendMessage:
          payload:
            message: string
        ReceiveMessage:
          payload:
            message: string
            from: 
              type: string
              description: The userId for the sender of the message
    ```
  </Accordion>

  <Accordion title="OpenRPC (JSON-RPC APIs)">
    [OpenRPC](https://open-rpc.org/) is a spec for describing JSON-RPC 2.0 APIs. It enables interactive docs and code generation tooling to the JSON-RPC ecosystem.

    Check out an example OpenRPC Specification for a crypto wallet service below:

    ```yaml maxLines=0
    # yaml-language-server: $schema=https://meta.open-rpc.org/
    $schema: https://meta.open-rpc.org/
    openrpc: 1.2.4
    info:
      title: Basic Wallet API JSON-RPC Specification
      description: A simple JSON-RPC API for querying wallet balances.
      version: 0.0.1
    servers:
      - url: https://wallet.example.com/json-rpc
        name: Mainnet
    methods:
      - name: getBalance
        description: Get the balance of a wallet address.
        params:
          - name: address
            required: true
            description: The wallet address to query.
            schema:
              type: string
        result:
          name: balance
          description: The balance of the wallet address.
          schema:
            type: number
        examples:
          - name: getBalance example
            params:
              - name: address
                value: "0x1234567890abcdef1234567890abcdef12345678"
            result:
              name: balance
              value: 42.5
    ```
  </Accordion>

  <Accordion title="gRPC (RPC APIs)">
    [gRPC](https://grpc.io/) is a modern, open-source RPC framework developed by Google. It uses Protocol Buffers as its interface definition language and supports multiple programming languages with efficient binary serialization.

    gRPC APIs are defined using Protocol Buffer (.proto) files that specify services and message types. Check out an example gRPC service definition below:

    ```proto maxLines={0}
    syntax = "proto3";

    package petstore;

    // The pet store service definition
    service PetStoreService {
      // Get a pet by ID
      rpc GetPet(GetPetRequest) returns (Pet);
      
      // Add a new pet to the store
      rpc AddPet(AddPetRequest) returns (Pet);
      
      // List all pets with optional filtering
      rpc ListPets(ListPetsRequest) returns (ListPetsResponse);
    }

    // Request message for getting a pet
    message GetPetRequest {
      int64 pet_id = 1;
    }

    // Request message for adding a pet
    message AddPetRequest {
      string name = 1;
      string category = 2;
      repeated string photo_urls = 3;
      PetStatus status = 4;
    }

    // Request message for listing pets
    message ListPetsRequest {
      int32 page_size = 1;
      string page_token = 2;
      PetStatus status = 3;
    }

    // Response message for listing pets
    message ListPetsResponse {
      repeated Pet pets = 1;
      string next_page_token = 2;
    }

    // Pet message definition
    message Pet {
      int64 id = 1;
      string name = 2;
      string category = 3;
      repeated string photo_urls = 4;
      PetStatus status = 5;
    }

    // Pet status enumeration
    enum PetStatus {
      PET_STATUS_UNSPECIFIED = 0;
      PET_STATUS_AVAILABLE = 1;
      PET_STATUS_PENDING = 2;
      PET_STATUS_SOLD = 3;
    }
    ```
  </Accordion>

  <Accordion title="Fern Definition (REST, Webhook, & WebSocket APIs)">
    The Fern Definition is our take on a simpler API definition format. It is designed with **best-practices**,
    supports **both RESTful and event-driven APIs**, and is optimized for **SDK generation**.

    <Note>
      The Fern Definition is inspired from internal API Definition formats built at companies like
      [Amazon](https://smithy.io/2.0/index.html), [Google](https://grpc.io/), [Palantir](https://blog.palantir.com/introducing-conjure-palantirs-toolchain-for-http-json-apis-2175ec172d32),
      Twilio and Stripe. These companies **rejected** OpenAPI and built their own version.
    </Note>

    Check out an example Fern Definition below:

    ```yaml maxLines={0}
    types:
      MovieId: string

      Movie:
        properties:
          id: MovieId
          title: string
          rating:
            type: double
            docs: The rating scale is one to five stars

      CreateMovieRequest:
        properties:
          title: string
          rating: double

    service:
      auth: false
      base-path: /movies
      endpoints:
        createMovie:
          docs: Add a movie to the database
          method: POST
          path: /create-movie
          request: CreateMovieRequest
          response: MovieId

        getMovie:
          method: GET
          path: /{movieId}
          path-parameters:
            movieId: MovieId
          response: Movie
          errors:
            - MovieDoesNotExistError

    errors:
      MovieDoesNotExistError:
        status-code: 404
        type: MovieId
    ```
  </Accordion>
</AccordionGroup>

## Why create an API definition?

Once you have an API definition, Fern uses it as an input to generate artifacts
like SDKs and API Reference documentation. Every time you update the API definition,
you can regenerate these artifacts to ensure they are always up-to-date.

<CardGroup cols={2}>
  <Card title="SDKs" icon="brands github" href="/sdks/overview/introduction">
    Client libraries in multiple languages that automatically stay in sync with your API.
  </Card>

  <Card title="Documentation" icon="regular browser" href="/docs/getting-started/overview">
    Interactive API docs with code examples and live testing capabilities.
  </Card>

  <Card title="Postman Collection" icon={<img src="https://cdn.worldvectorlogo.com/logos/postman.svg" alt="Postman logo"/>} href="/docs/integrations/postman">
    Ready-to-use collection with pre-filled example requests and responses.
  </Card>

  <Card title="Server Boilerplate" icon={<img src="https://cdn.worldvectorlogo.com/logos/fastapi-1.svg" alt="FastAPI logo" />} href="/api-definitions/openapi/frameworks/fastapi">
    Pydantic models for FastAPI or controllers for your Spring Boot application.
  </Card>
</CardGroup>