Skip to content

Commit 75663c8

Browse files
authored
fix(docs): return 404 for unknown docs paths and derive integration counts from the catalog (#9003)
* fix(docs): return 404 for unknown docs paths and derive integration counts from the catalog - Pass the bundled OpenAPI specs to fumadocs in memory instead of by file path; serverless functions don't ship the spec files, so every non-prerendered docs route failed with a 500 - Set dynamicParams = false on the docs page and llms.mdx route so unknown paths are a static 404 - Generate catalog totals and derive every public integration claim from them in one unit (integrations, actions, triggers) instead of the hardcoded "1,000+" and stale comparison counts - Add a "Calling the Sim API" section to the docs llms.txt and clarify X-API-Key vs Bearer in the API docs - Redirect /triggers/api to the API deployment page * fix(seo): keep JSON-LD integration claims to the count the pages show
1 parent ad8c127 commit 75663c8

40 files changed

Lines changed: 203 additions & 80 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ macOS 12+, Apple Silicon and Intel. See the [desktop docs](https://docs.sim.ai/d
4242

4343
## Capabilities
4444

45-
- Connect 1,000+ integrations and every major LLM
45+
- Connect 270+ integrations (5,400+ actions, 520+ triggers) and every major LLM
4646
- Add Slack, Notion, HubSpot, Salesforce, databases, and more
4747
- Build agents visually, conversationally, or with code
4848
- Ingest files, knowledge bases, and structured table data

‎apps/docs/app/[[...slug]]/page.tsx‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,9 @@ export default async function Page(props: { params: Promise<{ slug?: string[] }>
300300
)
301301
}
302302

303+
/** Every docs page is prerendered, so an unknown path is a static 404 rather than a function call. */
304+
export const dynamicParams = false
305+
303306
export async function generateStaticParams() {
304307
return source.generateParams()
305308
}

‎apps/docs/app/layout.tsx‎

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { ReactNode } from 'react'
2+
import { INTEGRATION_REACH } from '@sim/deployment-config/integration-claims'
23
import { DocsLayout } from 'fumadocs-ui/layouts/docs'
34
import { SidebarProvider, SidebarTrigger, useSidebar } from 'fumadocs-ui/layouts/docs/slots/sidebar'
45
import { RootProvider } from 'fumadocs-ui/provider/next'
@@ -21,12 +22,13 @@ const inter = Inter({
2122
display: 'swap',
2223
})
2324

25+
const DOCS_DESCRIPTION = `Documentation for Sim — the open-source AI workspace where teams build, deploy, and manage AI agents. Connect ${INTEGRATION_REACH} and every major LLM.`
26+
2427
const structuredData = {
2528
'@context': 'https://schema.org',
2629
'@type': 'WebSite',
2730
name: 'Sim Documentation',
28-
description:
29-
'Documentation for Sim — the open-source AI workspace where teams build, deploy, and manage AI agents. Connect 1,000+ integrations and every major LLM.',
31+
description: DOCS_DESCRIPTION,
3032
url: DOCS_BASE_URL,
3133
publisher: {
3234
'@type': 'Organization',
@@ -118,8 +120,7 @@ export const metadata = {
118120
default: 'Sim Documentation — The AI Workspace for Teams',
119121
template: '%s | Sim Docs',
120122
},
121-
description:
122-
'Documentation for Sim — the open-source AI workspace where teams build, deploy, and manage AI agents. Connect 1,000+ integrations and every major LLM.',
123+
description: DOCS_DESCRIPTION,
123124
applicationName: 'Sim Docs',
124125
generator: 'Next.js',
125126
referrer: 'origin-when-cross-origin' as const,
@@ -165,8 +166,7 @@ export const metadata = {
165166
url: DOCS_BASE_URL,
166167
siteName: 'Sim Documentation',
167168
title: 'Sim Documentation — The AI Workspace for Teams',
168-
description:
169-
'Documentation for Sim — the open-source AI workspace where teams build, deploy, and manage AI agents. Connect 1,000+ integrations and every major LLM.',
169+
description: DOCS_DESCRIPTION,
170170
images: [
171171
{
172172
url: `${DOCS_BASE_URL}/api/og?title=Sim%20Documentation`,
@@ -179,8 +179,7 @@ export const metadata = {
179179
twitter: {
180180
card: 'summary_large_image',
181181
title: 'Sim Documentation — The AI Workspace for Teams',
182-
description:
183-
'Documentation for Sim — the open-source AI workspace where teams build, deploy, and manage AI agents. Connect 1,000+ integrations and every major LLM.',
182+
description: DOCS_DESCRIPTION,
184183
creator: '@simdotai',
185184
site: '@simdotai',
186185
images: [`${DOCS_BASE_URL}/api/og?title=Sim%20Documentation`],

‎apps/docs/app/llms.mdx/[[...slug]]/route.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { getLLMText } from '@/lib/llms'
44
import { source } from '@/lib/source'
55

66
export const revalidate = false
7+
export const dynamicParams = false
78

89
export async function GET(
910
_request: NextRequest,

‎apps/docs/app/llms.txt/route.ts‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import { INTEGRATION_REACH } from '@sim/deployment-config/integration-claims'
12
import { createLogger } from '@sim/logger'
23
import { source } from '@/lib/source'
3-
import { DOCS_BASE_URL } from '@/lib/urls'
4+
import { DOCS_BASE_URL, SIM_SITE_URL } from '@/lib/urls'
45

56
const logger = createLogger('DocsLlmsManifest')
67

@@ -32,7 +33,15 @@ export async function GET() {
3233
3334
> The open-source AI workspace where teams build, deploy, and manage AI agents.
3435
35-
Sim is the open-source AI workspace where teams build, deploy, and manage AI agents. Connect 1,000+ integrations and every major LLM to create agents that automate real work — visually, conversationally, or with code. Trusted by over 100,000 builders.
36+
Sim is the open-source AI workspace where teams build, deploy, and manage AI agents. Connect ${INTEGRATION_REACH} and every major LLM to create agents that automate real work — visually, conversationally, or with code. Trusted by over 100,000 builders.
37+
38+
## Calling the Sim API
39+
40+
- Base URL: \`${SIM_SITE_URL}\`. Every endpoint is under \`/api\`; there is no \`api.sim.ai\` host.
41+
- Run a deployed workflow: \`POST ${SIM_SITE_URL}/api/v2/workflows/{workflowId}/execute\` with a JSON body like \`{ "input": { "fieldName": "value" } }\`.
42+
- Authenticate API keys with the \`X-API-Key\` header. \`Authorization: Bearer\` accepts only Sim OAuth access tokens, never API keys.
43+
- Responses wrap the payload in \`data\`. A synchronous run returns \`200 { "data": { "runId", "status", "output", ... } }\`; with \`"async": true\` in the body it returns \`202 { "data": { "runId", "statusUrl" } }\` and you poll \`statusUrl\`.
44+
- SDKs: \`simstudio-ts-sdk\` (npm) and \`simstudio-sdk\` (PyPI). Full reference: [API getting started](${baseUrl}/api-reference/getting-started).
3645
3746
## Documentation Overview
3847

‎apps/docs/components/structured-data.tsx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { INTEGRATION_COUNT_LABEL } from '@sim/deployment-config/integration-claims'
12
import { serializeJsonLd } from '@/lib/json-ld'
23
import { DOCS_BASE_URL } from '@/lib/urls'
34

@@ -74,8 +75,7 @@ export function StructuredData({
7475
applicationCategory: 'BusinessApplication',
7576
applicationSubCategory: 'AI Workspace',
7677
operatingSystem: 'Any',
77-
description:
78-
'Sim is the open-source AI workspace where teams build, deploy, and manage AI agents. Connect 1,000+ integrations and every major LLM to create agents that automate real work.',
78+
description: `Sim is the open-source AI workspace where teams build, deploy, and manage AI agents. Connect ${INTEGRATION_COUNT_LABEL} integrations and every major LLM to create agents that automate real work.`,
7979
url: baseUrl,
8080
author: {
8181
'@type': 'Organization',
@@ -89,7 +89,7 @@ export function StructuredData({
8989
'AI workspace for teams',
9090
'Chat — natural language agent creation',
9191
'Visual workflow builder',
92-
'1,000+ integrations',
92+
`${INTEGRATION_COUNT_LABEL} integrations`,
9393
'LLM orchestration (OpenAI, Anthropic, Google, xAI, Mistral, Perplexity)',
9494
'Knowledge base creation',
9595
'Table creation',

‎apps/docs/content/docs/api-reference/authentication.mdx‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ administrators can create shared keys from **Workspace settings** → **Sim API
3838

3939
## Using API Keys
4040

41-
Pass your API key in the `X-API-Key` header with every request:
41+
Pass your API key in the `X-API-Key` header with every request. An API key is never accepted as `Authorization: Bearer`; that header is only for [OAuth access tokens](#oauth-access-tokens).
4242

4343
<Tabs items={['curl', 'TypeScript', 'Python']}>
4444
<Tab value="curl">
@@ -66,6 +66,8 @@ Pass your API key in the `X-API-Key` header with every request:
6666
</Tab>
6767
<Tab value="Python">
6868
```python
69+
import os
70+
6971
import requests
7072

7173
response = requests.post(

‎apps/docs/content/docs/api-reference/getting-started.mdx‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ All API requests are made to:
1515
https://www.sim.ai
1616
```
1717

18+
Every endpoint lives under `/api` on this origin, for example `https://www.sim.ai/api/v2/workflows/{workflowId}/execute`. There is no `api.sim.ai` host.
19+
1820
## OpenAPI specification
1921

2022
Download the [complete OpenAPI 3.1 specification](/openapi.json) as JSON for client generation, request validation, and API tooling.

‎apps/docs/lib/openapi.ts‎

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,35 @@
1-
import type { MethodInformation } from 'fumadocs-openapi'
1+
import { isRecordLike } from '@sim/utils/object'
2+
import type { Document, MethodInformation } from 'fumadocs-openapi'
23
import type { InlineCodeUsageGenerator } from 'fumadocs-openapi/requests/generators'
34
import { createOpenAPI } from 'fumadocs-openapi/server'
45
import { buildAuthCodeSamples } from '@/lib/openapi-code-samples'
56
import { OPENAPI_DOCUMENTS_BY_FILE } from '@/lib/openapi-documents'
67
import { OPENAPI_SPEC_FILES } from '@/lib/openapi-specs'
78

9+
function isOpenAPIDocument(value: unknown): value is Document {
10+
return isRecordLike(value) && typeof value.openapi === 'string' && isRecordLike(value.info)
11+
}
12+
13+
/**
14+
* Clones a bundled spec for the OpenAPI loader, which resolves references in place;
15+
* the imports are shared with the code-sample helpers below.
16+
*/
17+
function loadSpec(file: (typeof OPENAPI_SPEC_FILES)[number]): Document {
18+
const document: unknown = structuredClone(OPENAPI_DOCUMENTS_BY_FILE[file])
19+
if (!isOpenAPIDocument(document)) {
20+
throw new Error(`${file} is not an OpenAPI document`)
21+
}
22+
return document
23+
}
24+
25+
/**
26+
* Specs are passed as the statically imported documents, never as file paths: a path
27+
* is read from disk at request time, and the serverless bundle does not include the
28+
* spec files, so every non-prerendered route that loads the docs source would fail.
29+
* The `./<file>` keys keep the schema ids pages are generated against.
30+
*/
831
export const openapi = createOpenAPI({
9-
input: OPENAPI_SPEC_FILES.map((file) => `./${file}`),
32+
input: () => Object.fromEntries(OPENAPI_SPEC_FILES.map((file) => [`./${file}`, loadSpec(file)])),
1033
})
1134

1235
interface OpenAPIOperation {

‎apps/docs/lib/redirects.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ const PATH_REDIRECTS: DocsRedirect[] = [
138138
destination: '/workflows/triggers/:slug',
139139
permanent: true,
140140
},
141+
// the API trigger merged into the Start block; calling a workflow is documented under API deployment
142+
{ source: '/triggers/api', destination: '/workflows/deployment/api', permanent: true },
141143
{ source: '/deployment', destination: '/workflows/deployment', permanent: true },
142144
{
143145
source: '/deployment/:path*',

0 commit comments

Comments
 (0)