Skip to content

Commit f0e521f

Browse files
feat(api): document public API authentication (#1038)
1 parent 2fa86ff commit f0e521f

File tree

4 files changed

+76
-10
lines changed

4 files changed

+76
-10
lines changed

docs/api-reference/sourcebot-public.openapi.json

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,18 @@
33
"info": {
44
"title": "Sourcebot Public API",
55
"version": "v4.16.3",
6-
"description": "OpenAPI description for the public Sourcebot REST endpoints used for search, repository listing, and file browsing."
6+
"description": "OpenAPI description for the public Sourcebot REST endpoints used for search, repository listing, and file browsing. Authentication is instance-dependent: API keys are the standard integration mechanism, OAuth bearer tokens are EE-only, and some instances may allow anonymous access."
7+
78
},
9+
"security": [
10+
{
11+
"bearerAuth": []
12+
},
13+
{
14+
"sourcebotApiKey": []
15+
},
16+
{}
17+
],
818
"tags": [
919
{
1020
"name": "Search",
@@ -512,8 +522,7 @@
512522
"properties": {
513523
"version": {
514524
"type": "string",
515-
"description": "Running Sourcebot version.",
516-
"example": "v4.15.2"
525+
"description": "Running Sourcebot version."
517526
}
518527
},
519528
"required": [
@@ -657,11 +666,25 @@
657666
"additionalProperties": false
658667
}
659668
},
660-
"parameters": {}
669+
"parameters": {},
670+
"securitySchemes": {
671+
"bearerAuth": {
672+
"type": "http",
673+
"scheme": "bearer",
674+
"description": "Send either a Sourcebot API key (`sbk_...` or legacy `sourcebot-...`) or, on EE instances with OAuth enabled, an OAuth access token (`sboa_...`) in the Authorization header."
675+
},
676+
"sourcebotApiKey": {
677+
"type": "apiKey",
678+
"in": "header",
679+
"name": "X-Sourcebot-Api-Key",
680+
"description": "Send a Sourcebot API key (`sbk_...` or legacy `sourcebot-...`) in the X-Sourcebot-Api-Key header."
681+
}
682+
}
661683
},
662684
"paths": {
663685
"/api/search": {
664686
"post": {
687+
"operationId": "search",
665688
"tags": [
666689
"Search"
667690
],
@@ -712,6 +735,7 @@
712735
},
713736
"/api/stream_search": {
714737
"post": {
738+
"operationId": "streamSearch",
715739
"tags": [
716740
"Search"
717741
],
@@ -763,6 +787,7 @@
763787
},
764788
"/api/repos": {
765789
"get": {
790+
"operationId": "listRepositories",
766791
"tags": [
767792
"Repositories"
768793
],
@@ -878,6 +903,7 @@
878903
},
879904
"/api/version": {
880905
"get": {
906+
"operationId": "getVersion",
881907
"tags": [
882908
"Misc"
883909
],
@@ -898,6 +924,7 @@
898924
},
899925
"/api/source": {
900926
"get": {
927+
"operationId": "getFileSource",
901928
"tags": [
902929
"Files"
903930
],
@@ -974,6 +1001,7 @@
9741001
},
9751002
"/api/tree": {
9761003
"post": {
1004+
"operationId": "getFileTree",
9771005
"tags": [
9781006
"Files"
9791007
],
@@ -1043,6 +1071,7 @@
10431071
},
10441072
"/api/files": {
10451073
"post": {
1074+
"operationId": "listFiles",
10461075
"tags": [
10471076
"Files"
10481077
],

docs/docs/api-reference/overview.mdx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ You can fetch the OpenAPI document for your Sourcebot instance from `/api/openap
77

88
This API reference is generated from the web app's Zod schemas and OpenAPI registry. Mintlify renders it from the checked-in spec at [`/api-reference/sourcebot-public.openapi.json`](/api-reference/sourcebot-public.openapi.json).
99

10+
For authenticated access, create an API key in Sourcebot from **Settings -> API Keys** and send it with either:
11+
12+
- `X-Sourcebot-Api-Key: sbk_...`
13+
- `Authorization: Bearer sbk_...`
14+
15+
Some instances may also allow anonymous access for these endpoints. On EE instances with OAuth enabled, bearer tokens with the `sboa_...` prefix are also accepted.
16+
1017
The first documented endpoints include:
1118

1219
- `/api/search`

packages/web/src/openapi/publicApiDocument.ts

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { OpenAPIRegistry, OpenApiGeneratorV3 } from '@asteasolutions/zod-to-openapi';
22
import type { ZodTypeAny } from 'zod';
3-
import type { SchemaObject } from 'openapi3-ts/oas30';
3+
import type { ComponentsObject, SchemaObject, SecuritySchemeObject } from 'openapi3-ts/oas30';
44
import {
55
publicFileSourceRequestSchema,
66
publicFileSourceResponseSchema,
@@ -45,6 +45,20 @@ const publicGetTreeResponseSchema: SchemaObject = {
4545
additionalProperties: false,
4646
};
4747

48+
const securitySchemes: Record<string, SecuritySchemeObject> = {
49+
bearerAuth: {
50+
type: 'http',
51+
scheme: 'bearer',
52+
description: 'Send either a Sourcebot API key (`sbk_...` or legacy `sourcebot-...`) or, on EE instances with OAuth enabled, an OAuth access token (`sboa_...`) in the Authorization header.',
53+
},
54+
sourcebotApiKey: {
55+
type: 'apiKey',
56+
in: 'header',
57+
name: 'X-Sourcebot-Api-Key',
58+
description: 'Send a Sourcebot API key (`sbk_...` or legacy `sourcebot-...`) in the X-Sourcebot-Api-Key header.',
59+
},
60+
};
61+
4862
function jsonContent(schema: ZodTypeAny | SchemaObject) {
4963
return {
5064
'application/json': {
@@ -66,6 +80,7 @@ export function createPublicOpenApiDocument(version: string) {
6680
registry.registerPath({
6781
method: 'post',
6882
path: '/api/search',
83+
operationId: 'search',
6984
tags: [searchTag.name],
7085
summary: 'Run a blocking code search',
7186
request: {
@@ -87,6 +102,7 @@ export function createPublicOpenApiDocument(version: string) {
87102
registry.registerPath({
88103
method: 'post',
89104
path: '/api/stream_search',
105+
operationId: 'streamSearch',
90106
tags: [searchTag.name],
91107
summary: 'Run a streaming code search',
92108
description: 'Returns a server-sent event stream. Each event data payload is a JSON object describing either a chunk, final summary, or error.',
@@ -113,6 +129,7 @@ export function createPublicOpenApiDocument(version: string) {
113129
registry.registerPath({
114130
method: 'get',
115131
path: '/api/repos',
132+
operationId: 'listRepositories',
116133
tags: [reposTag.name],
117134
summary: 'List repositories',
118135
request: {
@@ -147,6 +164,7 @@ export function createPublicOpenApiDocument(version: string) {
147164
registry.registerPath({
148165
method: 'get',
149166
path: '/api/version',
167+
operationId: 'getVersion',
150168
tags: [miscTag.name],
151169
summary: 'Get Sourcebot version',
152170
responses: {
@@ -160,6 +178,7 @@ export function createPublicOpenApiDocument(version: string) {
160178
registry.registerPath({
161179
method: 'get',
162180
path: '/api/source',
181+
operationId: 'getFileSource',
163182
tags: [filesTag.name],
164183
summary: 'Get file contents',
165184
request: {
@@ -179,6 +198,7 @@ export function createPublicOpenApiDocument(version: string) {
179198
registry.registerPath({
180199
method: 'post',
181200
path: '/api/tree',
201+
operationId: 'getFileTree',
182202
tags: [filesTag.name],
183203
summary: 'Get a file tree',
184204
request: {
@@ -201,6 +221,7 @@ export function createPublicOpenApiDocument(version: string) {
201221
registry.registerPath({
202222
method: 'post',
203223
path: '/api/files',
224+
operationId: 'listFiles',
204225
tags: [filesTag.name],
205226
summary: 'List files in a repository revision',
206227
request: {
@@ -227,16 +248,26 @@ export function createPublicOpenApiDocument(version: string) {
227248
info: {
228249
title: 'Sourcebot Public API',
229250
version,
230-
description: 'OpenAPI description for the public Sourcebot REST endpoints used for search, repository listing, and file browsing.',
251+
description: 'OpenAPI description for the public Sourcebot REST endpoints used for search, repository listing, and file browsing. Authentication is instance-dependent: API keys are the standard integration mechanism, OAuth bearer tokens are EE-only, and some instances may allow anonymous access.',
231252
},
253+
security: [
254+
{ bearerAuth: [] },
255+
{ sourcebotApiKey: [] },
256+
{},
257+
],
232258
tags: [searchTag, reposTag, filesTag, miscTag],
233259
});
234260

235-
document.components = document.components ?? {};
236-
document.components.schemas = {
237-
...(document.components.schemas ?? {}),
261+
const components: ComponentsObject = document.components ?? {};
262+
components.schemas = {
263+
...(components.schemas ?? {}),
238264
PublicFileTreeNode: publicFileTreeNodeSchema,
239265
};
266+
components.securitySchemes = {
267+
...(components.securitySchemes ?? {}),
268+
...securitySchemes,
269+
};
270+
document.components = components;
240271

241272
return document;
242273
}

packages/web/src/openapi/publicApiSchemas.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ export const publicFileSourceResponseSchema = fileSourceResponseSchema.openapi('
4141
export const publicVersionResponseSchema = z.object({
4242
version: z.string().openapi({
4343
description: 'Running Sourcebot version.',
44-
example: 'v4.15.2',
4544
}),
4645
}).openapi('PublicVersionResponse');
4746

0 commit comments

Comments
 (0)