Skip to main content

Friendli Docs

Mintlify-powered documentation site for FriendliAI products (Model APIs, Dedicated Endpoints, Container).

Language

  • Conversations, explanations, and responses: Korean
  • All code, comments, inline docs, scripts, and documentation files (.md, .mdx, etc.): English
  • All GitHub PR titles and descriptions: English only

Quick Commands

pnpm install                # Install dependencies
pnpm dev                    # Local dev server (mint dev)
pnpm lint                   # Format + broken-links + openapi-check + eslint (also runs on pre-commit)
pnpm format                 # Prettier only

SSOT (Single Source of Truth) update

# Update source data then regenerate
for file in $(find scripts/ssot -name 'script.ts'); do
    pnpm dlx tsx "$file"
done
pnpm format

OpenAPI schema update

The openapi.yaml is pulled from Speakeasy registry. Do not edit it by hand — use the Speakeasy workflow:
speakeasy run

Project Structure

guides/             # Main documentation pages (MDX)
openapi/            # Generated API reference pages (from openapi.yaml)
snippets/
  components/       # Reusable MDX components (cards, callout boxes, tables)
  icons/            # Custom SVG icons
scripts/ssot/       # Scripts that auto-generate snippet tables from upstream data
static/             # Images, SVGs
sdk/                # SDK documentation
styles/             # Custom CSS (fonts, overrides)
docs.json           # Mintlify config: navigation, theme, redirects, metadata
openapi.yaml        # OpenAPI spec (managed by Speakeasy — do not hand-edit)

Writing Content

MDX page format

Every page is an .mdx file with YAML frontmatter. description and og:description must always be present and identical:
---
title: "Page Title"
sidebarTitle: "Sidebar Label"
description: "Short description for SEO."
"og:description": "Short description for SEO."
---

import SomeSnippet from "/snippets/components/card/some-card.mdx";

Content here. Use Mintlify built-in components (`<Card>`, `<CardGroup>`, `<Info>`, `<Tabs>`, etc.)
and project-specific snippets imported from `/snippets/`.

<SomeSnippet />
OpenAPI reference pages use an openapi frontmatter directive to bind to a spec operation:
---
title: "Chat completions"
openapi: post /serverless/v1/chat/completions
---

File naming conventions

  • guides/ — lowercase with hyphens (e.g., model-apis/, tool-calling.mdx)
  • openapi/ — lowercase with hyphens (e.g., chat-completions.mdx, image-generations.mdx)
  • snippets/kebab-case (e.g., model-apis-token-based-table.mdx)

Registering a new page

A page must be added to the navigation section in docs.json to appear in the sidebar. Pages are referenced without the .mdx extension. MDX files not listed in docs.json are still accessible via direct URL but hidden from navigation.

Moving or renaming a page

When changing a page’s URL path, add a redirect in the redirects section of docs.json so old links keep working:
{ "source": "/old/path", "destination": "/new/path" }
Wildcard redirects are supported for bulk moves: "/old/:slug*""/new/:slug*"

Hiding a page

Rename the file extension from .mdx to .txt to prevent access entirely.

Mintlify built-in components

Prefer Mintlify built-in components over raw HTML or plain markdown when structuring content.

Callouts

Use callouts to highlight important information. Choose the type based on intent:
<Note>Supplementary information or follow-up references.</Note>
<Warning>Limitations, permission requirements, or breaking changes.</Warning>
<Info>Prerequisites or contextual background.</Info>
<Tip>Recommended best practices or efficiency tips.</Tip>

CodeGroup

Wrap multiple code blocks to show language/SDK alternatives in tabs. The filename becomes the tab label:
<CodeGroup>
  ```python Python SDK
  client.chat.completions.create(model="...")
  ```

```javascript Node.js SDK
client.chat.completions.create({ model: "..." });
```

</CodeGroup>

Tabs

Use for non-code content that varies by OS, method, or mode:
<Tabs>
  <Tab title="macOS">Instructions for macOS.</Tab>
  <Tab title="Linux">Instructions for Linux.</Tab>
</Tabs>
Tabs with the same title across the page auto-sync when clicked.

Steps

Use for sequential procedures (tutorials, setup guides):
<Steps>
  <Step title="Install dependencies">Run `pnpm install`.</Step>
  <Step title="Start the server">Run `pnpm dev`.</Step>
</Steps>

Accordion

Use for FAQ pages or collapsible supplementary content:
<AccordionGroup>
  <Accordion title="How do I reset my API Key?">
    Go to Settings > API Keys and click "Regenerate".
  </Accordion>
  <Accordion title="What models are supported?">
    See the model list page for details.
  </Accordion>
</AccordionGroup>

Card and CardGroup

Use for navigation links to related pages:
<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/guides/quickstart">
    Get started in minutes.
  </Card>
  <Card title="API Reference" icon="code" href="/openapi/overview">
    Explore the API endpoints.
  </Card>
</CardGroup>

Expandable and ResponseField

Use in openapi/ pages for documenting nested API response structures:
<ResponseField name="choices" type="array" required>
  <Expandable title="child attributes">
    <ResponseField name="message" type="object">
      The assistant's response message.
    </ResponseField>
  </Expandable>
</ResponseField>

Tooltip

Use for inline definitions of technical terms:
<Tooltip tip="Graphics Processing Unit — specialized hardware for parallel computation.">
  GPU
</Tooltip>

Mermaid diagrams

Use for architecture diagrams, sequence flows, or decision trees instead of static images when possible:
```mermaid
flowchart LR
    A[Client] --> B[API Gateway] --> C[Model Server]
```
Supports flowcharts, sequence diagrams, state diagrams, and more. See Mermaid docs for syntax.

Code block enhancements

Mintlify code blocks support several useful features beyond basic syntax highlighting:
{/* Line highlighting */}

```python {1,3-5}
import friendli
client = friendli.Friendli()
response = client.chat.completions.create(
    model="meta-llama-3.1-8b-instruct",
    messages=[{"role": "user", "content": "Hello"}],
)
```

{/* Diff markers for showing changes */}

```python
client = friendli.Friendli(
    base_url="https://old-endpoint.friendli.ai",  // [!code --]
    base_url="https://new-endpoint.friendli.ai",  // [!code ++]
)
```

{/* Expandable for long code blocks */}

```python expandable
# Long code content that starts collapsed...
```

Images

Use RoundedBorderBox to wrap images. Import it and use inline style to control sizing:
import { RoundedBorderBox } from "/snippets/components/frame/rounded-border-box.mdx";

{/* Full width (default) */}

<RoundedBorderBox>
  <img alt="Container" src="/static/svgs/icons/container-fill.svg" />
</RoundedBorderBox>

{/* Constrained width */}

<RoundedBorderBox>
  <img
    alt="Dedicated Endpoints"
    style={{ maxWidth: "320px", width: "-webkit-fill-available" }}
    src="/static/svgs/icons/dedicated-fill.svg"
  />
</RoundedBorderBox>

{/* With caption */}

<RoundedBorderBox caption="Caption text">
  <img alt="Model APIs" src="/static/svgs/icons/model-apis-fill.svg" />
</RoundedBorderBox>
Store image files under static/images/ in a subdirectory matching the guide path (e.g., static/images/guides/model-apis/).

Snippets

Reusable MDX fragments live in snippets/components/. Import and use them as JSX components:
{/* Named export (component defined with export const) */}
import { RoundedBorderBox } from '/snippets/components/frame/rounded-border-box.mdx'

{/* Default export (component is the entire file content) */}
import EndpointPricingTable from '/snippets/components/pricing-table/endpoint-pricing-table.mdx'
Key snippet directories:
  • snippets/components/card/ — Card components for linking to pages (API reference, quickstart, etc.)
  • snippets/components/callout-box/ — Reusable info/warning callouts
  • snippets/components/frame/RoundedBorderBox for images
  • snippets/components/model-list/ — Model tables (auto-generated)
  • snippets/components/pricing-table/ — Pricing tables (auto-generated)
  • snippets/components/usage-table/ — Usage tier tables (auto-generated)

Adding a new API endpoint

When adding a new endpoint to the API Reference:
  1. Add the endpoint spec to openapi.yaml (via Speakeasy)
  2. Create a card snippet in snippets/components/card/api-reference/<product>/ for the new endpoint
  3. Import and add the card to the corresponding openapi/<product>/overview.mdx — this is how users discover the endpoint in the overview page
  4. Register the endpoint page in the navigation section of docs.json

Writing Guidelines

All documentation must be written in English about FriendliAI products.
  • Capitalize plan names: “Basic plan”, “Enterprise plan”, “Trial plan”
  • Use full plan names when referencing users: “Enterprise plan user” (not “enterprise user”)
  • Format plan-specific features consistently: “(Enterprise plan only)”
  • Maintain consistent terminology and branding throughout
Source of truth for writing guidelines: .cursor/rules/writing-guideline.mdc

Code Style

  • Prettier: 2-space tabs, double quotes, trailing commas. MDX files have embeddedLanguageFormatting: off. Config: .prettierrc
  • ESLint: MDX linting with eslint-plugin-mdx. Code blocks enforce no-var and prefer-const. Config: eslint.config.js
  • Pre-commit hook: pnpm lint runs automatically on every commit (via husky). Fix lint errors before committing.
  • No debug artifacts: Do not commit console.log, debugging statements, or sensitive environment variables (.env, API Keys, tokens). The .gitignore excludes .env* files, but always double-check before staging.

Auto-Generated Files — Do Not Hand-Edit

The following snippet files are generated by SSOT scripts (scripts/ssot/). Edit the corresponding source.ts instead, then run the SSOT update command above.
  • snippets/components/model-list/*.mdx — model availability and pricing tables
  • snippets/components/pricing-table/*.mdx — endpoint and fine-tuning pricing
  • snippets/components/usage-table/*.mdx — usage tier tables
Similarly, openapi.yaml is managed by Speakeasy and should not be edited by hand.

SSOT data pipeline

SSOT source data lives in the friendliai/web repository. The scripts in scripts/ssot/ fetch it via GitHub API, transform it, and write MDX snippets. A scheduled GitHub Action runs this automatically on weekdays (15:00 KST) and opens a PR titled Update SSOT (YYYY-MM-DD).

OpenAPI workflow

openapi.yaml is synced from Speakeasy registry (friendliai/friendliai/friendli-api-schema). To update, run speakeasy run or trigger the update-openapi-schema workflow manually. The generated spec should not be hand-edited — changes must go through the upstream API schema.

Changelog

Changelog entries in changelog.mdx use the <Update> component:
## April, 2026

<Update label="Apr 9" tags={["Model APIs"]}>

#### Model Release

- Added `some-org/some-model` to Model APIs.

</Update>
  • Group entries by month (## Month, Year)
  • label: short date (“Apr 9”)
  • tags: array of product names (e.g., ["Model APIs"], ["Dedicated Endpoints"])
  • Use #### for section headers within an entry (Model Release, Pricing Update, Deprecation, etc.)

Mintlify Reference

For Mintlify syntax and components, refer to the official documentation:
Last modified on June 6, 2026