diff --git a/fern/assets/styles.css b/fern/assets/styles.css
index ee80bb9ff..07b5a1bf8 100644
--- a/fern/assets/styles.css
+++ b/fern/assets/styles.css
@@ -92,7 +92,7 @@
grid-row: 2;
}
- > a[href*="api-definition"]:before {
+ /* > a[href*="api-definition"]:before {
content: "Utilities";
font-weight: 500;
position: absolute;
@@ -108,19 +108,7 @@
width: 1.5rem;
height: 1.5rem;
}
- }
-
-
- > a[href*="cli-api-reference"] {
- grid-column: 3;
- grid-row: 2;
- transform: translateY(-32px);
-
- .fern-selection-item-icon {
- width: 1.5rem;
- height: 1.5rem;
- }
- }
+ } */
> a[href*="openapi"]:before {
content: "Supported Specs";
@@ -151,6 +139,17 @@
}
}
+ > a[href*="cli-api-reference"] {
+ grid-column: 3;
+ grid-row: 3;
+ transform: translateY(-64px);
+
+ .fern-selection-item-icon {
+ width: 1.5rem;
+ height: 1.5rem;
+ }
+ }
+
> a[href*="asyncapi"] {
grid-column: 3;
grid-row: 3;
diff --git a/fern/docs.yml b/fern/docs.yml
index fb605af42..f9ff0993c 100644
--- a/fern/docs.yml
+++ b/fern/docs.yml
@@ -27,16 +27,29 @@ products:
- display-name: Ask Fern
path: ./products/ask-fern/ask-fern.yml
- icon: fa-regular fa-magnifying-glass
+ icon: fa-regular fa-magnifying-glass
image: ./images/product-switcher/product-switcher-askfern-light.png
slug: ask-fern
subtitle: Let users find answers in your documentation instantly
- - display-name: API Definition
- path: ./products/api-definition/api-definition.yml
+
+ # - display-name: API Definition
+ # path: ./products/api-definition/api-definition.yml
+ # icon: fa-regular fa-book
+ # image: ./images/product-switcher/api-definitions-light.png
+ # slug: api-definition
+
+ - display-name: OpenAPI
+ path: ./products/openapi-def/openapi-def.yml
icon: fa-regular fa-book
- image: ./images/product-switcher/api-definitions-light.png
- slug: api-definition
+ image: ./images/product-switcher/openapi-def.png
+ slug: openapi
+
+ - display-name: Fern Definition
+ path: ./products/fern-def/fern-def.yml
+ icon: fa-regular fa-seedling
+ image: ./images/product-switcher/fern-def.png
+ slug: fern-def
- display-name: CLI & API Reference
path: ./products/cli-api-reference/cli-api-reference.yml
@@ -44,18 +57,6 @@ products:
image: ./images/product-switcher/cli-api-reference-light.png
slug: cli-api-reference
- # - display-name: OpenAPI
- # path: ./products/openapi-def/openapi-def.yml
- # icon: fa-regular fa-book
- # image: ./images/product-switcher/openapi-def.png
- # slug: openapi
-
- # - display-name: Fern Definition
- # path: ./products/fern-def/fern-def.yml
- # icon: fa-regular fa-seedling
- # image: ./images/product-switcher/fern-def.png
- # slug: fern-def
-
# - display-name: AsyncAPI
# path: ./products/asyncapi-def/asyncapi-def.yml
# icon: fa-regular fa-bolt
@@ -152,27 +153,66 @@ redirects:
- source: /learn/welcome
destination: /learn
permanent: true
- - source: /learn/home
- destination: /learn
+ - source: /learn
+ destination: /learn/home
permanent: true
- source: /learn/api-definition/fern/api-yml-reference
destination: /learn/api-definition/fern/api-yml/overview
permanent: true
+ - source: /learn/docs/api-references/api-explorer
+ destination: /learn/docs/api-references/api-explorer/overview
- source: /learn/docs/api-references/api-playground/:slug*
- destination: /learn/docs/api-references/api-explorer/:slug*
+ destination: learn/docs/api-references/api-explorer/:slug*
permanent: true
- source: /learn/docs/api-references/api-playground
- destination: /learn/docs/api-references/api-explorer
+ destination: /learn/docs/api-references/api-explorer/overview
permanent: true
- source: /learn/sdks/features/:slug*
destination: /learn/sdks/capabilities/:slug*
permanent: true
+ - source: /learn/sdks/capabilities/method-names
+ destination: /learn/sdks/deep-dives/customize-method-names
+ permanent: true
+ - source: /learn/sdks/guides/preview-your-sdk-locally
+ destination: /learn/sdks/deep-dives/setup-local-sdk-previews
+ permanent: true
+ - source: /learn/sdks/capabilities/auto-pagination
+ destination: /learn/v2/sdks/deep-dives/configure-auto-pagination
+ permanent: true
+ - source: /learn/sdks/capabilities/idempotency-headers
+ destination: /learn/sdks/deep-dives/configure-idempotency
+ permanent: true
- source: /learn/sdks/package-managers/:slug*
destination: /learn/sdks/guides/publish-to-package-managers/:slug*
permanent: true
+ - source: /learn/sdks/guides/publish-to-package-managers/npm-type-script
+ destination: /learn/sdks/generators/type-script/publishing-to-npm
+ permanent: true
+ - source: /learn/sdks/guides/publish-to-package-managers/pypi
+ destination: /learn/sdks/generators/python/publishing-to-py-pi
+ permanent: true
+ - source: /learn/sdks/guides/publish-to-package-managers/nuget
+ destination: /learn/sdks/generators/net/publishing-to-nu-get
+ permanent: true
+ - source: /learn/sdks/guides/publish-to-package-managers/pkgsite
+ destination: /learn/sdks/generators/go/publishing-as-a-go-module
+ permanent: true
+ - source: /learn/sdks/guides/publish-to-package-managers/maven-central
+ destination: /learn/sdks/generators/java/publishing-to-maven-central
+ permanent: true
+ - source: /learn/sdks/guides/publish-to-package-managers/rubygems
+ destination: /learn/sdks/generators/ruby/publishing-to-rubygems
+ permanent: true
+ - source: /learn/sdks/guides/publish-to-package-managers/packagist
+ destination: /learn/sdks/generators/php/publishing-to-packagist
+ permanent: true
- source: /learn/sdks/introduction/configuration
destination: /learn/sdks/introduction/language-support
permanent: true
+ - source: /learn/sdks/introduction/language-support
+ destination: /learn/sdks/overview/introduction
+ permanent: true
+ ## PAUSED HERE
- source: /learn/sdks/getting-started/:slug*
destination: /learn/sdks/guides/:slug*
permanent: true
diff --git a/fern/products/docs/docs.yml b/fern/products/docs/docs.yml
index ed3c14e13..b9573e2b0 100644
--- a/fern/products/docs/docs.yml
+++ b/fern/products/docs/docs.yml
@@ -115,8 +115,9 @@ navigation:
path: ./pages/api-references/http-snippets.mdx
- section: API Explorer
slug: api-explorer
- path: ./pages/api-references/api-explorer.mdx
contents:
+ - page: Overview
+ path: ./pages/api-references/api-explorer.mdx
- page: Auto-populate API Keys
path: ./pages/api-references/autopopulate-api-key.mdx
- page: Endpoint Errors
diff --git a/fern/products/fern-def/fern-def.yml b/fern/products/fern-def/fern-def.yml
index f91e653ac..b68f4f182 100644
--- a/fern/products/fern-def/fern-def.yml
+++ b/fern/products/fern-def/fern-def.yml
@@ -1,55 +1,55 @@
navigation:
- - section: Getting Started
+ - page: Overview
+ path: ./pages/overview.mdx
+ - page: Authentication
+ path: ./pages/auth.mdx
+ - page: Types
+ path: ./pages/types.mdx
+ - section: Endpoints
+ path: ./pages/endpoints.mdx
+ contents:
+ - page: HTTP JSON Endpoints
+ path: ./pages/endpoints/rest.mdx
+ slug: http
+ - page: Multipart Form Uploads
+ path: ./pages/endpoints/multipart.mdx
+ slug: multipart
+ - page: Bytes
+ path: ./pages/endpoints/bytes.mdx
+ slug: bytes
+ - page: Server-Sent Events
+ path: ./pages/endpoints/sse.mdx
+ slug: sse
+ - page: Webhooks
+ path: ./pages/webhooks.mdx
+ - page: WebSockets
+ path: ./pages/websockets.mdx
+ slug: websockets
+ - page: Errors
+ path: ./pages/errors.mdx
+ - page: Imports
+ path: ./pages/imports.mdx
+ - page: Examples
+ path: ./pages/examples.mdx
+ - page: Audiences
+ path: ./pages/audiences.mdx
+ - page: Availability
+ path: ./pages/availability.mdx
+ - section: api.yml Reference
+ slug: api-yml
contents:
- page: Overview
- path: ./pages/getting-started/overview.mdx
- - page: Quickstart
- path: ./pages/getting-started/quickstart.mdx
- - page: Philosophy
- path: ./pages/getting-started/philosophy.mdx
- - page: Customer Showcase
- path: ./pages/getting-started/customer-showcase.mdx
- - section: Global Settings
- contents:
- - page: Authentication
- path: ./pages/global-settings/authentication.mdx
- - page: Global Headers
- path: ./pages/global-settings/global-headers.mdx
+ path: ./pages/api-yml/overview.mdx
- page: Environments
- path: ./pages/global-settings/environments.mdx
- - page: API Versions
- path: ./pages/global-settings/api-versions.mdx
- - section: Defining your API
- contents:
- - page: Types
- path: ./pages/defining-your-api/types.mdx
- - page: Imports
- path: ./pages/defining-your-api/imports.mdx
- - page: Endpoints
- path: ./pages/defining-your-api/endpoints.mdx
- - page: Webhooks
- path: ./pages/defining-your-api/webhooks.mdx
- - page: WebSockets
- path: ./pages/defining-your-api/websockets.mdx
- - page: Examples
- path: ./pages/defining-your-api/examples.mdx
+ path: ./pages/api-yml/environments.mdx
+ - page: Global Headers
+ path: ./pages/api-yml/global-configuration.mdx
- page: Errors
- path: ./pages/defining-your-api/errors.mdx
- - page: Doc
- path: ./pages/defining-your-api/doc.mdx
- - page: Availability
- path: ./pages/defining-your-api/availability.mdx
- - page: Audiences
- path: ./pages/defining-your-api/audiences.mdx
- - section: Guides
- contents:
- - page: Validate your Fern Definition
- path: ./pages/guides/validate-your-fern-definition.mdx
- - page: Define multiple APIs
- path: ./pages/guides/define-multiple-apis.mdx
- - page: Export to OpenAPI
- path: ./pages/guides/export-to-openapi.mdx
- - page: Depending on other APIs
- path: ./pages/guides/depending-on-other-apis.mdx
- - page: Creating namespaces
- path: ./pages/guides/creating-namespaces.mdx
+ path: ./pages/api-yml/errors.mdx
+ - page: Packages
+ path: ./pages/packages.mdx
+ - page: Depending on Other APIs
+ path: ./pages/depending-on-other-apis.mdx
+ - page: Export to OpenAPI
+ slug: export-openapi
+ path: ./pages/export-openapi.mdx
\ No newline at end of file
diff --git a/fern/products/fern-def/pages/defining-your-api/audiences.mdx b/fern/products/fern-def/pages-archived/defining-your-api/audiences.mdx
similarity index 100%
rename from fern/products/fern-def/pages/defining-your-api/audiences.mdx
rename to fern/products/fern-def/pages-archived/defining-your-api/audiences.mdx
diff --git a/fern/products/fern-def/pages/defining-your-api/availability.mdx b/fern/products/fern-def/pages-archived/defining-your-api/availability.mdx
similarity index 100%
rename from fern/products/fern-def/pages/defining-your-api/availability.mdx
rename to fern/products/fern-def/pages-archived/defining-your-api/availability.mdx
diff --git a/fern/products/fern-def/pages/defining-your-api/doc.mdx b/fern/products/fern-def/pages-archived/defining-your-api/doc.mdx
similarity index 100%
rename from fern/products/fern-def/pages/defining-your-api/doc.mdx
rename to fern/products/fern-def/pages-archived/defining-your-api/doc.mdx
diff --git a/fern/products/fern-def/pages/defining-your-api/endpoints.mdx b/fern/products/fern-def/pages-archived/defining-your-api/endpoints.mdx
similarity index 100%
rename from fern/products/fern-def/pages/defining-your-api/endpoints.mdx
rename to fern/products/fern-def/pages-archived/defining-your-api/endpoints.mdx
diff --git a/fern/products/fern-def/pages/defining-your-api/errors.mdx b/fern/products/fern-def/pages-archived/defining-your-api/errors.mdx
similarity index 100%
rename from fern/products/fern-def/pages/defining-your-api/errors.mdx
rename to fern/products/fern-def/pages-archived/defining-your-api/errors.mdx
diff --git a/fern/products/fern-def/pages/defining-your-api/examples.mdx b/fern/products/fern-def/pages-archived/defining-your-api/examples.mdx
similarity index 100%
rename from fern/products/fern-def/pages/defining-your-api/examples.mdx
rename to fern/products/fern-def/pages-archived/defining-your-api/examples.mdx
diff --git a/fern/products/fern-def/pages/defining-your-api/imports.mdx b/fern/products/fern-def/pages-archived/defining-your-api/imports.mdx
similarity index 100%
rename from fern/products/fern-def/pages/defining-your-api/imports.mdx
rename to fern/products/fern-def/pages-archived/defining-your-api/imports.mdx
diff --git a/fern/products/fern-def/pages/defining-your-api/types.mdx b/fern/products/fern-def/pages-archived/defining-your-api/types.mdx
similarity index 100%
rename from fern/products/fern-def/pages/defining-your-api/types.mdx
rename to fern/products/fern-def/pages-archived/defining-your-api/types.mdx
diff --git a/fern/products/fern-def/pages/defining-your-api/webhooks.mdx b/fern/products/fern-def/pages-archived/defining-your-api/webhooks.mdx
similarity index 100%
rename from fern/products/fern-def/pages/defining-your-api/webhooks.mdx
rename to fern/products/fern-def/pages-archived/defining-your-api/webhooks.mdx
diff --git a/fern/products/fern-def/pages/defining-your-api/websockets.mdx b/fern/products/fern-def/pages-archived/defining-your-api/websockets.mdx
similarity index 100%
rename from fern/products/fern-def/pages/defining-your-api/websockets.mdx
rename to fern/products/fern-def/pages-archived/defining-your-api/websockets.mdx
diff --git a/fern/products/fern-def/pages/getting-started/customer-showcase.mdx b/fern/products/fern-def/pages-archived/getting-started/customer-showcase.mdx
similarity index 100%
rename from fern/products/fern-def/pages/getting-started/customer-showcase.mdx
rename to fern/products/fern-def/pages-archived/getting-started/customer-showcase.mdx
diff --git a/fern/products/fern-def/pages/getting-started/overview.mdx b/fern/products/fern-def/pages-archived/getting-started/overview.mdx
similarity index 100%
rename from fern/products/fern-def/pages/getting-started/overview.mdx
rename to fern/products/fern-def/pages-archived/getting-started/overview.mdx
diff --git a/fern/products/fern-def/pages/getting-started/philosophy.mdx b/fern/products/fern-def/pages-archived/getting-started/philosophy.mdx
similarity index 100%
rename from fern/products/fern-def/pages/getting-started/philosophy.mdx
rename to fern/products/fern-def/pages-archived/getting-started/philosophy.mdx
diff --git a/fern/products/fern-def/pages/getting-started/quickstart.mdx b/fern/products/fern-def/pages-archived/getting-started/quickstart.mdx
similarity index 100%
rename from fern/products/fern-def/pages/getting-started/quickstart.mdx
rename to fern/products/fern-def/pages-archived/getting-started/quickstart.mdx
diff --git a/fern/products/fern-def/pages/global-settings/api-versions.mdx b/fern/products/fern-def/pages-archived/global-settings/api-versions.mdx
similarity index 100%
rename from fern/products/fern-def/pages/global-settings/api-versions.mdx
rename to fern/products/fern-def/pages-archived/global-settings/api-versions.mdx
diff --git a/fern/products/fern-def/pages/global-settings/authentication.mdx b/fern/products/fern-def/pages-archived/global-settings/authentication.mdx
similarity index 100%
rename from fern/products/fern-def/pages/global-settings/authentication.mdx
rename to fern/products/fern-def/pages-archived/global-settings/authentication.mdx
diff --git a/fern/products/fern-def/pages/global-settings/environments.mdx b/fern/products/fern-def/pages-archived/global-settings/environments.mdx
similarity index 100%
rename from fern/products/fern-def/pages/global-settings/environments.mdx
rename to fern/products/fern-def/pages-archived/global-settings/environments.mdx
diff --git a/fern/products/fern-def/pages/global-settings/global-headers.mdx b/fern/products/fern-def/pages-archived/global-settings/global-headers.mdx
similarity index 100%
rename from fern/products/fern-def/pages/global-settings/global-headers.mdx
rename to fern/products/fern-def/pages-archived/global-settings/global-headers.mdx
diff --git a/fern/products/fern-def/pages/guides/creating-namespaces.mdx b/fern/products/fern-def/pages-archived/guides/creating-namespaces.mdx
similarity index 100%
rename from fern/products/fern-def/pages/guides/creating-namespaces.mdx
rename to fern/products/fern-def/pages-archived/guides/creating-namespaces.mdx
diff --git a/fern/products/fern-def/pages/guides/define-multiple-apis.mdx b/fern/products/fern-def/pages-archived/guides/define-multiple-apis.mdx
similarity index 100%
rename from fern/products/fern-def/pages/guides/define-multiple-apis.mdx
rename to fern/products/fern-def/pages-archived/guides/define-multiple-apis.mdx
diff --git a/fern/products/fern-def/pages/guides/depending-on-other-apis.mdx b/fern/products/fern-def/pages-archived/guides/depending-on-other-apis.mdx
similarity index 100%
rename from fern/products/fern-def/pages/guides/depending-on-other-apis.mdx
rename to fern/products/fern-def/pages-archived/guides/depending-on-other-apis.mdx
diff --git a/fern/products/fern-def/pages/guides/export-to-openapi.mdx b/fern/products/fern-def/pages-archived/guides/export-to-openapi.mdx
similarity index 100%
rename from fern/products/fern-def/pages/guides/export-to-openapi.mdx
rename to fern/products/fern-def/pages-archived/guides/export-to-openapi.mdx
diff --git a/fern/products/fern-def/pages/guides/validate-your-fern-definition.mdx b/fern/products/fern-def/pages-archived/guides/validate-your-fern-definition.mdx
similarity index 100%
rename from fern/products/fern-def/pages/guides/validate-your-fern-definition.mdx
rename to fern/products/fern-def/pages-archived/guides/validate-your-fern-definition.mdx
diff --git a/fern/products/fern-def/pages/api-yml/environments.mdx b/fern/products/fern-def/pages/api-yml/environments.mdx
new file mode 100644
index 000000000..bdb9cc691
--- /dev/null
+++ b/fern/products/fern-def/pages/api-yml/environments.mdx
@@ -0,0 +1,87 @@
+---
+title: Environments
+description: List environments like production, staging, and development.
+---
+
+You can specify the environments where your server is deployed.
+
+## Single URL environments
+
+```yaml title="api.yml"
+name: api
+environments:
+ Production: https://www.yoursite.com
+ Staging:
+ docs: This staging environment is helpful for testing!
+ url: https://www.staging.yoursite.com
+```
+
+## Multiple URLs per environment
+
+You can specify multiple URLs per environment. This is helpful if you have a
+microservice architecture, and you want a single SDK to interact with multiple
+servers.
+
+```yaml title="api.yml"
+environments:
+ Production:
+ urls:
+ Auth: https://auth.yoursite.com
+ Plants: https://plants.yoursite.com
+ Staging:
+ urls:
+ Auth: https://auth.staging.yoursite.com
+ Plants: https://plants.staging.yoursite.com
+```
+
+If you choose to use this feature, you must specify a `url` for each service you define:
+
+```yaml title="auth.yml"
+service:
+ url: Auth
+ base-path: /auth
+ ...
+```
+
+## Default environment
+
+You can also provide a default environment:
+
+```yaml title="api.yml"
+name: api
+environments:
+ Production: https://www.yoursite.com
+ Staging:
+ docs: This staging environment is helpful for testing!
+ url: https://www.staging.yoursite.com
+default-environment: Production
+```
+
+ By providing a default environment, the generated SDK will be setup to hit that URL out-of-the-box.
+
+## Base path
+If you would like all of your endpoints to be prefixed with a path, use `base-path`.
+
+In the example below, every endpoint is prefixed with a `/v1`:
+```yaml title="api.yml"
+name: api
+base-path: /v1
+```
+
+## Audiences
+
+If you have listed environments that you want to filter, you can leverage audiences.
+
+```yaml title="api.yml"
+audiences:
+ - public
+
+environments:
+ Dev:
+ url: https://api.dev.buildwithfern.com
+ Prod:
+ url: https://api.buildwithfern.com
+ audiences:
+ - external
+```
+
diff --git a/fern/products/fern-def/pages/api-yml/errors.mdx b/fern/products/fern-def/pages/api-yml/errors.mdx
new file mode 100644
index 000000000..06ce9ef3f
--- /dev/null
+++ b/fern/products/fern-def/pages/api-yml/errors.mdx
@@ -0,0 +1,54 @@
+---
+title: Errors
+description: Specify error types and schemas
+---
+
+In order to generate SDKs idiomatically, Fern needs to know how to differentiate
+between different errors when parsing an endpoint response.
+
+### Discriminate by status code
+
+You can specify Fern to discriminate by status code. This means on each
+endpoint, every error that's listed must have a different HTTP status code.
+
+
+```yaml
+name: api
+error-discrimination:
+ strategy: status-code
+```
+
+
+### Discriminate by error name
+
+You can specify Fern to discriminate by error name. If you select this strategy,
+then Fern will assume that every error response has an extra property denoting
+the error name.
+
+If you use Fern to generate server-side code, then this option provides
+the most flexibility. Otherwise, you'll probably want to use the status code
+discrimination strategy.
+
+
+```yaml
+name: api
+error-discrimination:
+ strategy: property
+ property-name: errorName
+```
+
+
+### Global errors
+
+You can import and list errors that will be thrown by every endpoint.
+
+
+```yaml
+imports:
+ commons: commons.yml
+
+errors:
+ - commons.NotFoundError
+ - commons.BadRequestError
+```
+
\ No newline at end of file
diff --git a/fern/products/fern-def/pages/api-yml/global-configuration.mdx b/fern/products/fern-def/pages/api-yml/global-configuration.mdx
new file mode 100644
index 000000000..0f3cc3b7d
--- /dev/null
+++ b/fern/products/fern-def/pages/api-yml/global-configuration.mdx
@@ -0,0 +1,53 @@
+---
+title: Global Configuration
+description: Specify global headers, path parameters or query parameters meant to be included on every request.
+---
+
+The `api.yml` configuration supports global configuration like headers and path parameters.
+
+## Global headers
+
+You can specify headers that are meant to be included on every request:
+
+
+```yaml
+name: api
+headers:
+ X-App-Id: string
+```
+
+
+## Global path parameters
+
+You can specify path parameters that are meant to be included on every request:
+
+
+```yaml
+name: api
+base-path: /{userId}/{orgId}
+path-parameters:
+ userId: string
+ orgId: string
+```
+
+
+### Overriding the base path
+
+If you have certain endpoints that do not live at the configured `base-path`, you can
+override the `base-path` at the endpoint level.
+
+```yml imdb.yml {5}
+service:
+ endpoints:
+ getMovie:
+ method: POST
+ base-path: "override/{arg}"
+ path: "movies/{movieId}"
+ path-parameters:
+ arg: string
+```
+
+## Global query parameters
+
+You cannot yet specify query parameters that are meant to be included on every request.
+If you'd like to see this feature, please upvote [this issue](https://github.com/fern-api/fern/issues/2930).
\ No newline at end of file
diff --git a/fern/products/fern-def/pages/api-yml/overview.mdx b/fern/products/fern-def/pages/api-yml/overview.mdx
new file mode 100644
index 000000000..d27912ad7
--- /dev/null
+++ b/fern/products/fern-def/pages/api-yml/overview.mdx
@@ -0,0 +1,57 @@
+---
+title: The api.yml configuration file
+description: The api.yml file contains general API configuration when using the Fern Definition format.
+---
+
+A `fern/` folder has a special file called `api.yml`, which includes all the API-wide configuration.
+
+```bash {5}
+fern/
+├─ fern.config.json
+├─ generators.yml
+└─ definition/
+ ├─ api.yml
+ ├─ pet.yml
+ ├─ store.yml
+ └─ user.yml
+```
+
+## API name
+
+This name is used to uniquely identify your API in your organization. If you just have one API, then `api` is a sufficient name.
+
+
+```yaml
+name: api
+```
+
+
+## API description
+
+You can define a top level API description. This description will come through in the OpenAPI Specification and Postman collection.
+
+
+```yaml {2-4}
+name: api
+docs: |
+ ## Header
+ This API provides access to...
+```
+
+
+## API version
+
+You can define your header-based API versioning scheme, such as an `X-API-Version`. The supported versions
+and default value are specified like so:
+
+
+```yaml
+version:
+ header: X-API-Version
+ default: "2.0.0"
+ values:
+ - "1.0.0"
+ - "2.0.0"
+ - "latest"
+```
+
\ No newline at end of file
diff --git a/fern/products/fern-def/pages/audiences.mdx b/fern/products/fern-def/pages/audiences.mdx
new file mode 100644
index 000000000..20f2876a3
--- /dev/null
+++ b/fern/products/fern-def/pages/audiences.mdx
@@ -0,0 +1,113 @@
+---
+title: Audiences in Fern Definition
+subtitle: Use audiences in your Fern Definition to segment your API for different groups of consumers.
+---
+
+Audiences are a useful tool for segmenting your API for different consumers. You can configure your Fern Docs to publish documentation specific to an `Audience`. You can use [audiences in your OpenAPI Specification](/learn/api-definition/openapi/audiences), too.
+
+Common examples of audiences include:
+
+- Internal consumers (e.g., frontend developers who use the API)
+- Beta testers
+- Customers
+
+By default, if no audience is specified, it will be accessible to all consumers.
+
+## Configuration
+
+The Fern Definition has a first-class concept for marking different endpoints, types, and properties for different audiences.
+
+To use audiences in your Fern Definition, add them to `api.yml`.
+
+In the example below, we have created audiences for `internal`, `beta`, and `customer` groups:
+
+```yaml title='api.yml' {2-5}
+name: api
+audiences:
+ - internal
+ - beta
+ - customers
+```
+
+## Audiences for endpoints
+
+To mark an endpoint for a particular consumer, add an `audience` with the relevant groups.
+
+In this example, the `sendEmail` endpoint is only available to internal consumers:
+
+```yaml title='user.yml' {6-7}
+service:
+ base-path: /users
+ auth: true
+ endpoints:
+ sendEmail:
+ audiences:
+ - internal
+ path: /send-email
+ ...
+```
+
+## Audiences for types
+
+Types can also be marked for different audiences.
+
+In this example, the `Email` type is available to internal and beta consumers:
+
+```yaml title='user.yml' {5-7}
+Email:
+ properties:
+ subject: string
+ body: optional
+ audiences:
+ - internal
+ - beta
+```
+
+## Audiences for properties
+
+Properties of a type can also be marked for different audiences.
+
+In this example, the `to` property is available to beta consumers only:
+
+```yaml title='user.yml' {8-9}
+Email:
+ properties:
+ subject: string
+ body: optional
+ to:
+ type: string
+ docs: The recipient of the email
+ audiences:
+ - beta
+```
+
+## Audiences for SDKs
+
+In `generators.yml`, you can apply audience filters so that only certain
+endpoints are passed to the generators.
+
+The following example configures the SDKs to filter for `customers`:
+
+```yaml title='generators.yml' {3-4}
+groups:
+ external:
+ audiences:
+ - customers
+ generators:
+ ...
+```
+
+## Audiences with docs
+
+If generating Fern Docs, update your `docs.yml` configuration to include your audiences.
+
+The following example shows how to configure your `docs.yml` to publish documentation for the `customers` audience:
+
+
+```yaml {3-4}
+navigation:
+ - api: API Reference
+ audiences:
+ - customers
+```
+
diff --git a/fern/products/fern-def/pages/auth.mdx b/fern/products/fern-def/pages/auth.mdx
new file mode 100644
index 000000000..e75ebbbd4
--- /dev/null
+++ b/fern/products/fern-def/pages/auth.mdx
@@ -0,0 +1,224 @@
+---
+title: Authentication
+subtitle: Model auth schemes such as bearer, basic, custom headers, and oauth.
+---
+
+Configuring authentication schemes happens in the `api.yml` file.
+
+```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.
+
+```yaml api.yml {1-2}
+auth-schemes:
+ AuthScheme:
+ ...
+```
+
+
+To apply an authentication scheme across all endpoints, reference the `auth-scheme` within the `auth` section of your `api.yml` file.
+```yaml api.yml {1}
+auth: AuthScheme
+auth-schemes:
+ AuthScheme:
+ ...
+```
+
+
+## Bearer authentication
+
+Start by defining a `Bearer` authentication scheme in `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`.
+
+```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:
+
+```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:
+
+```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`:
+
+```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`.
+
+```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:
+
+```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:
+
+```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.
+
+```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`.
+
+```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:
+
+```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:
+
+```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. Note that you'll need to define a token retrieval endpoint.
+
+```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.getToken
+ response-properties:
+ access-token: $response.access_token
+ expires-in: $response.expires_in
+
+```
+
+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.
+
+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 `:
+
+```yaml api.yml {5-6}
+auth-schemes:
+ OAuthScheme:
+ scheme: oauth
+ type: client-credentials
+ token-header: Fern-Authorization
+ token-prefix: Fern-Bearer
+ get-token:
+ ...
+```
\ No newline at end of file
diff --git a/fern/products/fern-def/pages/availability.mdx b/fern/products/fern-def/pages/availability.mdx
new file mode 100644
index 000000000..9e335ec12
--- /dev/null
+++ b/fern/products/fern-def/pages/availability.mdx
@@ -0,0 +1,96 @@
+---
+title: Availability in Fern Definition
+description: Add availability to Fern Definition API services, endpoints, types, or properties to indicate their release status.
+---
+
+You can add `availability` to an endpoint, type, or property within your Fern Definition.
+
+Availability can be:
+- `in-development` which means it is being worked on; will show a `Beta` tag
+- `pre-release` which means it is available; will show a `Beta` tag
+- `deprecated` which means it will be removed in the future; will show a `Deprecated` tag
+- `generally-available` which means it is stable and available for use; will show a `GA` tag
+
+## Endpoint
+
+
+```yaml {6}
+service:
+ base-path: /pet
+ auth: true
+ endpoints:
+ add:
+ availability: deprecated
+ display-name: Add pet
+ docs: Add a new Pet to the store
+ method: POST
+ path: ""
+ request: AddPetRequest
+ response: Pet
+```
+
+
+In Fern Docs, this will look like:
+
+
+
+
+
+## Type
+
+
+```yaml {15}
+ Pet:
+ properties:
+ id:
+ type: integer
+ docs: A unique ID for the Pet
+ name:
+ type: string
+ docs: The first name of the Pet
+ photoUrls:
+ type: list
+ docs: A list of publicly available URLs featuring the Pet
+ availability: generally-available
+ category:
+ type: optional
+ availability: pre-release
+
+ Category:
+ properties:
+ id: optional
+ name: optional
+```
+
+
+In Fern Docs, this will look like:
+
+
+
+
+
+## Property
+
+
+```yaml {12}
+ Pet:
+ properties:
+ id:
+ type: integer
+ docs: A unique ID for the Pet
+ name:
+ type: string
+ docs: The first name of the Pet
+ photoUrls:
+ type: list
+ docs: A list of publicly available URLs featuring the Pet
+ availability: deprecated
+ category: optional
+```
+
+
+In Fern Docs, this will look like:
+
+
+
+
diff --git a/fern/products/fern-def/pages/depending-on-other-apis.mdx b/fern/products/fern-def/pages/depending-on-other-apis.mdx
new file mode 100644
index 000000000..5a327feaf
--- /dev/null
+++ b/fern/products/fern-def/pages/depending-on-other-apis.mdx
@@ -0,0 +1,67 @@
+---
+title: "Depending on other APIs"
+subtitle: Import API Definitions to generate unified SDKs
+---
+
+Fern allows you to import other APIs into your API.
+
+This is often useful if:
+
+- you want to reuse another API's types in your API
+- you want to combine multiple microservices' APIs into one SDK (similar to the AWS SDK)
+
+## Registering the dependency API
+
+The first step is to **register** the API you want to depend on. To do this, use
+the `register` command:
+
+```
+$ fern register
+[some-dependency]: Uploading definition...
+[some-dependency]: Registered @fern/some-dependency:0.0.1
+```
+
+## Depending on the registered API
+
+To add a dependency on another API, you must add a `dependencies.yml` to declare which
+APIs you wish to depend on.
+
+```bash {4}
+fern/
+├─ fern.config.json
+├─ generators.yml
+├─ dependencies.yml
+└─ definition/
+ ├─ api.yml
+ ├─ imdb.yml
+```
+
+Your `dependencies.yml` has a list of all the APIs you wish to depend:
+
+```yaml dependencies.yml
+dependencies:
+ "@fern/some-dependency": "0.0.1"
+```
+
+Next, you need create a folder in your Fern Definition to house the dependency. Inside the folder, create a special file
+`__package__.yml` which specifies the dependency and version you want to add.
+
+```bash {8-9}
+fern/
+├─ fern.config.json
+├─ generators.yml
+├─ dependencies.yml
+└─ definition/
+ ├─ api.yml
+ ├─ imdb.yml
+ └─ my-folder
+ └─ __package__.yml
+```
+
+```yaml __package__.yml
+export:
+ dependency: "@fern/some-dependency"
+```
+
+When you generate the SDK with `fern generate`, the `__package__.yml` file will
+effectively be replaced with the API you're depending on.
diff --git a/fern/products/fern-def/pages/endpoints.mdx b/fern/products/fern-def/pages/endpoints.mdx
new file mode 100644
index 000000000..ad91ab18f
--- /dev/null
+++ b/fern/products/fern-def/pages/endpoints.mdx
@@ -0,0 +1,519 @@
+---
+title: Endpoints in Fern Definition
+description: 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**
+
+
+ ```yaml
+ service:
+ base-path: /users
+ auth: false
+ endpoints: {}
+ ```
+
+
+
+ To define a service with an empty base path use the empty string: `base-path: ""`
+
+
+## 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.
+
+
+```yaml {6}
+service:
+ base-path: /users
+ auth: false
+ endpoints:
+ getAllUsers:
+ path: /all
+ method: GET
+```
+
+
+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`
+
+## 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/add-plant) displays as the title of the endpoint page within the API Reference.
+
+
+```yaml {7}
+service:
+ base-path: /v3
+ auth: false
+ endpoints:
+ addPlant:
+ path: /plant
+ display-name: Add a new plant to the store
+ method: POST
+```
+
+
+## Path parameters
+
+Supply path parameters for your endpoints to create dynamic URLs.
+
+
+```yaml {6-8}
+service:
+ base-path: /users
+ auth: false
+ endpoints:
+ getUser:
+ path: /{userId}
+ path-parameters:
+ userId: string
+ method: GET
+```
+
+
+Services can also have path-parameters:
+
+
+ ```yaml {2-4}
+ service:
+ base-path: /projects/{projectId}
+ path-parameters:
+ projectId: string
+ auth: false
+ endpoints:
+ ...
+ ```
+
+
+## Query parameters
+
+Each endpoint can specify query parameters:
+
+
+```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
+```
+
+
+### `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.
+
+
+```yaml {5}
+ ...
+ query-parameters:
+ filter:
+ type: string
+ allow-multiple: true
+```
+
+
+## Auth
+
+Each endpoint can override the auth behavior specified in the service.
+
+
+ ```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.
+ ```
+
+
+## Headers
+
+Each endpoint can specify request headers:
+
+
+ ```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
+ ```
+
+
+Services can also specify request headers. These headers will cascade to the service's endpoints.
+
+
+ ```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
+ ```
+
+
+## Request body
+
+Endpoints can specify a request body type.
+
+
+```yaml {10}
+service:
+ base-path: /users
+ auth: false
+ endpoints:
+ setUserName:
+ path: /{userId}/set-name
+ path-parameters:
+ userId: string
+ method: POST
+ request: string
+```
+
+
+### 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.
+
+
+ ```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
+ ```
+
+
+## Success response
+
+Endpoints can specify a `response`, which is the type of the body that will be
+returned on a successful (200) call.
+
+
+```yaml
+service:
+ base-path: /users
+ auth: false
+ endpoints:
+ getAllUsers:
+ path: /all
+ method: GET
+ response: list
+
+types:
+ User:
+ properties:
+ userId: string
+ name: string
+```
+
+
+## Response status codes
+
+You can also use the `status-code` field to specify a custom status code
+for a success response.
+
+
+```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
+```
+
+
+## Error responses
+
+Endpoints can specify error responses, which detail the non-200 responses that
+the endpoint might return.
+
+
+```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
+```
+
+
+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.
+
+
+```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
+```
+
+
+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
+ 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.
+
+
+ ```yaml
+ examples:
+ - path-parameters:
+ userId: some-user-id
+ query-parameters:
+ limit: 50
+ headers:
+ X-My-Header: some-value
+ response:
+ body:
+ response-field: hello
+ ```
+
+
+### 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.
+
+
+```yaml {5}
+examples:
+ - path-parameters:
+ userId: missing-user-id
+ response:
+ error: UserNotFoundError
+
+errors:
+ UserNotFoundError:
+ status-code: 404
+```
+
+
+If the error has a body, then you must include the body in the example.
+
+
+```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
+```
+
+
+### Referencing examples from types
+
+To avoid duplication, you can reference examples from types using `$`.
+
+
+```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
+```
+
diff --git a/fern/products/fern-def/pages/endpoints/bytes.mdx b/fern/products/fern-def/pages/endpoints/bytes.mdx
new file mode 100644
index 000000000..43a1926d8
--- /dev/null
+++ b/fern/products/fern-def/pages/endpoints/bytes.mdx
@@ -0,0 +1,60 @@
+---
+title: Binary Data and Files
+subtitle: Use the `bytes` type to handle binary data in your API
+---
+
+
+ The `bytes` type allows you to handle binary data in both requests and responses.
+
+
+## Sending bytes
+
+If your API needs to send a stream of bytes (i.e. typical for assets like audio, images and other files) then
+you can use the `bytes` type in the Fern Definition to model this.
+
+```yml audio.yml
+service:
+ base-path: /audio
+ endpoints:
+ upload:
+ display-name: Upload audio
+ method: POST
+ path: /upload
+ content-type: application/octet-stream
+ request:
+ type: bytes
+ docs: The bytes of the MP3 file that you would like to upload
+```
+
+## Receiving bytes
+
+
+ When handling binary data in responses, use `type: file` instead of `type: bytes`.
+
+
+On the other hand, if your API is returning a stream of bytes, then you can leverage the `bytes` type as a response.
+
+```yml textToSpeech.yml
+service:
+ base-path: /tts
+ endpoints:
+ upload:
+ display-name: Upload audio
+ method: POST
+ path: ""
+ request:
+ name: TTSRequest
+ body:
+ properties:
+ text:
+ type: string
+ docs: The text that you want converted to speech.
+ response:
+ type: file
+ docs: The bytes of the audio file.
+```
+
+
+
+
+
diff --git a/fern/products/fern-def/pages/endpoints/multipart.mdx b/fern/products/fern-def/pages/endpoints/multipart.mdx
new file mode 100644
index 000000000..f5270d6ca
--- /dev/null
+++ b/fern/products/fern-def/pages/endpoints/multipart.mdx
@@ -0,0 +1,46 @@
+---
+title: Multipart File Upload
+description: Document endpoints with the `multiform` content type.
+---
+
+Endpoints in Fern are defined underneath the `endpoints` key. If your endpoint request includes file uploads, you can use the `file` type to indicate the request is of a `multiform` content type. The example below demonstrates an endpoint which includes a file in the request body.
+
+
+```yaml {12}
+service:
+ base-path: /documents
+ auth: false
+ endpoints:
+ uploadDocument:
+ path: /upload
+ method: POST
+ request:
+ name: UploadDocumentRequest
+ body:
+ properties:
+ file: file
+```
+
+
+Within a given multipart request, a string parameter with `format:binary` will represent an arbitrary file.
+
+## List of Files
+
+If your endpoint supports a list of files, then your request body must indicate such.
+
+
+```yaml {12}
+service:
+ base-path: /documents
+ auth: false
+ endpoints:
+ uploadDocuments:
+ path: /upload
+ method: POST
+ request:
+ name: UploadDocumentsRequest
+ body:
+ properties:
+ files: list
+```
+
diff --git a/fern/products/fern-def/pages/endpoints/rest.mdx b/fern/products/fern-def/pages/endpoints/rest.mdx
new file mode 100644
index 000000000..3a4459ba2
--- /dev/null
+++ b/fern/products/fern-def/pages/endpoints/rest.mdx
@@ -0,0 +1,45 @@
+---
+title: HTTP JSON Endpoints
+---
+
+Endpoints in Fern are defined underneath the `endpoints` key. Below is an example of defining
+a single REST endpoint:
+
+```yml title="users.yml" maxLines=0
+service:
+ base-path: /users
+ auth: false
+ endpoints:
+ createUser:
+ path: /create
+ method: POST
+ request:
+ body:
+ properties:
+ userName: string
+```
+
+## Examples
+
+You can provide examples of requests and responses by using the `examples` key.
+
+```yaml {11-17}
+service:
+ base-path: /users
+ auth: false
+ endpoints:
+ getUser:
+ path: /{userId}
+ path-parameters:
+ userId: string
+ method: GET
+ response: User
+ examples:
+ - path-parameters:
+ userId: alice-user-id
+ response:
+ body:
+ userId: alice-user-id
+ name: Alice
+```
+
diff --git a/fern/products/fern-def/pages/endpoints/sse.mdx b/fern/products/fern-def/pages/endpoints/sse.mdx
new file mode 100644
index 000000000..c1ab53770
--- /dev/null
+++ b/fern/products/fern-def/pages/endpoints/sse.mdx
@@ -0,0 +1,101 @@
+---
+title: Server-Sent Events and Streaming APIs
+subtitle: Use the `response-stream` key to model streaming endpoints
+---
+
+
+ Specifying `response-stream` on an endpoints allows you to represent endpoint responses that are streaming.
+
+
+
+## JSON streaming
+
+If your API returns a series of `JSON` chunks as seen below
+
+```json
+{ "text": "Hi, I am a" }
+{ "text": "chatbot. Do you have any"}
+{ "text": "questions for me"}
+```
+
+then simply specify the response under `response-stream` for your endpoint.
+
+```yaml title="chat.yml" {4}
+service:
+ base-path: /chat
+ endpoints:
+ stream:
+ method: POST
+ path: ""
+ response-stream: Chat
+
+types:
+ Chat:
+ properties:
+ text: string
+```
+
+## Server-sent events
+
+If your API returns server-sent-events, with the `data` and `event` keys as seen below
+
+```json
+data: { "text": "Hi, I am a" }
+data: { "text": "chatbot. Do you have any"}
+data: { "text": "questions for me"}
+```
+
+then make sure to include `format: sse`.
+
+```yaml title="chat.yml" {9}
+service:
+ base-path: /chat
+ endpoints:
+ stream:
+ method: POST
+ path: ""
+ response-stream:
+ type: Chat
+ format: sse
+
+types:
+ Chat:
+ properties:
+ text: string
+```
+
+## `Stream` parameter
+
+It has become common practice for endpoints to have a `stream` parameter that
+controls whether the response is streamed or not. Fern supports this pattern in a first
+class way.
+
+Simply specify the `stream-condition` as well as the ordinary response and the streaming response:
+
+```yaml title="chat.yml" {7}
+service:
+ base-path: /chat
+ endpoints:
+ stream:
+ method: POST
+ path: ""
+ stream-condition: $request.stream
+ request:
+ name: StreamChatRequest
+ body:
+ properties:
+ stream: boolean
+ response: Chat
+ response-stream:
+ type: ChatChunk
+ format: sse
+
+types:
+ Chat:
+ properties:
+ text: string
+ tokens: integer
+ ChatChunk:
+ properties:
+ text: string
+```
\ No newline at end of file
diff --git a/fern/products/fern-def/pages/errors.mdx b/fern/products/fern-def/pages/errors.mdx
new file mode 100644
index 000000000..60fa6e63a
--- /dev/null
+++ b/fern/products/fern-def/pages/errors.mdx
@@ -0,0 +1,25 @@
+---
+title: Errors in Fern Definition
+description: Add errors representing failed responses from API endpoints in Fern Definition.
+---
+
+Errors represent failed (non-200) responses from endpoints.
+
+An error has:
+
+- An HTTP status code
+- A body type _(Optional)_
+
+
+```yaml
+errors:
+ UserNotFoundError:
+ status-code: 404
+ type: UserNotFoundErrorBody
+
+types:
+ UserNotFoundErrorBody:
+ properties:
+ requestedUserId: string
+```
+
\ No newline at end of file
diff --git a/fern/products/fern-def/pages/examples.mdx b/fern/products/fern-def/pages/examples.mdx
new file mode 100644
index 000000000..b16ab4936
--- /dev/null
+++ b/fern/products/fern-def/pages/examples.mdx
@@ -0,0 +1,339 @@
+---
+title: Examples in Fern Definition
+subtitle: 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
+ 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
+```
+
+
+```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;
+};
+```
+
+
+### Lists
+
+```yml
+ Shipments:
+ type: list
+ 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
+```
+
+
+```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;
+```
+
+
+#### Undiscriminated union
+
+```yml
+types:
+ Animal:
+ discriminated: false
+ union:
+ - Dog
+ - Cat
+ examples:
+ - value:
+ likesToMeow: true
+ Dog:
+ properties:
+ likesToWoof: boolean
+ Cat:
+ properties:
+ likesToMeow: boolean
+```
+
+
+```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;
+```
+
+
+### Aliases
+
+```yml
+types:
+ UserId:
+ docs: A unique identifier for a user
+ type: string
+ examples:
+ - value: user-id-123
+```
+
+
+ ```typescript
+ /**
+ * A unique identifier for a user *
+ * @example "user-id-123"
+ */
+ type UserId = string;
+ ```
+
+
+## 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 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"
+```
diff --git a/fern/products/fern-def/pages/export-openapi.mdx b/fern/products/fern-def/pages/export-openapi.mdx
new file mode 100644
index 000000000..cf5b99cd4
--- /dev/null
+++ b/fern/products/fern-def/pages/export-openapi.mdx
@@ -0,0 +1,23 @@
+---
+title: Export from Fern Definition to OpenAPI
+description: Export your Fern Definition files to OpenAPI using Fern's OpenAPI generator.
+---
+
+To prevent lock-in to the Fern Definition format, we provide a generator that will export your Fern Def files to OpenAPI 3.1.
+This lets you switch to using OpenAPI at any time, or use your API definition with OpenAPI tools.
+To convert your Fern Definition to OpenAPI, use the `fern-openapi` generator.
+
+Update your `generators.yml` file:
+
+
+```yaml
+- name: fernapi/fern-openapi
+ version: 0.0.31
+ config:
+ format: yaml # options are yaml or json
+ output:
+ location: local-file-system
+ path: ../openapi # relative path to output location
+```
+
+
diff --git a/fern/products/fern-def/pages/imports.mdx b/fern/products/fern-def/pages/imports.mdx
new file mode 100644
index 000000000..d52749f86
--- /dev/null
+++ b/fern/products/fern-def/pages/imports.mdx
@@ -0,0 +1,22 @@
+---
+title: Imports in Fern Definition
+description: Use imports to reference API types and errors from other Fern Definition files.
+---
+
+Imports allow you to reference types and errors from other files.
+
+```yaml title="person.yml"
+types:
+ Person: ...
+```
+
+```yaml title="family.yml"
+imports:
+ person: ./path/to/person.yml
+types:
+ Family:
+ properties:
+ people: list # use an imported type
+```
+
+Note that you can only import files that exist in your Fern Definition (i.e., in the same `definition/` folder).
diff --git a/fern/products/fern-def/pages/overview.mdx b/fern/products/fern-def/pages/overview.mdx
new file mode 100644
index 000000000..25b04a2db
--- /dev/null
+++ b/fern/products/fern-def/pages/overview.mdx
@@ -0,0 +1,104 @@
+---
+title: What is a Fern Definition?
+subtitle: "A Fern Definition is a set of YAML files that describe your API."
+---
+
+A Fern Definition is a set of YAML files that are the single source of truth for your API. You check your Fern Definition into your repo,
+inside of which describes your API requests, responses, models, paths, methods, errors, and authentication scheme.
+
+
+ Want to use OpenAPI instead? No worries, we support that [as well](/learn/api-definition/introduction/what-is-an-api-definition#openapi-swagger)
+
+
+## Fern Definition structure
+
+To initialize a Fern Definition, simply run:
+
+```sh
+npm install -g fern-api
+fern init
+```
+
+This will create the following folder structure in your project:
+
+```bash
+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
+```
+
+## Definition file
+
+Each **Fern Definition** file may define:
+
+- **[Custom types](/learn/api-definition/fern/types)**. Use **custom types** to build your data model.
+- **[Endpoints](/learn/api-definition/fern/endpoints)**. A **service** is a set of related REST endpoints.
+- **[Errors](/learn/api-definition/fern/errors)**. An **error** represents a failed (non-200) response from an endpoint.
+- **[Imports](/learn/api-definition/fern/imports)**. Use **imports** to share types across files.
+
+```yml imdb.yml maxLines=0
+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:
+ - NotFoundError
+ - UnauthorizedError
+
+types:
+ Movie:
+ properties:
+ title: string
+ rating:
+ type: double
+ docs: The rating scale from one to five stars
+ id:
+ type: MovieId
+ docs: The unique identifier for a movie
+
+ CreateMovieRequest:
+ properties:
+ title: string
+ rating: double
+
+errors:
+ NotFoundError:
+ http:
+ statusCode: 404
+ type:
+ properties:
+ id: MovieId
+
+ UnauthorizedError:
+ http:
+ statusCode: 401
+```
+
+## Why another format?
+
+Google built gRPC. Amazon built Smithy. Facebook built GraphQL. Palantir built
+Conjure. These companies rejected OpenAPI in favor of a more concise API Definition Language.
+
+We built Fern to productize this design and make it accessible to all
+software companies.
+
+
+ Despite being a different format for describing APIs, **you are never locked in to Fern.** It's easy to convert your
+ [Fern Definition to OpenAPI](/learn/api-definition/fern/export-openapi).
+
diff --git a/fern/products/fern-def/pages/packages.mdx b/fern/products/fern-def/pages/packages.mdx
new file mode 100644
index 000000000..d66564568
--- /dev/null
+++ b/fern/products/fern-def/pages/packages.mdx
@@ -0,0 +1,153 @@
+---
+title: Packages in Fern Definition
+description: Fern Definition enables the reuse of API type and error names across packages, and can configure the structure of your API documentation.
+---
+
+## What is a package?
+
+Every folder in your API definition is a package.
+
+
+```bash
+fern/
+├─ fern.config.json
+├─ generators.yml
+└─ definition/ # <--- root package
+ ├─ api.yml
+ ├─ projects.yml
+ └─ roles/ # <--- nested package
+ └─ admin.yml
+```
+
+
+The generated SDK will match the hierarchy of your API definition.
+
+
+```ts
+const client = new Client();
+
+// calling endpoint defined in projects.yml
+client.projects.get();
+
+// calling endpoint defined in roles/admin.yml
+client.roles.admin.get();
+```
+
+
+## Package configuration
+
+Each package can have a special definition file called `__package__.yml`. Like any
+other definition file, it can contain [imports](/learn/api-definition/fern/imports),
+[types](/learn/api-definition/fern/types), [endpoints](/learn/api-definition/fern/endpoints),
+and [errors](/learn/api-definition/fern/errors).
+
+Endpoints in `__package__.yml` will appear at the root of the package.
+For example, the following generated SDK:
+
+
+```ts
+const client = new Client();
+
+client.getProjects();
+```
+
+
+would have a `fern/` folder:
+
+
+```bash {5}
+fern/
+├─ fern.config.json
+├─ generators.yml
+└─ definition/
+ ├─ __package__.yml
+ └─ roles.yml
+```
+
+
+that contains the following `__package__.yml`:
+
+
+```yaml
+service:
+ base-path: ""
+ auth: false
+ endpoints:
+ getProjects:
+ method: GET
+ path: ""
+ response: list
+```
+
+
+## Namespacing
+
+Each package has its own namespace. This means you can reuse type names and
+error names across packages.
+
+This is useful when versioning your APIs. For example, when you want to
+increment your API version, you can copy the existing API
+to a new package and start making changes. If the new API version reuses
+certain types or errors, that's okay because the two APIs live in different
+packages.
+
+
+```bash
+fern/
+├─ fern.config.json
+├─ generators.yml
+└─ definition/
+ ├─ api.yml
+ └─ roles/
+ └─ v1/
+ └─ admin.yml # type names can overlap with v2/admin.yml
+ └─ v2/
+ └─ admin.yml
+```
+
+
+## Navigation
+
+`__package__.yml` also allows you to configure the navigation order
+of your services. This is relevant when you want to control the display
+of your documentation.
+
+For example, let's say you have the following `fern/` folder:
+
+
+```bash
+fern/
+├─ fern.config.json
+├─ generators.yml
+└─ definition/
+ ├─ projects.yml
+ ├─ roles.yml
+ └─ users.yml
+```
+
+
+Your API will be sorted alphabetically: projects, roles, then users. If you
+want to control the navigation, you can add a `__package__.yml` file
+and configure the order:
+
+
+```bash
+fern/
+├─ fern.config.json
+├─ generators.yml
+└─ definition/
+ ├─ __package__.yml # <--- New File
+ ├─ projects.yml
+ ├─ roles.yml
+ └─ users.yml
+```
+
+
+
+```yaml
+navigation:
+ - users.yml
+ - roles.yml
+ - projects.yml
+```
+
\ No newline at end of file
diff --git a/fern/products/fern-def/pages/types.mdx b/fern/products/fern-def/pages/types.mdx
new file mode 100644
index 000000000..894f06b53
--- /dev/null
+++ b/fern/products/fern-def/pages/types.mdx
@@ -0,0 +1,279 @@
+---
+title: Types in Fern Definition
+description: Types describe the data model of your API. Fern has many built-in types and supports custom types, as well as extending and aliasing objects, and unions.
+---
+
+Types describe the data model of your API.
+
+## Built-in types
+
+- `string`
+- `integer`
+- `long`
+- `double`
+- `boolean`
+- `datetime` _An [RFC 3339, section 5.6 datetime](https://ijmacd.github.io/rfc3339-iso8601/). For example, `2017-07-21T17:32:28Z`._
+- `date` _An RFC 3339, section 5.6 date (YYYY-MM-DD). For example, `2017-07-21`._
+- `uuid`
+- `base64`
+- `list` _e.g., list\_
+- `set` _e.g., set\_
+- `map` _e.g., map\_
+- `optional` _e.g., optional\_
+- `literal` _e.g., literal\<"Plants"\>_
+- `file` _e.g., [file uploads](/learn/api-definition/fern/endpoints/multipart)_
+- `unknown` _Represents arbitrary JSON._
+
+## Custom types
+
+Creating your own types is easy in Fern!
+
+### Objects
+
+The most common custom types are **objects**.
+
+In Fern, you use the `"properties"` key to create an object:
+
+```yaml {3,8}
+types:
+ Person:
+ properties:
+ name: string
+ address: Address
+
+ Address:
+ properties:
+ line1: string
+ line2: optional
+ city: string
+ state: string
+ zip: string
+ country: literal<"USA">
+```
+
+These represent JSON objects:
+
+```json
+{
+ "name": "Alice",
+ "address": {
+ "line1": "123 Happy Lane",
+ "city": "New York",
+ "state": "NY",
+ "zip": "10001",
+ "country": "USA"
+ }
+}
+```
+
+You can also use **extends** to compose objects:
+
+```yaml {6}
+types:
+ Pet:
+ properties:
+ name: string
+ Dog:
+ extends: Pet
+ properties:
+ breed: string
+```
+
+You can extend multiple objects:
+
+```yaml {3-5}
+types:
+ GoldenRetriever:
+ extends:
+ - Dog
+ - Pet
+ properties:
+ isGoodBoy: boolean
+```
+
+### Aliases
+
+An Alias type is a renaming of an existing type. This is usually done for clarity.
+
+```yaml
+types:
+ # UserId is an alias of string
+ UserId: string
+
+ User:
+ properties:
+ id: UserId
+ name: string
+```
+
+### Enums
+
+An enum represents a string with a set of allowed values.
+
+In Fern, you use the `"enum"` key to create an enum:
+
+```yaml {3}
+types:
+ WeatherReport:
+ enum:
+ - SUNNY
+ - CLOUDY
+ - RAINING
+ - SNOWING
+```
+
+Enum names are restricted to `A-Z`, `a-z`, `0-9`, and `_` to ensure that generated code can compile across all of the languages that Fern can output. If you have an enum that doesn't follow this convention, you can use the `"name"` key to specify a custom name:
+
+```yaml
+types:
+ Operator:
+ enum:
+ - name: LESS_THAN # <--- the name that will be used in SDKs
+ value: '<' # <--- the value that will be serialized
+ - name: GREATER_THAN
+ value: '>'
+ - name: NOT_EQUAL
+ value: '!='
+```
+
+### Discriminated Unions
+
+Fern supports tagged unions (a.k.a. discriminated unions). Unions are useful for
+polymorphism. This is similar to the `oneOf` concept in OpenAPI.
+
+In Fern, you use the `"union"` key to create an union:
+
+```yaml {3-5}
+types:
+ Animal:
+ union:
+ dog: Dog
+ cat: Cat
+ Dog:
+ properties:
+ likesToWoof: boolean
+ Cat:
+ properties:
+ likesToMeow: boolean
+```
+
+In JSON, unions have a **discriminant property** to differentiate between
+different members of the union. By default, Fern uses `"type"` as the
+discriminant property:
+
+```json
+{
+ "type": "dog",
+ "likesToWoof": true
+}
+```
+
+You can customize the discriminant property using the "discriminant" key:
+
+```yaml {3}
+ types:
+ Animal:
+ discriminant: animalType
+ union:
+ dog: Dog
+ cat: Cat
+ Dog:
+ properties:
+ likesToWoof: boolean
+ Cat:
+ properties:
+ likesToMeow: boolean
+```
+
+This corresponds to a JSON object like this:
+
+```json
+{
+ "animalType": "dog",
+ "likesToWoof": true
+}
+```
+
+### Undiscriminated Unions
+
+Undiscriminated unions are similar to discriminated unions, however you don't
+need to define an explicit discriminant property.
+
+```yaml
+MyUnion:
+ discriminated: false
+ union:
+ - string
+ - integer
+```
+
+### Generics
+
+Fern supports shallow generic objects, to minimize code duplication. You can
+define a generic for reuse like so:
+
+```yaml
+MySpecialMapItem:
+ properties:
+ key: Key,
+ value: Value,
+ diagnostics: string
+```
+
+Now, you can instantiate generic types as a type alias:
+
+```yml
+StringIntegerMapItem:
+ type: Response
+
+StringStringMapItem:
+ type: Response
+```
+
+You can now freely use this type as if it were any other type! Note, generated
+code will not use generics. The above example will be generated in typescript as:
+
+```typescript
+type StringIntegerMapItem = {
+ key: string,
+ value: number,
+ diagnostics: string
+}
+
+type StringStringMapItem = {
+ key: string,
+ value: string,
+ diagnostics: string
+}
+```
+
+### Documenting types
+
+You can add documentation for types. These docs are passed into the compiler,
+and are incredibly useful in the generated outputs (e.g., docstrings in SDKs).
+
+
+```yaml
+types:
+ Person:
+ docs: A person represents a human being
+ properties:
+ name: string
+ age:
+ docs: age in years
+ type: integer
+```
+
+
+
+```typescript
+/**
+ * A person represents a human being
+ */
+interface Person {
+ name: string;
+ // age in years
+ age: number;
+}
+```
+
diff --git a/fern/products/fern-def/pages/webhooks.mdx b/fern/products/fern-def/pages/webhooks.mdx
new file mode 100644
index 000000000..399c3c2a1
--- /dev/null
+++ b/fern/products/fern-def/pages/webhooks.mdx
@@ -0,0 +1,65 @@
+---
+title: Webhooks in the Fern Definition
+description: Learn how to define webhooks in the Fern Definition
+---
+
+In Fern, you can specify webhooks in your API definition. The webhooks will be included
+in both the generated SDKs and the API documentation.
+
+## Webhook definition
+
+Each webhook defines:
+
+1. **Method**: The HTTP Method that the webhook will use (either `GET` or `POST`)
+2. **Headers**: The headers that the webhook will send
+3. **Payload**: The schema of the webhook payload
+
+
+ ```yaml {2-10}
+ webhooks:
+ paymentNotification:
+ display-name: Payment Notification
+ docs: Receive a notification when a payment changes status
+ method: POST
+ headers:
+ X-Signature-Primary:
+ type: string
+ docs: An HMAC signature of the payload
+ payload: PaymentNotificationPayload
+
+ types:
+ PaymentNotificationPayload:
+ discriminant: notificationType
+ union:
+ queued: QueuedPaymentNotification
+ processing: ProcessingPaymentNotification
+ completed: CompletedPaymentNotification
+ ```
+
+
+### Inlined payloads
+
+You can inline the schema of the payload by doing the following:
+
+
+ ```yaml
+ webhooks:
+ paymentNotification:
+ display-name: Payment Notification
+ docs: Receive a notification when a payment changes status
+ method: POST
+ headers:
+ X-Signature-Primary:
+ type: string
+ docs: An HMAC signature of the payload
+ payload:
+ name: PaymentNotificationPayload
+ properties:
+ id:
+ type: string
+ docs: The notification id
+ amount: double
+ currency: Currency
+ ```
+
+
diff --git a/fern/products/fern-def/pages/websocket.png b/fern/products/fern-def/pages/websocket.png
new file mode 100644
index 000000000..e7f3cc355
Binary files /dev/null and b/fern/products/fern-def/pages/websocket.png differ
diff --git a/fern/products/fern-def/pages/websockets.mdx b/fern/products/fern-def/pages/websockets.mdx
new file mode 100644
index 000000000..efac1a6e0
--- /dev/null
+++ b/fern/products/fern-def/pages/websockets.mdx
@@ -0,0 +1,96 @@
+---
+title: WebSockets in the Fern Definition
+description: Learn how to define WebSockets in the Fern Definition
+---
+
+WebSockets enable a user to create a connection with a server, over which bidirectional communication can be sent.
+
+In Fern, you can specify WebSockets in your API definition. The WebSockets will be included in both the generated SDKs and the API documentation.
+
+## WebSocket definition
+Each WebSocket is defined in its own file, where it is described by the `channel` object.
+
+### The channel object
+
+A `channel` is defined by the following fields:
+
+- `auth`: The authentication scheme for the WebSocket
+- `path`: The path of the WebSocket
+- `headers` _(Optional)_: Any headers the WebSocket will send
+- `path-parameters` _(Optional)_: Any path parameters in the WebSocket path
+- `query-parameters` _(Optional)_: Any query parameters used in the initial request of the WebSocket
+- `messages` _(Optional)_: The schemas of the messages the WebSocket can send and receive once connected
+ - `origin`: The entity that sent the message (e.g. `client` or `server`)
+ - `body`: The schema of the message
+- `examples`: Example WebSocket connection _(Optional)_
+
+### WebSocket example
+
+
+ ```yaml
+ channel:
+ path: /chat
+ auth: false
+ query-parameters:
+ model_id:
+ type: optional
+ docs: The unique identifier of the model.
+ model_version:
+ type: optional
+ docs: The version number of the model.
+ messages:
+ publish:
+ origin: client
+ body: PublishEvent
+ subscribe:
+ origin: server
+ body: SubscribeEvent
+ examples:
+ - query-parameters:
+ model_id: "123"
+ messages:
+ - type: publish
+ body:
+ text: "Hello, world."
+ - type: subscribe
+ body:
+ id: "23823049"
+ message: "Hello there, how are you?"
+ types:
+ PublishEvent:
+ docs: The input from the user to send through the WebSocket.
+ properties:
+ text:
+ type: string
+ docs: The user text to send into the conversation.
+ SubscribeEvent:
+ docs: The response from the server sent through the WebSocket.
+ properties:
+ id:
+ type: string
+ docs: The id of the message.
+ message:
+ type: string
+ docs: The message sent through the socket.
+ ```
+
+
+## WebSocket API Reference
+
+### WebSocket Reference
+
+Fern renders a unique reference page for WebSockets. The **Handshake** section outlines the protocol for connecting with the server, while the **Send** and **Receive** sections outline the message schemas that can be sent between the client and server.
+
+
+
+
+
+### WebSocket Playground
+
+
+
+Users can connect to and use WebSockets from right within the API Reference (check one of Hume's WebSockets [here](https://dev.hume.ai/reference/empathic-voice-interface-evi/chat/chat)).
+
+
+
+
\ No newline at end of file
diff --git a/fern/products/fern-def/pages/wss-reference.png b/fern/products/fern-def/pages/wss-reference.png
new file mode 100644
index 000000000..cfef31111
Binary files /dev/null and b/fern/products/fern-def/pages/wss-reference.png differ
diff --git a/fern/products/openapi-def/openapi-def.yml b/fern/products/openapi-def/openapi-def.yml
index 07abf61a7..df5fe5969 100644
--- a/fern/products/openapi-def/openapi-def.yml
+++ b/fern/products/openapi-def/openapi-def.yml
@@ -1,61 +1,46 @@
navigation:
- - section: Getting Started
+ - page: Overview
+ path: ./pages/overview.mdx
+ - page: Authentication
+ path: ./pages/auth.mdx
+ - page: Servers
+ path: ./pages/servers.mdx
+ - section: Endpoints
+ slug: endpoints
contents:
- - page: Overview
- path: ./pages/getting-started/overview.mdx
- - page: Get to OpenAPI
- path: ./pages/getting-started/get-to-openapi.mdx
- - page: Philosophy
- path: ./pages/getting-started/philosophy.mdx
- - page: Customer Showcase
- path: ./pages/getting-started/customer-showcase.mdx
- - section: Get to OpenAPI
- contents:
- - page: Handwrite it
- path: ./pages/getting-started/get-to-openapi/handwrite-it.mdx
- - section: Generate it
- contents:
- - page: FastAPI
- path: ./pages/getting-started/get-to-openapi/generate-it/fastapi.mdx
- - page: NestJS
- path: ./pages/getting-started/get-to-openapi/generate-it/nestjs.mdx
- - page: Swaggo
- path: ./pages/getting-started/get-to-openapi/generate-it/swaggo.mdx
- - page: Request a new framework
- path: ./pages/getting-started/get-to-openapi/generate-it/request-new-framework.mdx
- - page: Overlay customizations
- path: ./pages/getting-started/overlay-customizations.mdx
- - section: Security Schemes
+ - page: HTTP JSON Endpoints
+ path: ./pages/endpoints/rest.mdx
+ slug: http
+ - page: Multipart Form Uploads
+ path: ./pages/endpoints/multipart.mdx
+ slug: multipart
+ - page: Server-Sent Events
+ path: ./pages/endpoints/sse.mdx
+ slug: sse
+ - page: Webhooks
+ path: ./pages/webhooks.mdx
+ - page: Audiences
+ path: ./pages/extensions/audiences.mdx
+ slug: audiences
+ - section: Extensions
+ slug: extensions
contents:
- - page: Overview
- path: ./pages/security-schemes/overview.mdx
- - page: Overriding the security scheme
- path: ./pages/security-schemes/overriding-security-scheme.mdx
- - page: Multiple security schemes
- path: ./pages/security-schemes/multiple-security-schemes.mdx
- - section: Servers
+ - page: SDK Method Names
+ path: ./pages/extensions/method-names.mdx
+ slug: method-names
+ - page: Parameter Names
+ path: ./pages/extensions/parameter-names.mdx
+ - page: Other
+ path: ./pages/extensions/others.mdx
+ slug: others
+ - page: Overlay Customizations
+ path: ./pages/overrides.mdx
+ - page: Sync your OpenAPI Specification
+ path: ./pages/automation.mdx
+ - section: Integrate your Server Framework
+ slug: frameworks
contents:
- - page: Overview
- path: ./pages/servers/overview.mdx
- - page: Overriding the servers
- path: ./pages/servers/overriding-servers.mdx
- - page: Naming your servers
- path: ./pages/servers/naming-your-servers.mdx
- - page: Multiple server URLs
- path: ./pages/servers/multiple-server-urls.mdx
- - section: Schemas
- contents:
- - page: Objects
- path: ./pages/schemas/objects.mdx
- - page: AllOf
- path: ./pages/schemas/allof.mdx
- - page: OneOf
- path: ./pages/schemas/oneof.mdx
- - page: AnyOf
- path: ./pages/schemas/anyof.mdx
- - page: Enums
- path: ./pages/schemas/enums.mdx
- - page: Override the type
- path: ./pages/schemas/override-type.mdx
- - page: Inlined schemas
- path: ./pages/schemas/inlined-schemas.mdx
+ - page: FastAPI
+ icon: fa-regular fa-circle-bolt
+ path: ./pages/server-frameworks/fastapi.mdx
+ slug: fastapi
diff --git a/fern/products/openapi-def/pages/getting-started/customer-showcase.mdx b/fern/products/openapi-def/pages-archived/getting-started/customer-showcase.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/getting-started/customer-showcase.mdx
rename to fern/products/openapi-def/pages-archived/getting-started/customer-showcase.mdx
diff --git a/fern/products/openapi-def/pages/getting-started/get-to-openapi.mdx b/fern/products/openapi-def/pages-archived/getting-started/get-to-openapi.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/getting-started/get-to-openapi.mdx
rename to fern/products/openapi-def/pages-archived/getting-started/get-to-openapi.mdx
diff --git a/fern/products/openapi-def/pages/getting-started/get-to-openapi/generate-it/fastapi.mdx b/fern/products/openapi-def/pages-archived/getting-started/get-to-openapi/generate-it/fastapi.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/getting-started/get-to-openapi/generate-it/fastapi.mdx
rename to fern/products/openapi-def/pages-archived/getting-started/get-to-openapi/generate-it/fastapi.mdx
diff --git a/fern/products/openapi-def/pages/getting-started/get-to-openapi/generate-it/nestjs.mdx b/fern/products/openapi-def/pages-archived/getting-started/get-to-openapi/generate-it/nestjs.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/getting-started/get-to-openapi/generate-it/nestjs.mdx
rename to fern/products/openapi-def/pages-archived/getting-started/get-to-openapi/generate-it/nestjs.mdx
diff --git a/fern/products/openapi-def/pages/getting-started/get-to-openapi/generate-it/request-new-framework.mdx b/fern/products/openapi-def/pages-archived/getting-started/get-to-openapi/generate-it/request-new-framework.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/getting-started/get-to-openapi/generate-it/request-new-framework.mdx
rename to fern/products/openapi-def/pages-archived/getting-started/get-to-openapi/generate-it/request-new-framework.mdx
diff --git a/fern/products/openapi-def/pages/getting-started/get-to-openapi/generate-it/swaggo.mdx b/fern/products/openapi-def/pages-archived/getting-started/get-to-openapi/generate-it/swaggo.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/getting-started/get-to-openapi/generate-it/swaggo.mdx
rename to fern/products/openapi-def/pages-archived/getting-started/get-to-openapi/generate-it/swaggo.mdx
diff --git a/fern/products/openapi-def/pages/getting-started/get-to-openapi/handwrite-it.mdx b/fern/products/openapi-def/pages-archived/getting-started/get-to-openapi/handwrite-it.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/getting-started/get-to-openapi/handwrite-it.mdx
rename to fern/products/openapi-def/pages-archived/getting-started/get-to-openapi/handwrite-it.mdx
diff --git a/fern/products/openapi-def/pages/getting-started/overlay-customizations.mdx b/fern/products/openapi-def/pages-archived/getting-started/overlay-customizations.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/getting-started/overlay-customizations.mdx
rename to fern/products/openapi-def/pages-archived/getting-started/overlay-customizations.mdx
diff --git a/fern/products/openapi-def/pages/getting-started/overview.mdx b/fern/products/openapi-def/pages-archived/getting-started/overview.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/getting-started/overview.mdx
rename to fern/products/openapi-def/pages-archived/getting-started/overview.mdx
diff --git a/fern/products/openapi-def/pages/getting-started/philosophy.mdx b/fern/products/openapi-def/pages-archived/getting-started/philosophy.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/getting-started/philosophy.mdx
rename to fern/products/openapi-def/pages-archived/getting-started/philosophy.mdx
diff --git a/fern/products/openapi-def/pages/schemas/allof.mdx b/fern/products/openapi-def/pages-archived/schemas/allof.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/schemas/allof.mdx
rename to fern/products/openapi-def/pages-archived/schemas/allof.mdx
diff --git a/fern/products/openapi-def/pages/schemas/anyof.mdx b/fern/products/openapi-def/pages-archived/schemas/anyof.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/schemas/anyof.mdx
rename to fern/products/openapi-def/pages-archived/schemas/anyof.mdx
diff --git a/fern/products/openapi-def/pages/schemas/enums.mdx b/fern/products/openapi-def/pages-archived/schemas/enums.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/schemas/enums.mdx
rename to fern/products/openapi-def/pages-archived/schemas/enums.mdx
diff --git a/fern/products/openapi-def/pages/schemas/inlined-schemas.mdx b/fern/products/openapi-def/pages-archived/schemas/inlined-schemas.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/schemas/inlined-schemas.mdx
rename to fern/products/openapi-def/pages-archived/schemas/inlined-schemas.mdx
diff --git a/fern/products/openapi-def/pages/schemas/objects.mdx b/fern/products/openapi-def/pages-archived/schemas/objects.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/schemas/objects.mdx
rename to fern/products/openapi-def/pages-archived/schemas/objects.mdx
diff --git a/fern/products/openapi-def/pages/schemas/oneof.mdx b/fern/products/openapi-def/pages-archived/schemas/oneof.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/schemas/oneof.mdx
rename to fern/products/openapi-def/pages-archived/schemas/oneof.mdx
diff --git a/fern/products/openapi-def/pages/schemas/override-type.mdx b/fern/products/openapi-def/pages-archived/schemas/override-type.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/schemas/override-type.mdx
rename to fern/products/openapi-def/pages-archived/schemas/override-type.mdx
diff --git a/fern/products/openapi-def/pages/security-schemes/multiple-security-schemes.mdx b/fern/products/openapi-def/pages-archived/security-schemes/multiple-security-schemes.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/security-schemes/multiple-security-schemes.mdx
rename to fern/products/openapi-def/pages-archived/security-schemes/multiple-security-schemes.mdx
diff --git a/fern/products/openapi-def/pages/security-schemes/overriding-security-scheme.mdx b/fern/products/openapi-def/pages-archived/security-schemes/overriding-security-scheme.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/security-schemes/overriding-security-scheme.mdx
rename to fern/products/openapi-def/pages-archived/security-schemes/overriding-security-scheme.mdx
diff --git a/fern/products/openapi-def/pages/security-schemes/overview.mdx b/fern/products/openapi-def/pages-archived/security-schemes/overview.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/security-schemes/overview.mdx
rename to fern/products/openapi-def/pages-archived/security-schemes/overview.mdx
diff --git a/fern/products/openapi-def/pages/servers/multiple-server-urls.mdx b/fern/products/openapi-def/pages-archived/servers/multiple-server-urls.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/servers/multiple-server-urls.mdx
rename to fern/products/openapi-def/pages-archived/servers/multiple-server-urls.mdx
diff --git a/fern/products/openapi-def/pages/servers/naming-your-servers.mdx b/fern/products/openapi-def/pages-archived/servers/naming-your-servers.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/servers/naming-your-servers.mdx
rename to fern/products/openapi-def/pages-archived/servers/naming-your-servers.mdx
diff --git a/fern/products/openapi-def/pages/servers/overriding-servers.mdx b/fern/products/openapi-def/pages-archived/servers/overriding-servers.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/servers/overriding-servers.mdx
rename to fern/products/openapi-def/pages-archived/servers/overriding-servers.mdx
diff --git a/fern/products/openapi-def/pages/servers/overview.mdx b/fern/products/openapi-def/pages-archived/servers/overview.mdx
similarity index 100%
rename from fern/products/openapi-def/pages/servers/overview.mdx
rename to fern/products/openapi-def/pages-archived/servers/overview.mdx
diff --git a/fern/products/openapi-def/pages/auth.mdx b/fern/products/openapi-def/pages/auth.mdx
new file mode 100644
index 000000000..1f9ea850b
--- /dev/null
+++ b/fern/products/openapi-def/pages/auth.mdx
@@ -0,0 +1,196 @@
+---
+title: Authentication
+subtitle: Model auth schemes such as bearer, basic, and api key.
+---
+
+Configuring authentication schemes happens in the `components.securitySchemes` section of OpenAPI.
+
+```yml title="openapi.yml" {2-3}
+components:
+ securitySchemes:
+ ...
+```
+
+
+To apply a security scheme across all endpoints, reference the `securityScheme` within the `security` section of your OpenAPI Specification.
+
+```yml title="openapi.yml" {3, 5-6}
+components:
+ securitySchemes:
+ AuthScheme:
+ ...
+security:
+ - AuthScheme: []
+```
+
+
+## Bearer security scheme
+
+Start by defining a `bearer` security scheme in your `openapi.yml`:
+
+```yml title="openapi.yml" {3-5}
+components:
+ securitySchemes:
+ BearerAuth:
+ type: http
+ scheme: bearer
+```
+
+This will generate an SDK where the user would have to provide
+a mandatory argument called `token`.
+
+```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:
+
+```yaml title="openapi.yml" {6-8}
+components:
+ securitySchemes:
+ BearerAuth:
+ type: http
+ scheme: bearer
+ x-fern-bearer:
+ name: apiKey
+ env: PLANTSTORE_API_KEY
+```
+
+The generated SDK would look like:
+
+```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 security scheme
+
+Start by defining a `basic` security scheme in your `openapi.yml`:
+
+```yaml title="openapi.yml" {3-5}
+components:
+ securitySchemes:
+ BasicAuth:
+ type: http
+ scheme: basic
+```
+
+This will generate an SDK where the user would have to provide
+a mandatory arguments called `username` and `password`.
+
+```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:
+
+```yaml title="openapi.yml" {6-12}
+components:
+ securitySchemes:
+ BasicAuth:
+ type: http
+ scheme: basic
+ x-fern-basic:
+ username:
+ name: clientId
+ env: PLANTSTORE_CLIENT_ID
+ password:
+ name: clientSecret
+ env: PLANTSTORE_CLIENT_SECRET
+```
+
+The generated SDK would look like:
+
+```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..."
+})
+```
+
+## ApiKey security scheme
+
+Start by defining an `apiKey` security scheme in your `openapi.yml`:
+
+```yml title="openapi.yml" {3-5}
+components:
+ securitySchemes:
+ ApiKey:
+ type: apiKey
+ in: header
+ name: X_API_KEY
+```
+
+This will generate an SDK where the user would have to provide
+a mandatory argument called `apiKey`.
+
+```ts index.ts
+const client = new Client({
+ apiKey: "ey34..."
+})
+```
+
+If you want to control variable naming and environment variables to scan,
+use the configuration below:
+
+```yaml title="openapi.yml" {7-10}
+components:
+ securitySchemes:
+ ApiKey:
+ type: apiKey
+ in: header
+ name: X_API_KEY
+ x-fern-header:
+ name: apiToken
+ env: PLANTSTORE_API_KEY
+ prefix: "Token " # Optional
+```
+
+The generated SDK would look like:
+
+```ts index.ts
+
+// Uses process.env.PLANTSTORE_API_KEY
+let client = new Client();
+
+// parameters have been renamed
+client = new Client({
+ apiToken: "ey34..."
+})
+```
+
+## Multiple security schemes
+
+If you would like to define multiple security schemes, simply
+list them under `components.securitySchemes`. For example, if you wanted to support
+`basic` and `apiKey` security schemes, see the example below:
+
+```yaml title="openapi.yml" {3,6}
+components:
+ securitySchemes:
+ BearerAuth:
+ type: http
+ scheme: bearer
+ ApiKey:
+ type: apiKey
+ in: header
+ name: X_API_KEY
+```
\ No newline at end of file
diff --git a/fern/products/openapi-def/pages/automation.mdx b/fern/products/openapi-def/pages/automation.mdx
new file mode 100644
index 000000000..5b974583e
--- /dev/null
+++ b/fern/products/openapi-def/pages/automation.mdx
@@ -0,0 +1,54 @@
+---
+title: Sync your OpenAPI Specification
+subtitle: Pull your latest OpenAPI Specification into your Fern Folder automatically.
+---
+
+If you host your OpenAPI Specification at a publicly available URL, you can have Fern programmatically fetch the latest spec on a preconfigured cadence through the [sync-openapi GitHub Action](https://github.com/fern-api/sync-openapi). This ensures your committed OpenAPI spec stays up to date with your live API.
+## Setup
+
+
+ Add the origin field to your generators.yml to specify where your OpenAPI spec is hosted:
+ ```yml title="generators.yml"
+ api:
+ path: openapi/openapi.json
+ origin: https://api.example.com/openapi.json
+ ```
+
+
+ Create `.github/workflows/sync-openapi.yml` in your repository:
+ ```yml
+ name: Sync OpenAPI Specs # can be customized
+ on: # additional custom triggers can be configured
+ workflow_dispatch: # manual dispatch
+ push:
+ branches:
+ - main # on push to main
+ schedule:
+ - cron: '0 3 * * *' # everyday at 3:00 AM UTC
+ jobs:
+ update-from-source:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ token: ${{ secrets.OPENAPI_SYNC_TOKEN }}
+ - name: Update API with Fern
+ uses: fern-api/sync-openapi@v2
+ with:
+ update_from_source: true
+ token: ${{ secrets.OPENAPI_SYNC_TOKEN }}
+ branch: 'update-api'
+ auto_merge: false
+ add_timestamp: true
+```
+
+
+ Generate a [fine-grained personal access token](https://github.com/settings/personal-access-tokens) with read/write access to your repository.
+
+
+ Navigate to your repository's `Settings > Secrets and variables > Actions`. Select **New repository secret**, name it `OPENAPI_SYNC_TOKEN`, add your token, and click **Add secret**.
+
+
+By default, this will create daily PRs with API spec updates to the repo containing your Fern folder. If you would like to adjust the frequency, learn more about GitHub's [schedule event](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#schedule).
+
+ For detailed configuration options and other use cases, see the [sync-openapi GitHub Action README](https://github.com/fern-api/sync-openapi).
diff --git a/fern/products/openapi-def/pages/endpoints/multipart.mdx b/fern/products/openapi-def/pages/endpoints/multipart.mdx
new file mode 100644
index 000000000..800fa0fa1
--- /dev/null
+++ b/fern/products/openapi-def/pages/endpoints/multipart.mdx
@@ -0,0 +1,75 @@
+---
+title: Multipart File Upload
+subtitle: Document endpoints with the `multipart/form-data` content type
+---
+
+Multipart requests combine one or more sets of data into a single body, separated by boundaries.
+You typically use these requests for file uploads and for transferring data of several types in a single request
+(for example, a file along with a JSON object).
+
+```yml title="openapi.yml" maxLines=0 {12-24}
+paths:
+ /upload:
+ post:
+ summary: Upload a file
+ description: Upload a file using multipart/form-data encoding
+ operationId: uploadFile
+ tags:
+ - file
+ requestBody:
+ required: true
+ content:
+ multipart/form-data:
+ schema:
+ type: object
+ properties:
+ file:
+ type: string
+ format: binary
+ description: The file to upload
+ description:
+ type: string
+ description: A description of the file (optional)
+ required:
+ - file
+ responses:
+ "200":
+ description: Successful upload
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ message:
+ type: string
+ fileId:
+ type: string
+```
+Any request body that is defined with a `multipart/form-data` content type, will be
+treated as a multipart request. Within a given multipart request, a string parameter with
+`format:binary` will represent an arbitrary file.
+
+## Array of Files
+
+If your endpoint supports an array of files, then your request body must use
+an array type.
+
+```yml openapi.yml {12-17}
+paths:
+ /upload:
+ post:
+ summary: Upload multiple files
+ operationId: uploadFiles
+ requestBody:
+ content:
+ multipart/form-data:
+ schema:
+ type: object
+ properties:
+ files:
+ type: array
+ items:
+ type: string
+ format: binary
+ description: An array of files to upload
+```
diff --git a/fern/products/openapi-def/pages/endpoints/rest.mdx b/fern/products/openapi-def/pages/endpoints/rest.mdx
new file mode 100644
index 000000000..a4dd8fcb4
--- /dev/null
+++ b/fern/products/openapi-def/pages/endpoints/rest.mdx
@@ -0,0 +1,66 @@
+---
+title: HTTP JSON Endpoints
+subtitle: Document HTTP JSON APIs with the `application/json` content type
+---
+
+Endpoints in OpenAPI are defined underneath the `paths` key. Below is an example of defining
+a single endpoint:
+
+```yml title="openapi.yml" maxLines=0 {2-18}
+paths:
+ /pets:
+ post:
+ summary: Create a new pet
+ description: Creates a new pet with the provided information
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Pet'
+ responses:
+ '200':
+ description: User created successfully
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Pet'
+```
+
+## Examples
+
+You can provide examples of requests and responses by using the `examples` key.
+
+```yaml title="openapi.yml" {12-17,25-30}
+paths:
+ /pets:
+ post:
+ summary: Create a new pet
+ description: Creates a new pet with the provided information
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Pet'
+ examples:
+ PetExample:
+ summary: This is an example of a Pet
+ value:
+ name: Markley
+ id: 44
+ responses:
+ '200':
+ description: A Pet object
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Pet'
+ examples:
+ PetExample:
+ summary: This is an example of a Pet
+ value:
+ name: Markley
+ id: 44
+```
+
diff --git a/fern/products/openapi-def/pages/endpoints/sse.mdx b/fern/products/openapi-def/pages/endpoints/sse.mdx
new file mode 100644
index 000000000..bc680cfe1
--- /dev/null
+++ b/fern/products/openapi-def/pages/endpoints/sse.mdx
@@ -0,0 +1,109 @@
+---
+title: Server-Sent Events and Streaming APIs
+subtitle: Use the `x-fern-streaming` extension to model streaming endpoints
+---
+
+
+ The `x-fern-streaming` extension allows you to represent endpoints that are streaming.
+
+
+
+## JSON streaming
+
+If your API returns a series of `JSON` chunks as seen below
+
+```json
+{ "text": "Hi, I am a" }
+{ "text": "chatbot. Do you have any"}
+{ "text": "questions for me"}
+```
+
+then simply add the `x-fern-streaming: true` to your OpenAPI operation.
+
+```yaml title="openapi.yml" {4}
+paths:
+ /logs:
+ post:
+ x-fern-streaming: true
+ responses:
+ "200":
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Chat"
+components:
+ schemas:
+ Chat:
+ type: object
+ properties:
+ text:
+ type: string
+```
+
+## Server-sent events
+
+If your API returns server-sent-events, with the `data` and `event` keys as seen below
+
+```json
+data: { "text": "Hi, I am a" }
+data: { "text": "chatbot. Do you have any"}
+data: { "text": "questions for me"}
+```
+
+then make sure to include `format: sse`.
+
+```yaml title="openapi.yml" {4-5}
+paths:
+ /logs:
+ post:
+ x-fern-streaming:
+ format: sse
+ responses:
+ "200":
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Chat"
+components:
+ schemas:
+ Chat:
+ type: object
+ properties:
+ text:
+ type: string
+```
+
+## `Stream` parameter
+
+It has become common practice for endpoints to have a `stream` parameter that
+controls whether the response is streamed or not. Fern supports this pattern in a first
+class way.
+
+Simply specify the `stream-condition` as well as the ordinary response and the streaming response:
+
+```yaml title="openapi.yml" {4-10}
+paths:
+ /logs:
+ post:
+ x-fern-streaming:
+ format: sse
+ stream-condition: $request.stream
+ response:
+ $ref: '#/components/schemas/Chat'
+ response-stream:
+ $ref: '#/components/schemas/ChatChunk'
+components:
+ schemas:
+ Chat:
+ type: object
+ properties:
+ text:
+ type: string
+ tokens:
+ type: number
+ ChatChunk:
+ type: object
+ properties:
+ text:
+ type: string
+```
\ No newline at end of file
diff --git a/fern/products/openapi-def/pages/examples.mdx b/fern/products/openapi-def/pages/examples.mdx
new file mode 100644
index 000000000..e4a77240e
--- /dev/null
+++ b/fern/products/openapi-def/pages/examples.mdx
@@ -0,0 +1,93 @@
+---
+title: How to use examples in OpenAPI
+description: Use the examples feature of OpenAPI to add example values in your API definition. Fern then uses your examples when generating SDKs and documentation.
+---
+
+Using examples in OpenAPI shows API consumers what requests and responses look like. They can be provided for request bodies, response bodies, and individual parameters.
+
+## Inline examples
+
+Examples can be placed directly within the operation definition under `paths`. Here's an example:
+
+```yaml
+paths:
+ /pet:
+ post:
+ summary: Add a new pet to the store
+ operationId: addPet
+ responses:
+ '200':
+ description: A Pet object
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Pet'
+ examples:
+ PetExample:
+ summary: This is an example of a Pet
+ value:
+ name: Markley
+ id: 44
+```
+
+## Reusable examples
+
+For more general examples that apply to multiple parts of the API, you can define them under the `components/examples` section. These can be referenced elsewhere in the documentation.
+
+```yaml
+components:
+ examples:
+ PetExample:
+ summary: Example of a Pet object
+ value:
+ name: Markley
+ id: 44
+
+paths:
+ /pet:
+ post:
+ summary: Add a new pet to the store
+ operationId: addPet
+ responses:
+ '200':
+ description: Successful operation
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Pet'
+ examples:
+ PetExample:
+ $ref: '#/components/examples/PetExample'
+```
+
+## How examples are used in Fern SDKs
+
+Fern SDKs use examples from your OpenAPI document to generate comments that show up in your IDE. For example, in a Node.js SDK:
+
+
+```ts
+
+import * as Petstore from "../../..";
+
+/**
+ * @example
+ * {
+ * name: "Markley",
+ * id: "44"
+ * }
+ */
+```
+
+
+Here's an [example in GitHub](https://github.com/FlatFilers/flatfile-node/blob/ab955a0a337c40ea00755e24df08f8c9a146c39c/src/api/resources/documents/types/DocumentResponse.ts#L8-L27) from Flatfile's Node.js SDK.
+
+## How examples are used in Fern Docs
+
+In the request and response code snippets, you'll see the example values used.
+
+
+
+
+
+If you generate SDKs with Fern, the code examples for each language will also be populated with the example values. [Check out Flatfile's Docs to see this in action](https://reference.flatfile.com/api-reference/documents/create). Change the language toggle to see the examples in different languages.
+
diff --git a/fern/products/openapi-def/pages/extensions/audiences.mdx b/fern/products/openapi-def/pages/extensions/audiences.mdx
new file mode 100644
index 000000000..8bd80fc5f
--- /dev/null
+++ b/fern/products/openapi-def/pages/extensions/audiences.mdx
@@ -0,0 +1,118 @@
+---
+title: Use audiences to filter your API
+subtitle: Use `x-fern-audiences` to filter to relevant endpoints, schemas and properties
+---
+
+Audiences are a useful tool for segmenting your API for different consumers. Common examples of audiences include `public`
+and `beta`.
+
+
+ Remember to filter your SDKs and Docs after specifying audiences. If **no audiences** are specified,
+ nothing will be filtered.
+
+
+
+
+The following example configures the SDK to filter to the `public` audience:
+
+```yaml title="generators.yml" {3-4}
+groups:
+ sdks:
+ audiences:
+ - public
+ generators:
+ - name: fernapi/fern-typescript-node-sdk
+ version: 0.8.8
+```
+
+
+
+The following example configures the docs to filter to the `public` audience:
+
+```yaml title="docs.yml" {3-4}
+navigation:
+ - api: API Reference
+ audiences:
+ - public
+```
+
+
+
+
+
+
+## Audiences for servers
+
+To mark a server with a particular audience, add the `x-fern-server-name` and `x-fern-audiences` extension to the relevant server.
+
+In the example below, the `Production` server is only available to public consumers:
+
+```yaml title="openapi.yml" {3-5}
+servers:
+ - url: https://api.com
+ x-fern-server-name: Production
+ x-fern-audiences:
+ - public
+```
+
+## Audiences for endpoints
+
+To mark an endpoint with a particular audience, add the `x-fern-audiences` extension to the relevant endpoint.
+
+In the example below, the `POST /users/sendEmail` endpoint is only available to public consumers:
+
+```yaml title="openapi.yml" {4-5}
+paths:
+ /users/sendEmail:
+ post:
+ x-fern-audiences:
+ - public
+ operationId: send_email
+```
+
+## Audiences for schemas
+
+Schemas can be marked for different audiences, as well.
+
+In this example, the `Email` type is available to both public and beta customers.
+
+```yaml title="openapi.yml" {13-15}
+components:
+ schemas:
+ Email:
+ title: Email
+ type: object
+ properties:
+ subject:
+ type: string
+ body:
+ type: string
+ to:
+ type: string
+ x-fern-audiences:
+ - public
+ - beta
+```
+
+## Audiences for properties
+
+Properties can be marked for different audiences, as well.
+
+In this example, the `to` property is available to beta customers only.
+
+```yaml title="openapi.yml" {13-17}
+components:
+ schemas:
+ Email:
+ title: Email
+ type: object
+ properties:
+ subject:
+ type: string
+ body:
+ type: string
+ to:
+ type: string
+ x-fern-audiences:
+ - beta
+```
diff --git a/fern/products/openapi-def/pages/extensions/method-names.mdx b/fern/products/openapi-def/pages/extensions/method-names.mdx
new file mode 100644
index 000000000..6a5c42306
--- /dev/null
+++ b/fern/products/openapi-def/pages/extensions/method-names.mdx
@@ -0,0 +1,58 @@
+---
+title: Customize SDK Method Names
+description: Use `x-fern-sdk-method-name` and `x-fern-sdk-group-name` to finetune SDK naming.
+---
+
+## Operation IDs
+
+By default, if you have no extensions present, Fern will try to use your operation ID to generate idiomatic
+method names for the SDK. We typically recommend formatting your operation IDs like `{tag_name}_{operation_name}`.
+
+For example, for an endpoint that has the tag `users` and the operation id `users_get`, we will generate an SDK
+method that is `users.get()`. If your operation id does not start with a tag, then we will simply use it as the method name.
+
+## Usage
+
+
+ The `x-fern-sdk-group-name` and `x-fern-sdk-method-name` extensions allow you to customize the generated SDK method
+ names.
+
+
+In the example below, Fern will generate a method called `client.users.create()` for the `POST /users` endpoint.
+
+```yaml title="openapi.yaml"
+paths:
+ /users:
+ post:
+ x-fern-sdk-group-name: users
+ x-fern-sdk-method-name: create
+```
+
+## Top level methods
+
+If you omit the `x-fern-sdk-group-name` extension, then the generated SDK method will live at the root.
+In the example below, Fern will generate a method called `client.send()`:
+
+```yaml title="openapi.yaml"
+paths:
+ /send:
+ post:
+ x-fern-sdk-method-name: send
+```
+
+## Multiple levels of nesting
+
+If you add more than one `x-fern-sdk-group-name` extension, then the generated SDK will nest group names.
+The order of the group names is preserved in the generated SDK method.
+
+In the example below, Fern will generate a method called `client.users.notifications.send()`:
+
+```yaml title="openapi.yaml"
+paths:
+ /users/notifications:
+ post:
+ x-fern-sdk-group-name:
+ - users
+ - notifications
+ x-fern-sdk-method-name: send
+```
diff --git a/fern/products/openapi-def/pages/extensions/others.mdx b/fern/products/openapi-def/pages/extensions/others.mdx
new file mode 100644
index 000000000..b3aa4b3e3
--- /dev/null
+++ b/fern/products/openapi-def/pages/extensions/others.mdx
@@ -0,0 +1,416 @@
+---
+title: Other extensions
+description: Learn about Fern's OpenAPI extensions for authentication overrides, global headers, enum descriptions and names, audiences, and more.
+---
+
+Fern supports different OpenAPI extensions so that you can generate higher-quality SDKs.
+
+## API version
+
+You can define your API version scheme, such as a `X-API-Version` header. The supported versions and default value are specified like so:
+
+```yaml title="openapi.yaml"
+x-fern-version:
+ version:
+ header: X-API-Version
+ default: "2.0.0"
+ values:
+ - "1.0.0"
+ - "2.0.0"
+ - "latest"
+paths: ...
+```
+
+## Global headers
+
+At times, your API will leverage certain headers for every endpoint, or the majority of them, we call these "global headers". For convenience, generated Fern SDKs expose "global headers" to easily be updated on API calls. Take for example an API key, if we declare the API key as a global header, a user will be able to plug theirs in easily:
+
+```python
+import os
+
+class Client:
+
+ def __init__(self, *, apiKey: str):
+```
+
+To configure global headers, Fern will automatically pull out headers that are used in every request, or the majority of requests, and mark them as global.
+In order to label additional headers as global, or to alias the names of global headers, you can leverage the `x-fern-global-headers` extension:
+
+```yaml title="openapi.yml"
+x-fern-global-headers:
+ - header: custom_api_key
+ name: api_key
+ - header: userpool_id
+ optional: true
+```
+
+yields the following client:
+
+```python
+import os
+
+class Client:
+
+ def __init__(self, *, apiKey: str, userpoolId: typing.Optional[str])
+```
+
+## Enum descriptions and names
+
+OpenAPI doesn't natively support adding descriptions to enum values. To do this in Fern you can use the `x-fern-enum`
+extension.
+
+In the example below, we've added some descriptions to enum values. These descriptions will
+propagate into the generated SDK and docs website.
+
+```yaml title="openapi.yml" {9-13}
+components:
+ schemas:
+ CardSuit:
+ enum:
+ - clubs
+ - diamonds
+ - hearts
+ - spades
+ x-fern-enum:
+ clubs:
+ description: Some docs about clubs
+ spades:
+ description: Some docs about spades
+```
+
+`x-fern-enum` also supports a `name` field that allows you to customize the name of the enum in code.
+This is particularly useful when you have enums that rely on symbolic characters that would otherwise cause
+generated code not to compile.
+
+For example, the following OpenAPI
+
+```yaml title="openapi.yml" {9,12}
+components:
+ schemas:
+ Operand:
+ enum:
+ - '>'
+ - '<'
+ x-fern-enum:
+ '>':
+ name: GreaterThan
+ description: Checks if value is greater than
+ '<':
+ name: LessThan
+ description: Checks if value is less than
+```
+
+would generate
+
+```typescript title="operand.ts"
+export enum Operand {
+ GreaterThan = ">",
+ LessThan = "<"
+}
+```
+
+## Schema names
+
+OpenAPI allows you to define inlined schemas that do not have names.
+
+```yaml title="Inline type in openapi.yml" {11}
+components:
+ schemas:
+ Movie:
+ type: object
+ properties:
+ name:
+ type: string
+ cast:
+ type: array
+ items:
+ type: object
+ properties:
+ firstName:
+ type: string
+ lastName:
+ type: string
+ age:
+ type: integer
+```
+
+Fern automatically generates names for all the inlined schemas. For example, in this example,
+Fern would generate the name `CastItem` for the inlined array item schema.
+
+```typescript title="Auto-generated name" {6}
+export interface Movie {
+ name?: string;
+ cast?: CastItem[];
+}
+
+export interface CastItem {
+ firstName?: string;
+ lastName?: string;
+ age?: integer;
+}
+```
+
+If you want to override the generated name, you can use the extension `x-fern-type-name`.
+
+```yaml title="openapi.yml" {12}
+components:
+ schemas:
+ Movie:
+ type: object
+ properties:
+ name:
+ type: string
+ cast:
+ type: array
+ items:
+ type: object
+ x-fern-type-name: Person
+ properties:
+ firstName:
+ type: string
+ lastName:
+ type: string
+ age:
+ type: integer
+```
+
+This would replace `CastItem` with `Person` and the generated code would read more idiomatically:
+
+```typescript title="Overridden name" {6}
+export interface Movie {
+ name?: string;
+ cast?: Person[];
+}
+
+export interface Person {
+ firstName?: string;
+ lastName?: string;
+ age?: integer;
+}
+```
+
+## Property names
+
+The `x-fern-property-name` extension allows you to customize the variable name for object
+properties.
+
+For example, if you had a property called `_metadata` in your schema but you wanted the
+variable to be called `data` in your SDK you would do the following:
+
+```yaml {6}
+components:
+ schemas:
+ MyUser:
+ _metadata:
+ type: object
+ x-fern-property-name: data
+```
+
+## Server names
+
+The `x-fern-server-name` extension is used to name your servers.
+
+```yaml title="openapi.yml"
+servers:
+ - url: https://api.example.com
+ x-fern-server-name: Production
+ - url: https://sandbox.example.com
+ x-fern-server-name: Sandbox
+```
+
+In a generated TypeScript SDK, you'd see:
+
+```typescript title="environment.ts"
+export const ExampleEnvironment = {
+ Production: "https://api.example.com"
+} as const;
+
+export type ExampleEnvironment = typeof ExampleEnvironment.Production;
+```
+
+## Base path
+
+The `x-fern-base-path` extension is used to configure the base path prepended to every endpoint.
+
+In the example below, we have configured the `/v1` base path so the full endpoint path is
+`https://api.example.com/v1/users`.
+
+```yaml title="Set the base path in openapi.yml" {1}
+x-fern-base-path: /v1
+servers:
+ - url: https://api.example.com
+paths:
+ /users: ...
+```
+
+## Ignoring schemas or endpoints
+
+If you want Fern to skip reading any endpoints or schemas, use the `x-fern-ignore` extension.
+
+To skip an endpoint, add `x-fern-ignore: true` at the operation level.
+
+```yaml title="x-fern-ignore at operation level in openapi.yml" {4}
+paths:
+ /users:
+ get:
+ x-fern-ignore: true
+ ...
+```
+
+To skip a schema, add `x-fern-ignore: true` at the schema level.
+
+```yaml title="x-fern-ignore at schema level in openapi.yml" {4}
+components:
+ schemas:
+ SchemaToSkip:
+ x-fern-ignore: true
+ ...
+```
+
+## Overlaying extensions
+
+Because of the number of tools that use OpenAPI, it may be more convenient to
+"overlay" your fern specific OpenAPI extensions onto your original definition. \
+In order to do this you can specify your overrides file in `generators.yml`.
+
+Below is an example of how someone can overlay the extensions `x-fern-sdk-method-name` and
+`x-fern-sdk-group-name` without polluting their original OpenAPI. The combined result is
+shown in the third tab.
+
+
+ ```yaml title="generators.yml" {3}
+ api:
+ path: ./openapi/openapi.yaml
+ overrides: ./openapi/overrides.yaml
+ default-group: sdk
+ groups:
+ sdk:
+ generators:
+ - name: fernapi/fern-python-sdk
+ version: 2.2.0
+ ```
+
+ ```yaml title="overrides.yml"
+ paths:
+ /users:
+ get:
+ x-fern-sdk-group-name: users
+ x-fern-sdk-method-name: get
+ ```
+
+ ```yaml title="Overlaid OpenAPI" {4-5}
+ paths:
+ /users:
+ get:
+ x-fern-sdk-group-name: users
+ x-fern-sdk-method-name: get
+ summary: Get a list of users
+ description: Retrieve a list of users from the system.
+ responses:
+ '200':
+ description: Successful response
+ '500':
+ description: Internal Server Error
+ ```
+
+
+
+## Embedding extensions
+
+If instead of overlaying your extensions within an overrides file, as mentioned above. Certain frameworks that generate OpenAPI Specifications make it easy to embed extensions directly from code.
+
+### FastAPI
+
+Please view our page on [FastAPI](/learn/api-definition/openapi/frameworks/fastapi) for more information on how to extend your OpenAPI Specification within FastAPI.
+
+## Request + response examples
+
+While OpenAPI has several fields for examples, there is no easy way
+to associate a request with a response. This is especially useful when
+you want to show more than one example in your documentation.
+
+`x-fern-examples` is an array of examples. Each element of the array
+can contain `path-parameters`, `query-parameters`, `request` and `response`
+examples values that are all associated.
+
+```yaml title="openapi.yml" {5-16}
+paths:
+ /users/{userId}:
+ get:
+ x-fern-examples:
+ - path-parameters:
+ userId: user-1234
+ response:
+ body:
+ name: Foo
+ ssn: 1234
+ - path-parameters:
+ userId: user-4567
+ response:
+ body:
+ name: Foo
+ ssn: 4567
+components:
+ schemas:
+ User:
+ type: object
+ properties:
+ name:
+ type: string
+ ssn:
+ type: integer
+```
+
+### Code samples
+
+If you'd like to specify custom code samples for your example, use `code-samples`.
+
+```yaml title="openapi.yml" {11-16}
+paths:
+ /users/{userId}:
+ get:
+ x-fern-examples:
+ - path-parameters:
+ userId: user-1234
+ response:
+ body:
+ name: Foo
+ ssn: 1234
+ code-samples:
+ - sdk: typescript
+ code: |
+ import { UserClient } from "...";
+
+ client.users.get("user-1234")
+```
+
+If you're on the Fern Basic plan or higher for SDKs you won't have to worry about manually adding code samples! Our generators do that for you.
+
+## Availability
+
+The `x-fern-availability` extension is used to mark the availability of an endpoint. The availability information propagates into the generated Fern Docs website as visual tags.
+
+The options are:
+
+- `beta`
+- `generally-available`
+- `deprecated`
+
+The example below marks that the `POST /pet` endpoint is `deprecated`.
+
+```yaml title="x-fern-availability in openapi.yml" {4}
+paths:
+ /pet:
+ post:
+ x-fern-availability: deprecated
+```
+
+This renders as:
+
+
+
+
+
+### Request new extensions
+
+If there's an extension you want that doesn't already exist, file an [issue](https://github.com/fern-api/fern/issues/new) to start a discussion about it.
diff --git a/fern/products/openapi-def/pages/extensions/parameter-names.mdx b/fern/products/openapi-def/pages/extensions/parameter-names.mdx
new file mode 100644
index 000000000..ff60bf613
--- /dev/null
+++ b/fern/products/openapi-def/pages/extensions/parameter-names.mdx
@@ -0,0 +1,65 @@
+---
+title: Customize parameter names
+description: Use `x-fern-parameter-name` to customize query parameter, header and path parameter naming.
+---
+
+
+ The `x-fern-parameter-name` extension allows you to customize the variable names of parameters in your generated SDKs.
+
+
+## Headers
+
+In the example below, the header `X-API-Version` is renamed to `version` in the
+generated SDK. The rename makes the SDK more human readable.
+
+```yaml {8}
+paths:
+ "/user":
+ get:
+ operationId: list_user
+ parameters:
+ - in: header
+ name: X-API-Version
+ x-fern-parameter-name: version
+ schema:
+ type: string
+ required: true
+```
+
+## Query parameters
+
+In the example below, the query parameter `q` is renamed to `search_terms` in the
+generated SDK. The rename makes the parameter more approachable for end users.
+
+```yaml {8}
+paths:
+ "/user/search":
+ get:
+ operationId: search_user
+ parameters:
+ - in: query
+ name: q
+ x-fern-parameter-name: search_terms
+ schema:
+ type: string
+ required: false
+```
+
+## Path parameters
+
+In the example below, the path parameter `userId` is renamed to `id` in the
+generated SDK. The rename makes the SDK less verbose.
+
+```yaml {8}
+paths:
+ "/user/{userId}":
+ get:
+ operationId: get_user
+ parameters:
+ - in: path
+ name: userId
+ x-fern-parameter-name: id
+ schema:
+ type: string
+ required: false
+```
diff --git a/fern/products/openapi-def/pages/overrides.mdx b/fern/products/openapi-def/pages/overrides.mdx
new file mode 100644
index 000000000..50d6462d7
--- /dev/null
+++ b/fern/products/openapi-def/pages/overrides.mdx
@@ -0,0 +1,74 @@
+---
+title: Overlay customizations on an existing OpenAPI spec
+subtitle: Can't directly modify your OpenAPI spec? No worries, use an overrides file instead.
+---
+
+If you generate your OpenAPI from server code, you may want to tweak your OpenAPI Spec without having to
+touch the generated file. Fern supports this via an `overrides` file.
+
+
+```yml openapi.yml
+paths:
+ /users:
+ post:
+ description: Create a User
+ operationId: users_post
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/User'
+```
+```yml title="overrides.yml" {4-5}
+paths:
+ /users:
+ post:
+ x-fern-sdk-group-name: users
+ x-fern-sdk-method-name: create
+```
+```yml title="combined" {4-5}
+paths:
+ /users/post:
+ post:
+ x-fern-sdk-group-name: users
+ x-fern-sdk-method-name: create
+ description: Create a User
+ operationId: users_post
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/User'
+```
+
+
+## Configuration
+
+Follow the steps below to configure your OpenAPI overrides:
+
+
+### Create an `overrides.yml`
+
+Simply create a yaml file and write down all the overrides you want to add:
+
+```yaml overrides.yml
+paths:
+ /v1/history:
+ get:
+ x-fern-sdk-group-name:
+ - history
+ x-fern-sdk-method-name: get_all
+```
+
+### Reference the file in your `generators.yml`
+
+```yml generators.yml
+api:
+ path: ../openapi.yml
+ overrides: ../overrides.yml
+```
+
+ The format of the overrides file is independent from the spec. For example, even if your OpenAPI spec is in JSON format, you can write the overrides in yaml.
+
+
+
diff --git a/fern/products/openapi-def/pages/overview.mdx b/fern/products/openapi-def/pages/overview.mdx
new file mode 100644
index 000000000..725c5d7fe
--- /dev/null
+++ b/fern/products/openapi-def/pages/overview.mdx
@@ -0,0 +1,128 @@
+---
+title: What is an OpenAPI Specification?
+subtitle: OpenAPI is a standard for documenting REST APIs
+---
+
+The OpenAPI Specification (OAS) is a framework used by developers to document REST APIs. The specification
+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).
+
+ Considering options to generate an OpenAPI spec? Get live support [here](https://fern-community.slack.com/join/shared_invite/zt-2dpftfmif-MuAegl8AfP_PK8s2tx350Q%EF%BB%BF#/shared-invite/email)
+
+Below is an example of an OpenAPI file:
+
+```yaml openapi.yml
+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
+```
+
+## Setup 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
+```
+fern/
+ ├─ fern.config.json
+ ├─ generators.yml
+ └─ openapi/
+ ├─ openapi.yml
+```
+
diff --git a/fern/products/openapi-def/pages/server-frameworks/fastapi.mdx b/fern/products/openapi-def/pages/server-frameworks/fastapi.mdx
new file mode 100644
index 000000000..df5bcbe3a
--- /dev/null
+++ b/fern/products/openapi-def/pages/server-frameworks/fastapi.mdx
@@ -0,0 +1,92 @@
+---
+title: FastAPI Instrumentation
+description: Learn about best practices for creating rich OpenAPI Specifications when instrumenting FastAPI applications.
+---
+
+[FastAPI](https://fastapi.tiangolo.com/) is a popular Python web framework developed by [tiangolo](https://github.com/tiangolo).
+
+The offering brands itself as
+
+> FastAPI is a modern, fast (high-performance), web framework for building APIs with Python based on standard Python type hints.
+
+FastAPI plays very nicely with Fern because it has the power to output OpenAPI Specifications! Below we'll outline some tips for generating a rich OpenAPI with FastAPI.
+
+
+## OpenAPI generation
+
+By default, FastAPI will generate an OpenAPI Specification for you based on your routes and your data models! You can access this spec by visiting `/docs` on your FastAPI server.
+
+If you are not seeing any OpenAPI Specification (or the Swagger UI), you may need to review your FastAPI server configuration as the path may have been changed, or completely omitted.
+
+```python {6-8}
+from fastapi import FastAPI
+
+...
+
+FastAPI(
+ openapi_url="/openapi.json", # <-- this is the file and URL needed to access the OpenAPI Specification, `docs_url` and `redoc_url` are convenient wrappers that display the file in a UI!
+ docs_url="/docs", # <-- this is the URL to access the Swagger UI, which will point to your OpenAPI Specification
+ redoc_url="/redoc" # <-- this is the URL to access the ReDoc UI, which will point to your OpenAPI Specification
+)
+```
+
+## Specifying servers
+
+Fern will automatically generate clients that point to the servers you configure within your OpenAPI Specification, so it's important to specify the servers that your API will be hosted on.
+
+```python {5}
+from fastapi import FastAPI
+
+...
+
+app = FastAPI(servers=[{"url": "http://prod.test.com", "description": "Production server"}])
+# This creates the following server object in your OpenAPI Specification:
+# "servers":[{"url":"http://prod.test.com","description":"Production server"}],
+```
+
+## OpenAPI extensions
+
+FastAPI allows you to add in extra OpenAPI configuration directly within your route, through the use of the `openapi_extra` parameter.
+Below, we've annotated a "good" route within FastAPI that has it's typings as well as Fern extensions to assist in naming.
+
+```python {5-9}
+@router.post(
+ "/your/post/endpoint",
+ response_model=YourResponseModel, # <-- with FastAPI, it is important to specify your response model so that it comes through to the OpenAPI Specification
+ summary="Get some response for your req", # <-- if you'd like to add a description to your endpoint, you can do so here
+ openapi_extra={ # <-- finally, you can add in your Fern extensions here, these extensions will produce SDK code that looks something like: `client.endpoints.create(...)` in python
+ "x-fern-sdk-method-name": "create",
+ "x-fern-sdk-group-name": "endpoints",
+ "x-fern-availability": "beta",
+ },
+)
+async def your_post_endpoint(
+ payload: YourRequestModel,
+) -> YourResponseModel:
+```
+
+## Specifying examples
+
+FastAPI allows you to specify examples for your data models, which Fern will pick up and use within your generated SDKs and documentation automatically.
+
+For more information on leveraging examples within Fern, please refer to the [Fern documentation](/learn/api-definition/openapi/extensions/others#request--response-examples).
+
+For more information on this FastAPI functionality, please refer to the [FastAPI documentation](https://fastapi.tiangolo.com/tutorial/schema-extra-example/).
+
+```python {7-11}
+from pydantic import BaseModel
+
+class MyObject(BaseModel):
+ id: str
+
+ class Config:
+ schema_extra = {
+ "example": {
+ "id": "a-cool-uuid",
+ }
+ }
+```
+
+## Additional customization
+
+FastAPI has a lot of flexibility in how you can customize your OpenAPI Specification. Please refer to the [FastAPI documentation](https://fastapi.tiangolo.com/how-to/extending-openapi/#modify-the-openapi-schema) for more information.
diff --git a/fern/products/openapi-def/pages/servers.mdx b/fern/products/openapi-def/pages/servers.mdx
new file mode 100644
index 000000000..28ce155a2
--- /dev/null
+++ b/fern/products/openapi-def/pages/servers.mdx
@@ -0,0 +1,84 @@
+---
+title: Servers
+description: Configure server URLs and environments to help users connect to your API.
+subtitle: Define server URLs and environments to help users connect to your API.
+---
+
+OpenAPI allows you to specify one or more base URLs under the `servers` key.
+
+```yml openapi.yml
+
+servers:
+ - url: https://api.yourcompany.com/
+ - url: https://api.eu.yourcompany.com/
+```
+
+Specifying servers is valuable for both SDKs and Docs:
+- For SDKs, your users won't need to manually specify the baseURL at client instantiation
+- For Docs, your API playground will automatically hit the correct server
+
+## Naming your servers
+
+If you have more than one server, we recommend specifying an `x-fern-server-name` to name
+the server.
+
+```yml openapi.yml {3,5}
+servers:
+ - x-fern-server-name: Production
+ url: https://api.yourcompany.com/
+ - x-fern-server-name: Production_EU
+ url: https://api.eu.yourcompany.com/
+```
+
+## Multiple Base URLs for a single API
+
+If you have a microservice architecture, it is possible that you may have different endpoints hosted
+at different URLs. For example, your AI endpoints might be hosted at `ai.yourcompany.com` and the rest
+of your endpoints might be hosted at `api.yourcompany.com`.
+
+To specify this, you will need to add configuration to both your `generators.yml` and OpenAPI spec. The
+snippet directly below shows how to configure an environment with multiple urls in your `generators.yml`.
+
+```yml generators.yml {3-8}
+api:
+ default-environment: Production
+ default-url: api
+ environments:
+ Production:
+ api: api.yourcompany.com
+ ai: ai.yourcompany.com
+ specs:
+ - openapi: ./path/to/your/openapi
+ overrides: ./path/to/your/overrides # optional
+```
+
+Once you've specified the environments in your `generators.yml`, you can use the `x-fern-server-name`
+extension to specify which server the operation belongs to.
+
+```yml openapi.yml {4}
+paths:
+ /chat:
+ post:
+ x-fern-server-name: ai
+```
+
+If you have multiple environments like development or staging, you can model those in your `generators.yml`
+as well.
+
+```yml generators.yml {7-12}
+api:
+ default-environment: Production
+ default-url: api
+ environments:
+ Production:
+ api: api.yourcompany.com
+ ai: ai.yourcompany.com
+ Staging:
+ api: api.staging.yourcompany.com
+ ai: ai.staging.yourcompany.com
+ Dev:
+ api: api.dev.yourcompany.com
+ ai: ai.dev.yourcompany.com
+```
+
+To see an example of this in production, check out the Chariot [generators.yml](https://github.com/chariot-giving/chariot-openapi/blob/main/fern/apis/2025-02-24/generators.yml)
\ No newline at end of file
diff --git a/fern/products/openapi-def/pages/webhooks.mdx b/fern/products/openapi-def/pages/webhooks.mdx
new file mode 100644
index 000000000..0bf5a2699
--- /dev/null
+++ b/fern/products/openapi-def/pages/webhooks.mdx
@@ -0,0 +1,33 @@
+---
+title: Define Webhooks in OpenAPI
+subtitle: Use the `x-fern-webhook` extension to define webhooks in your OpenAPI spec
+---
+
+To define a webhook in your OpenAPI specification, add the `x-fern-webhook: true` extension to your endpoint. OpenAPI 3.0.0 or higher is required. Fern will treat the `requestBody` as the webhook payload.
+
+```yaml openapi.yml {6}
+paths:
+ /payment/updated/:
+ post:
+ summary: Payment Initiated
+ operationId: initiatePayment
+ x-fern-webhook: true
+ requestBody:
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ amount:
+ type: number
+ currency:
+ $ref: '#/components/schemas/Currency'
+ required:
+ - amount
+ - currency
+```
+
+
+The path that you choose when defining a webhook can be arbitrary. Since webhooks
+can be sent to any server, Fern just ignores the path.
+
diff --git a/fern/products/sdks/introduction.mdx b/fern/products/sdks/introduction.mdx
index ce41a8890..67a41f68c 100644
--- a/fern/products/sdks/introduction.mdx
+++ b/fern/products/sdks/introduction.mdx
@@ -14,7 +14,7 @@ description: Generate idiomatic SDKs in multiple programming languages
{/* */}
-
+