@supermodeltools/openapi-spec 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +2 -0
  2. package/openapi.yaml +1913 -0
  3. package/package.json +15 -0
package/openapi.yaml ADDED
@@ -0,0 +1,1913 @@
1
+ openapi: 3.0.0
2
+ info:
3
+ title: Supermodel
4
+ description: Code Graphing & Analysis API
5
+ version: 0.3.5
6
+ license:
7
+ name: Supermodel API Terms of Service
8
+ url: https://supermodeltools.com/legal/api-terms
9
+ servers:
10
+ - url: https://api.supermodeltools.com
11
+ description: Production server
12
+ tags:
13
+ - name: Data Plane
14
+ description: Calls the data plane to retrieve Supermodel analysis artifacts derived from repositories.
15
+ paths:
16
+ /v1/graphs/dependency:
17
+ post:
18
+ tags:
19
+ - Data Plane
20
+ summary: Dependency graph
21
+ description: Upload a zipped repository snapshot to generate the dependency graph.
22
+ operationId: generateDependencyGraph
23
+ security:
24
+ - ApiKeyAuth: []
25
+ parameters:
26
+ - $ref: '#/components/parameters/IdempotencyKey'
27
+ requestBody:
28
+ required: true
29
+ content:
30
+ multipart/form-data:
31
+ schema:
32
+ type: object
33
+ required:
34
+ - file
35
+ properties:
36
+ file:
37
+ type: string
38
+ format: binary
39
+ description: Zipped repository archive containing the code to analyze.
40
+ x-codeSamples:
41
+ - lang: cURL
42
+ label: cURL
43
+ source: |
44
+ curl -X POST 'https://api.supermodeltools.com/v1/graphs/dependency' \
45
+ -H 'Idempotency-Key: <idempotency-key>' \
46
+ -H 'X-Api-Key: <api-key>' \
47
+ -F 'file=@/path/to/your/repo-snapshot.zip;type=application/zip'
48
+ - lang: javascript
49
+ label: JavaScript (fetch)
50
+ source: |
51
+ import { readFile } from 'node:fs/promises';
52
+ const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
53
+ const apiKey = '<api-key>';
54
+ const idempotencyKey = '<idempotency-key>';
55
+ const archivePath = '/path/to/your/repo-snapshot.zip';
56
+
57
+ const buffer = await readFile(archivePath);
58
+ const form = new FormData();
59
+ form.append('file', new Blob([buffer], { type: 'application/zip' }), 'repo-snapshot.zip');
60
+
61
+ const res = await fetch(`${baseUrl}/v1/graphs/dependency`, {
62
+ method: 'POST',
63
+ headers: {
64
+ 'Idempotency-Key': idempotencyKey,
65
+ 'X-Api-Key': apiKey
66
+ },
67
+ body: form
68
+ });
69
+
70
+ if (!res.ok) throw new Error(await res.text());
71
+ console.log(await res.json());
72
+ - lang: typescript
73
+ label: TypeScript (SDK)
74
+ source: |
75
+ import { Configuration, DefaultApi } from '@supermodel/public-api-typescript';
76
+ import { readFile } from 'node:fs/promises';
77
+
78
+ const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
79
+ const apiKey = '<api-key>';
80
+ const idempotencyKey = '<idempotency-key>';
81
+ const archivePath = '/path/to/your/repo-snapshot.zip';
82
+
83
+ const buffer = await readFile(archivePath);
84
+ const archiveBlob = new Blob([buffer], { type: 'application/zip' });
85
+
86
+ const configuration = new Configuration({ basePath: baseUrl });
87
+
88
+ const apiKeyOverride = async ({ init }) => ({
89
+ headers: { ...(init.headers ?? {}), 'X-Api-Key': apiKey }
90
+ });
91
+
92
+ const api = new DefaultApi(configuration);
93
+ const result = await api.generateDependencyGraph(
94
+ { idempotencyKey, file: archiveBlob },
95
+ apiKeyOverride
96
+ );
97
+
98
+ console.log(result);
99
+ - lang: java
100
+ label: Java (generated client)
101
+ source: |
102
+ import org.openapitools.client.ApiClient;
103
+ import org.openapitools.client.api.DefaultApi;
104
+
105
+ import java.io.File;
106
+
107
+ public class Example {
108
+ public static void main(String[] args) throws Exception {
109
+ String baseUrl = System.getenv().getOrDefault("API_BASE_URL", "https://api.supermodeltools.com");
110
+ String apiKey = "<api-key>";
111
+ String idempotencyKey = "<idempotency-key>";
112
+ File archive = new File("/path/to/your/repo-snapshot.zip");
113
+
114
+ ApiClient client = new ApiClient();
115
+ client.updateBaseUri(baseUrl);
116
+ client.setRequestInterceptor(rb -> {
117
+ rb.header("X-Api-Key", apiKey);
118
+ });
119
+
120
+ DefaultApi api = new DefaultApi(client);
121
+ api.generateDependencyGraph(idempotencyKey, archive);
122
+ }
123
+ }
124
+ - lang: python
125
+ label: Python (generated client)
126
+ source: |
127
+ import os
128
+ from supermodel_public_api import ApiClient, Configuration
129
+ from supermodel_public_api.api.default_api import DefaultApi
130
+
131
+ base_url = os.environ.get("API_BASE_URL", "https://api.supermodeltools.com")
132
+ api_key = "<api-key>"
133
+ idempotency_key = "<idempotency-key>"
134
+
135
+ configuration = Configuration(host=base_url)
136
+ configuration.api_key["ApiKeyAuth"] = api_key
137
+
138
+ api_client = ApiClient(configuration)
139
+ api = DefaultApi(api_client)
140
+
141
+ with open("/path/to/your/repo-snapshot.zip", "rb") as f:
142
+ payload = f.read()
143
+
144
+ result = api.generate_dependency_graph(idempotency_key, file=payload)
145
+ print(result)
146
+ - lang: rust
147
+ label: Rust (reqwest)
148
+ source: |
149
+ use bytes::Bytes;
150
+ use reqwest::multipart::{Form, Part};
151
+
152
+ #[tokio::main]
153
+ async fn main() -> anyhow::Result<()> {
154
+ let base_url = std::env::var("API_BASE_URL")
155
+ .unwrap_or_else(|_| "https://api.supermodeltools.com".to_string());
156
+ let api_key = "<api-key>";
157
+ let idempotency_key = "<idempotency-key>";
158
+
159
+ let archive_bytes = Bytes::from(tokio::fs::read("/path/to/your/repo-snapshot.zip").await?);
160
+ let url = format!("{}/v1/graphs/dependency", base_url.trim_end_matches('/'));
161
+
162
+ let file_part = Part::bytes(archive_bytes.to_vec())
163
+ .file_name("repo.zip")
164
+ .mime_str("application/zip")?;
165
+ let form = Form::new().part("file", file_part);
166
+
167
+ let response = reqwest::Client::new()
168
+ .post(url)
169
+ .header("Idempotency-Key", idempotency_key)
170
+ .header("X-Api-Key", api_key)
171
+ .multipart(form)
172
+ .send()
173
+ .await?;
174
+ let status = response.status();
175
+ let body = response.bytes().await?;
176
+
177
+ if status.is_success() {
178
+ println!("{}", String::from_utf8_lossy(&body));
179
+ } else {
180
+ anyhow::bail!(
181
+ "Request failed ({}): {}",
182
+ status.as_u16(),
183
+ String::from_utf8_lossy(&body)
184
+ );
185
+ }
186
+
187
+ Ok(())
188
+ }
189
+ responses:
190
+ '200':
191
+ description: Dependency graph
192
+ headers:
193
+ X-Request-Id:
194
+ $ref: '#/components/headers/X-Request-Id'
195
+ X-API-Version:
196
+ $ref: '#/components/headers/X-API-Version'
197
+ RateLimit-Limit:
198
+ $ref: '#/components/headers/RateLimit-Limit'
199
+ RateLimit-Remaining:
200
+ $ref: '#/components/headers/RateLimit-Remaining'
201
+ RateLimit-Reset:
202
+ $ref: '#/components/headers/RateLimit-Reset'
203
+ X-Usage-Units:
204
+ $ref: '#/components/headers/X-Usage-Units'
205
+ content:
206
+ application/json:
207
+ schema:
208
+ $ref: '#/components/schemas/CodeGraphEnvelope'
209
+ example:
210
+ generatedAt: '2025-02-05 15:42:10.000000000 Z'
211
+ message: Graph generated successfully
212
+ stats:
213
+ filesProcessed: 2
214
+ classes: 0
215
+ functions: 0
216
+ types: 0
217
+ processingTimeMs: 15
218
+ graph:
219
+ nodes:
220
+ - id: src/main.js
221
+ labels:
222
+ - File
223
+ properties:
224
+ path: src/main.js
225
+ name: main.js
226
+ - id: src/math.js
227
+ labels:
228
+ - File
229
+ properties:
230
+ path: src/math.js
231
+ name: math.js
232
+ relationships:
233
+ - id: src/main.js_imports_src/math.js
234
+ type: imports
235
+ startNode: src/main.js
236
+ endNode: src/math.js
237
+ properties: {}
238
+ '400':
239
+ $ref: '#/components/responses/BadRequest'
240
+ '401':
241
+ $ref: '#/components/responses/Unauthorized'
242
+ '403':
243
+ $ref: '#/components/responses/Forbidden'
244
+ '404':
245
+ $ref: '#/components/responses/NotFound'
246
+ '429':
247
+ $ref: '#/components/responses/TooManyRequests'
248
+ '500':
249
+ $ref: '#/components/responses/InternalError'
250
+ '502':
251
+ description: Bad Gateway
252
+ content:
253
+ application/json:
254
+ schema:
255
+ $ref: '#/components/schemas/Error'
256
+ /v1/graphs/call:
257
+ post:
258
+ tags:
259
+ - Data Plane
260
+ summary: Call graph
261
+ description: Upload a zipped repository snapshot to generate the function-level call graph.
262
+ operationId: generateCallGraph
263
+ security:
264
+ - ApiKeyAuth: []
265
+ parameters:
266
+ - $ref: '#/components/parameters/IdempotencyKey'
267
+ requestBody:
268
+ required: true
269
+ content:
270
+ multipart/form-data:
271
+ schema:
272
+ type: object
273
+ required:
274
+ - file
275
+ properties:
276
+ file:
277
+ type: string
278
+ format: binary
279
+ description: Zipped repository archive containing the code to analyze.
280
+ x-codeSamples:
281
+ - lang: cURL
282
+ label: cURL
283
+ source: |
284
+ curl -X POST 'https://api.supermodeltools.com/v1/graphs/call' \
285
+ -H 'Idempotency-Key: <idempotency-key>' \
286
+ -H 'X-Api-Key: <api-key>' \
287
+ -F 'file=@/path/to/your/repo-snapshot.zip;type=application/zip'
288
+ - lang: javascript
289
+ label: JavaScript (fetch)
290
+ source: |
291
+ import { readFile } from 'node:fs/promises';
292
+ const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
293
+ const apiKey = '<api-key>';
294
+ const idempotencyKey = '<idempotency-key>';
295
+ const archivePath = '/path/to/your/repo-snapshot.zip';
296
+
297
+ const buffer = await readFile(archivePath);
298
+ const form = new FormData();
299
+ form.append('file', new Blob([buffer], { type: 'application/zip' }), 'repo-snapshot.zip');
300
+
301
+ const res = await fetch(`${baseUrl}/v1/graphs/call`, {
302
+ method: 'POST',
303
+ headers: {
304
+ 'Idempotency-Key': idempotencyKey,
305
+ 'X-Api-Key': apiKey
306
+ },
307
+ body: form
308
+ });
309
+
310
+ if (!res.ok) throw new Error(await res.text());
311
+ console.log(await res.json());
312
+ - lang: typescript
313
+ label: TypeScript (SDK)
314
+ source: |
315
+ import { Configuration, DefaultApi } from '@supermodel/public-api-typescript';
316
+ import { readFile } from 'node:fs/promises';
317
+
318
+ const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
319
+ const apiKey = '<api-key>';
320
+ const idempotencyKey = '<idempotency-key>';
321
+ const archivePath = '/path/to/your/repo-snapshot.zip';
322
+
323
+ const buffer = await readFile(archivePath);
324
+ const archiveBlob = new Blob([buffer], { type: 'application/zip' });
325
+
326
+ const configuration = new Configuration({ basePath: baseUrl });
327
+
328
+ const apiKeyOverride = async ({ init }) => ({
329
+ headers: { ...(init.headers ?? {}), 'X-Api-Key': apiKey }
330
+ });
331
+
332
+ const api = new DefaultApi(configuration);
333
+ const result = await api.generateCallGraph(
334
+ { idempotencyKey, file: archiveBlob },
335
+ apiKeyOverride
336
+ );
337
+
338
+ console.log(result);
339
+ - lang: java
340
+ label: Java (generated client)
341
+ source: |
342
+ import org.openapitools.client.ApiClient;
343
+ import org.openapitools.client.api.DefaultApi;
344
+
345
+ import java.io.File;
346
+
347
+ public class Example {
348
+ public static void main(String[] args) throws Exception {
349
+ String baseUrl = System.getenv().getOrDefault("API_BASE_URL", "https://api.supermodeltools.com");
350
+ String apiKey = "<api-key>";
351
+ String idempotencyKey = "<idempotency-key>";
352
+ File archive = new File("/path/to/your/repo-snapshot.zip");
353
+
354
+ ApiClient client = new ApiClient();
355
+ client.updateBaseUri(baseUrl);
356
+ client.setRequestInterceptor(rb -> {
357
+ rb.header("X-Api-Key", apiKey);
358
+ });
359
+
360
+ DefaultApi api = new DefaultApi(client);
361
+ api.generateCallGraph(idempotencyKey, archive);
362
+ }
363
+ }
364
+ - lang: python
365
+ label: Python (generated client)
366
+ source: |
367
+ import os
368
+ from supermodel_public_api import ApiClient, Configuration
369
+ from supermodel_public_api.api.default_api import DefaultApi
370
+
371
+ base_url = os.environ.get("API_BASE_URL", "https://api.supermodeltools.com")
372
+ api_key = "<api-key>"
373
+ idempotency_key = "<idempotency-key>"
374
+
375
+ configuration = Configuration(host=base_url)
376
+ configuration.api_key["ApiKeyAuth"] = api_key
377
+
378
+ api_client = ApiClient(configuration)
379
+ api = DefaultApi(api_client)
380
+
381
+ with open("/path/to/your/repo-snapshot.zip", "rb") as f:
382
+ payload = f.read()
383
+
384
+ result = api.generate_call_graph(idempotency_key, file=payload)
385
+ print(result)
386
+ - lang: rust
387
+ label: Rust (reqwest)
388
+ source: |
389
+ use bytes::Bytes;
390
+ use reqwest::multipart::{Form, Part};
391
+
392
+ #[tokio::main]
393
+ async fn main() -> anyhow::Result<()> {
394
+ let base_url = std::env::var("API_BASE_URL")
395
+ .unwrap_or_else(|_| "https://api.supermodeltools.com".to_string());
396
+ let api_key = "<api-key>";
397
+ let idempotency_key = "<idempotency-key>";
398
+
399
+ let archive_bytes = Bytes::from(tokio::fs::read("/path/to/your/repo-snapshot.zip").await?);
400
+ let url = format!("{}/v1/graphs/call", base_url.trim_end_matches('/'));
401
+
402
+ let file_part = Part::bytes(archive_bytes.to_vec())
403
+ .file_name("repo.zip")
404
+ .mime_str("application/zip")?;
405
+ let form = Form::new().part("file", file_part);
406
+
407
+ let response = reqwest::Client::new()
408
+ .post(url)
409
+ .header("Idempotency-Key", idempotency_key)
410
+ .header("X-Api-Key", api_key)
411
+ .multipart(form)
412
+ .send()
413
+ .await?;
414
+ let status = response.status();
415
+ let body = response.bytes().await?;
416
+
417
+ if status.is_success() {
418
+ println!("{}", String::from_utf8_lossy(&body));
419
+ } else {
420
+ anyhow::bail!(
421
+ "Request failed ({}): {}",
422
+ status.as_u16(),
423
+ String::from_utf8_lossy(&body)
424
+ );
425
+ }
426
+
427
+ Ok(())
428
+ }
429
+ responses:
430
+ '200':
431
+ description: Call graph
432
+ headers:
433
+ X-Request-Id:
434
+ $ref: '#/components/headers/X-Request-Id'
435
+ X-API-Version:
436
+ $ref: '#/components/headers/X-API-Version'
437
+ RateLimit-Limit:
438
+ $ref: '#/components/headers/RateLimit-Limit'
439
+ RateLimit-Remaining:
440
+ $ref: '#/components/headers/RateLimit-Remaining'
441
+ RateLimit-Reset:
442
+ $ref: '#/components/headers/RateLimit-Reset'
443
+ X-Usage-Units:
444
+ $ref: '#/components/headers/X-Usage-Units'
445
+ content:
446
+ application/json:
447
+ schema:
448
+ $ref: '#/components/schemas/CodeGraphEnvelope'
449
+ example:
450
+ generatedAt: '2025-02-05 15:42:10.000000000 Z'
451
+ message: Call graph generated successfully
452
+ stats:
453
+ filesProcessed: 2
454
+ classes: 0
455
+ functions: 2
456
+ types: 0
457
+ processingTimeMs: 8
458
+ graph:
459
+ nodes:
460
+ - id: fn:index.ts:init
461
+ labels:
462
+ - Function
463
+ properties:
464
+ file: src/index.ts
465
+ - id: fn:service.ts:handle
466
+ labels:
467
+ - Function
468
+ properties:
469
+ file: src/service.ts
470
+ relationships:
471
+ - id: fn:index.ts:init_calls_fn:service.ts:handle
472
+ type: calls
473
+ startNode: fn:index.ts:init
474
+ endNode: fn:service.ts:handle
475
+ properties:
476
+ count: 4
477
+ '400':
478
+ $ref: '#/components/responses/BadRequest'
479
+ '401':
480
+ $ref: '#/components/responses/Unauthorized'
481
+ '403':
482
+ $ref: '#/components/responses/Forbidden'
483
+ '404':
484
+ $ref: '#/components/responses/NotFound'
485
+ '429':
486
+ $ref: '#/components/responses/TooManyRequests'
487
+ '500':
488
+ $ref: '#/components/responses/InternalError'
489
+ '502':
490
+ description: Bad Gateway
491
+ content:
492
+ application/json:
493
+ schema:
494
+ $ref: '#/components/schemas/Error'
495
+ /v1/graphs/domain:
496
+ post:
497
+ tags:
498
+ - Data Plane
499
+ summary: Domain graph
500
+ description: Upload a zipped repository snapshot to generate the domain model graph.
501
+ operationId: generateDomainGraph
502
+ security:
503
+ - ApiKeyAuth: []
504
+ parameters:
505
+ - $ref: '#/components/parameters/IdempotencyKey'
506
+ requestBody:
507
+ required: true
508
+ content:
509
+ multipart/form-data:
510
+ schema:
511
+ type: object
512
+ required:
513
+ - file
514
+ properties:
515
+ file:
516
+ type: string
517
+ format: binary
518
+ description: Zipped repository archive containing the code to analyze.
519
+ x-codeSamples:
520
+ - lang: cURL
521
+ label: cURL
522
+ source: |
523
+ curl -X POST 'https://api.supermodeltools.com/v1/graphs/domain' \
524
+ -H 'Idempotency-Key: <idempotency-key>' \
525
+ -H 'X-Api-Key: <api-key>' \
526
+ -F 'file=@/path/to/your/repo-snapshot.zip;type=application/zip'
527
+ - lang: javascript
528
+ label: JavaScript (fetch)
529
+ source: |
530
+ import { readFile } from 'node:fs/promises';
531
+ const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
532
+ const apiKey = '<api-key>';
533
+ const idempotencyKey = '<idempotency-key>';
534
+ const archivePath = '/path/to/your/repo-snapshot.zip';
535
+
536
+ const buffer = await readFile(archivePath);
537
+ const form = new FormData();
538
+ form.append('file', new Blob([buffer], { type: 'application/zip' }), 'repo-snapshot.zip');
539
+
540
+ const res = await fetch(`${baseUrl}/v1/graphs/domain`, {
541
+ method: 'POST',
542
+ headers: {
543
+ 'Idempotency-Key': idempotencyKey,
544
+ 'X-Api-Key': apiKey
545
+ },
546
+ body: form
547
+ });
548
+
549
+ if (!res.ok) throw new Error(await res.text());
550
+ console.log(await res.json());
551
+ - lang: typescript
552
+ label: TypeScript (SDK)
553
+ source: |
554
+ import { Configuration, DefaultApi } from '@supermodel/public-api-typescript';
555
+ import { readFile } from 'node:fs/promises';
556
+
557
+ const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
558
+ const apiKey = '<api-key>';
559
+ const idempotencyKey = '<idempotency-key>';
560
+ const archivePath = '/path/to/your/repo-snapshot.zip';
561
+
562
+ const buffer = await readFile(archivePath);
563
+ const archiveBlob = new Blob([buffer], { type: 'application/zip' });
564
+
565
+ const configuration = new Configuration({ basePath: baseUrl });
566
+
567
+ const apiKeyOverride = async ({ init }) => ({
568
+ headers: { ...(init.headers ?? {}), 'X-Api-Key': apiKey }
569
+ });
570
+
571
+ const api = new DefaultApi(configuration);
572
+ const result = await api.generateDomainGraph(
573
+ { idempotencyKey, file: archiveBlob },
574
+ apiKeyOverride
575
+ );
576
+
577
+ console.log(result);
578
+ - lang: java
579
+ label: Java (generated client)
580
+ source: |
581
+ import org.openapitools.client.ApiClient;
582
+ import org.openapitools.client.api.DefaultApi;
583
+
584
+ import java.io.File;
585
+
586
+ public class Example {
587
+ public static void main(String[] args) throws Exception {
588
+ String baseUrl = System.getenv().getOrDefault("API_BASE_URL", "https://api.supermodeltools.com");
589
+ String apiKey = "<api-key>";
590
+ String idempotencyKey = "<idempotency-key>";
591
+ File archive = new File("/path/to/your/repo-snapshot.zip");
592
+
593
+ ApiClient client = new ApiClient();
594
+ client.updateBaseUri(baseUrl);
595
+ client.setRequestInterceptor(rb -> {
596
+ rb.header("X-Api-Key", apiKey);
597
+ });
598
+
599
+ DefaultApi api = new DefaultApi(client);
600
+ api.generateDomainGraph(idempotencyKey, archive);
601
+ }
602
+ }
603
+ - lang: python
604
+ label: Python (generated client)
605
+ source: |
606
+ import os
607
+ from supermodel_public_api import ApiClient, Configuration
608
+ from supermodel_public_api.api.default_api import DefaultApi
609
+
610
+ base_url = os.environ.get("API_BASE_URL", "https://api.supermodeltools.com")
611
+ api_key = "<api-key>"
612
+ idempotency_key = "<idempotency-key>"
613
+
614
+ configuration = Configuration(host=base_url)
615
+ configuration.api_key["ApiKeyAuth"] = api_key
616
+
617
+ api_client = ApiClient(configuration)
618
+ api = DefaultApi(api_client)
619
+
620
+ with open("/path/to/your/repo-snapshot.zip", "rb") as f:
621
+ payload = f.read()
622
+
623
+ result = api.generate_domain_graph(idempotency_key, file=payload)
624
+ print(result)
625
+ - lang: rust
626
+ label: Rust (reqwest)
627
+ source: |
628
+ use bytes::Bytes;
629
+ use reqwest::multipart::{Form, Part};
630
+
631
+ #[tokio::main]
632
+ async fn main() -> anyhow::Result<()> {
633
+ let base_url = std::env::var("API_BASE_URL")
634
+ .unwrap_or_else(|_| "https://api.supermodeltools.com".to_string());
635
+ let api_key = "<api-key>";
636
+ let idempotency_key = "<idempotency-key>";
637
+
638
+ let archive_bytes = Bytes::from(tokio::fs::read("/path/to/your/repo-snapshot.zip").await?);
639
+ let url = format!("{}/v1/graphs/domain", base_url.trim_end_matches('/'));
640
+
641
+ let file_part = Part::bytes(archive_bytes.to_vec())
642
+ .file_name("repo.zip")
643
+ .mime_str("application/zip")?;
644
+ let form = Form::new().part("file", file_part);
645
+
646
+ let response = reqwest::Client::new()
647
+ .post(url)
648
+ .header("Idempotency-Key", idempotency_key)
649
+ .header("X-Api-Key", api_key)
650
+ .multipart(form)
651
+ .send()
652
+ .await?;
653
+ let status = response.status();
654
+ let body = response.bytes().await?;
655
+
656
+ if status.is_success() {
657
+ println!("{}", String::from_utf8_lossy(&body));
658
+ } else {
659
+ anyhow::bail!(
660
+ "Request failed ({}): {}",
661
+ status.as_u16(),
662
+ String::from_utf8_lossy(&body)
663
+ );
664
+ }
665
+
666
+ Ok(())
667
+ }
668
+ responses:
669
+ '200':
670
+ description: Domain graph
671
+ headers:
672
+ X-Request-Id:
673
+ $ref: '#/components/headers/X-Request-Id'
674
+ X-API-Version:
675
+ $ref: '#/components/headers/X-API-Version'
676
+ RateLimit-Limit:
677
+ $ref: '#/components/headers/RateLimit-Limit'
678
+ RateLimit-Remaining:
679
+ $ref: '#/components/headers/RateLimit-Remaining'
680
+ RateLimit-Reset:
681
+ $ref: '#/components/headers/RateLimit-Reset'
682
+ X-Usage-Units:
683
+ $ref: '#/components/headers/X-Usage-Units'
684
+ content:
685
+ application/json:
686
+ schema:
687
+ $ref: '#/components/schemas/DomainClassificationResponse'
688
+ example:
689
+ runId: smart-sampling-a1b2c3d4
690
+ domains:
691
+ - name: BillingAccount
692
+ descriptionSummary: Handles billing and account management
693
+ keyFiles:
694
+ - src/domain/billing.ts
695
+ - src/services/billing.service.ts
696
+ responsibilities:
697
+ - Account creation
698
+ - Payment processing
699
+ subdomains:
700
+ - name: PaymentProcessing
701
+ descriptionSummary: Processes payment transactions
702
+ - name: UsageSummary
703
+ descriptionSummary: Tracks and summarizes usage metrics
704
+ keyFiles:
705
+ - src/domain/usage.ts
706
+ responsibilities:
707
+ - Usage tracking
708
+ - Metrics aggregation
709
+ subdomains: []
710
+ relationships:
711
+ - from: BillingAccount
712
+ to: UsageSummary
713
+ type: aggregates
714
+ strength: 0.8
715
+ reason: BillingAccount aggregates usage data for billing purposes
716
+ fileAssignments:
717
+ - filePath: src/domain/billing.ts
718
+ domainName: BillingAccount
719
+ - filePath: src/domain/usage.ts
720
+ domainName: UsageSummary
721
+ functionAssignments:
722
+ - functionId: func-123
723
+ subdomainName: PaymentProcessing
724
+ parentDomain: BillingAccount
725
+ unassignedFunctions:
726
+ - functionId: func-456
727
+ reason: Utility function with unclear domain association
728
+ classAssignments:
729
+ - classId: class-789
730
+ domainName: BillingAccount
731
+ functionDescriptions:
732
+ - functionId: func-123
733
+ descriptionSummary: Processes incoming payment transactions
734
+ domainName: BillingAccount
735
+ - functionId: func-456
736
+ descriptionSummary: Aggregates usage metrics for billing period
737
+ stats:
738
+ domainCount: 2
739
+ relationshipCount: 1
740
+ fileAssignments: 2
741
+ functionAssignments: 1
742
+ unassignedFunctions: 1
743
+ classAssignments: 1
744
+ '400':
745
+ $ref: '#/components/responses/BadRequest'
746
+ '401':
747
+ $ref: '#/components/responses/Unauthorized'
748
+ '403':
749
+ $ref: '#/components/responses/Forbidden'
750
+ '404':
751
+ $ref: '#/components/responses/NotFound'
752
+ '429':
753
+ $ref: '#/components/responses/TooManyRequests'
754
+ '500':
755
+ $ref: '#/components/responses/InternalError'
756
+ '502':
757
+ description: Bad Gateway
758
+ content:
759
+ application/json:
760
+ schema:
761
+ $ref: '#/components/schemas/Error'
762
+ /v1/graphs/parse:
763
+ post:
764
+ tags:
765
+ - Data Plane
766
+ summary: Parse graph
767
+ description: Upload a zipped repository snapshot to generate parse tree relationships.
768
+ operationId: generateParseGraph
769
+ security:
770
+ - ApiKeyAuth: []
771
+ parameters:
772
+ - $ref: '#/components/parameters/IdempotencyKey'
773
+ requestBody:
774
+ required: true
775
+ content:
776
+ multipart/form-data:
777
+ schema:
778
+ type: object
779
+ required:
780
+ - file
781
+ properties:
782
+ file:
783
+ type: string
784
+ format: binary
785
+ description: Zipped repository archive containing the code to analyze.
786
+ x-codeSamples:
787
+ - lang: cURL
788
+ label: cURL
789
+ source: |
790
+ curl -X POST 'https://api.supermodeltools.com/v1/graphs/parse' \
791
+ -H 'Idempotency-Key: <idempotency-key>' \
792
+ -H 'X-Api-Key: <api-key>' \
793
+ -F 'file=@/path/to/your/repo-snapshot.zip;type=application/zip'
794
+ - lang: javascript
795
+ label: JavaScript (fetch)
796
+ source: |
797
+ import { readFile } from 'node:fs/promises';
798
+ const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
799
+ const apiKey = '<api-key>';
800
+ const idempotencyKey = '<idempotency-key>';
801
+ const archivePath = '/path/to/your/repo-snapshot.zip';
802
+
803
+ const buffer = await readFile(archivePath);
804
+ const form = new FormData();
805
+ form.append('file', new Blob([buffer], { type: 'application/zip' }), 'repo-snapshot.zip');
806
+
807
+ const res = await fetch(`${baseUrl}/v1/graphs/parse`, {
808
+ method: 'POST',
809
+ headers: {
810
+ 'Idempotency-Key': idempotencyKey,
811
+ 'X-Api-Key': apiKey
812
+ },
813
+ body: form
814
+ });
815
+
816
+ if (!res.ok) throw new Error(await res.text());
817
+ console.log(await res.json());
818
+ - lang: typescript
819
+ label: TypeScript (SDK)
820
+ source: |
821
+ import { Configuration, DefaultApi } from '@supermodel/public-api-typescript';
822
+ import { readFile } from 'node:fs/promises';
823
+
824
+ const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
825
+ const apiKey = '<api-key>';
826
+ const idempotencyKey = '<idempotency-key>';
827
+ const archivePath = '/path/to/your/repo-snapshot.zip';
828
+
829
+ const buffer = await readFile(archivePath);
830
+ const archiveBlob = new Blob([buffer], { type: 'application/zip' });
831
+
832
+ const configuration = new Configuration({ basePath: baseUrl });
833
+
834
+ const apiKeyOverride = async ({ init }) => ({
835
+ headers: { ...(init.headers ?? {}), 'X-Api-Key': apiKey }
836
+ });
837
+
838
+ const api = new DefaultApi(configuration);
839
+ const result = await api.generateParseGraph(
840
+ { idempotencyKey, file: archiveBlob },
841
+ apiKeyOverride
842
+ );
843
+
844
+ console.log(result);
845
+ - lang: java
846
+ label: Java (generated client)
847
+ source: |
848
+ import org.openapitools.client.ApiClient;
849
+ import org.openapitools.client.api.DefaultApi;
850
+
851
+ import java.io.File;
852
+
853
+ public class Example {
854
+ public static void main(String[] args) throws Exception {
855
+ String baseUrl = System.getenv().getOrDefault("API_BASE_URL", "https://api.supermodeltools.com");
856
+ String apiKey = "<api-key>";
857
+ String idempotencyKey = "<idempotency-key>";
858
+ File archive = new File("/path/to/your/repo-snapshot.zip");
859
+
860
+ ApiClient client = new ApiClient();
861
+ client.updateBaseUri(baseUrl);
862
+ client.setRequestInterceptor(rb -> {
863
+ rb.header("X-Api-Key", apiKey);
864
+ });
865
+
866
+ DefaultApi api = new DefaultApi(client);
867
+ api.generateParseGraph(idempotencyKey, archive);
868
+ }
869
+ }
870
+ - lang: python
871
+ label: Python (generated client)
872
+ source: |
873
+ import os
874
+ from supermodel_public_api import ApiClient, Configuration
875
+ from supermodel_public_api.api.default_api import DefaultApi
876
+
877
+ base_url = os.environ.get("API_BASE_URL", "https://api.supermodeltools.com")
878
+ api_key = "<api-key>"
879
+ idempotency_key = "<idempotency-key>"
880
+
881
+ configuration = Configuration(host=base_url)
882
+ configuration.api_key["ApiKeyAuth"] = api_key
883
+
884
+ api_client = ApiClient(configuration)
885
+ api = DefaultApi(api_client)
886
+
887
+ with open("/path/to/your/repo-snapshot.zip", "rb") as f:
888
+ payload = f.read()
889
+
890
+ result = api.generate_parse_graph(idempotency_key, file=payload)
891
+ print(result)
892
+ - lang: rust
893
+ label: Rust (reqwest)
894
+ source: |
895
+ use bytes::Bytes;
896
+ use reqwest::multipart::{Form, Part};
897
+
898
+ #[tokio::main]
899
+ async fn main() -> anyhow::Result<()> {
900
+ let base_url = std::env::var("API_BASE_URL")
901
+ .unwrap_or_else(|_| "https://api.supermodeltools.com".to_string());
902
+ let api_key = "<api-key>";
903
+ let idempotency_key = "<idempotency-key>";
904
+
905
+ let archive_bytes = Bytes::from(tokio::fs::read("/path/to/your/repo-snapshot.zip").await?);
906
+ let url = format!("{}/v1/graphs/parse", base_url.trim_end_matches('/'));
907
+
908
+ let file_part = Part::bytes(archive_bytes.to_vec())
909
+ .file_name("repo.zip")
910
+ .mime_str("application/zip")?;
911
+ let form = Form::new().part("file", file_part);
912
+
913
+ let response = reqwest::Client::new()
914
+ .post(url)
915
+ .header("Idempotency-Key", idempotency_key)
916
+ .header("X-Api-Key", api_key)
917
+ .multipart(form)
918
+ .send()
919
+ .await?;
920
+ let status = response.status();
921
+ let body = response.bytes().await?;
922
+
923
+ if status.is_success() {
924
+ println!("{}", String::from_utf8_lossy(&body));
925
+ } else {
926
+ anyhow::bail!(
927
+ "Request failed ({}): {}",
928
+ status.as_u16(),
929
+ String::from_utf8_lossy(&body)
930
+ );
931
+ }
932
+
933
+ Ok(())
934
+ }
935
+ responses:
936
+ '200':
937
+ description: Parse graph
938
+ headers:
939
+ X-Request-Id:
940
+ $ref: '#/components/headers/X-Request-Id'
941
+ X-API-Version:
942
+ $ref: '#/components/headers/X-API-Version'
943
+ RateLimit-Limit:
944
+ $ref: '#/components/headers/RateLimit-Limit'
945
+ RateLimit-Remaining:
946
+ $ref: '#/components/headers/RateLimit-Remaining'
947
+ RateLimit-Reset:
948
+ $ref: '#/components/headers/RateLimit-Reset'
949
+ X-Usage-Units:
950
+ $ref: '#/components/headers/X-Usage-Units'
951
+ content:
952
+ application/json:
953
+ schema:
954
+ $ref: '#/components/schemas/CodeGraphEnvelope'
955
+ example:
956
+ generatedAt: '2025-02-05 15:42:10.000000000 Z'
957
+ message: Parse graph generated successfully
958
+ stats:
959
+ filesProcessed: 1
960
+ classes: 0
961
+ functions: 1
962
+ types: 0
963
+ processingTimeMs: 12
964
+ graph:
965
+ nodes:
966
+ - id: ast:src/index.ts:1:0
967
+ labels:
968
+ - Program
969
+ properties:
970
+ kind: Program
971
+ - id: ast:src/index.ts:3:2
972
+ labels:
973
+ - FunctionDeclaration
974
+ properties:
975
+ name: init
976
+ relationships:
977
+ - id: ast:src/index.ts:1:0_contains_ast:src/index.ts:3:2
978
+ type: contains
979
+ startNode: ast:src/index.ts:1:0
980
+ endNode: ast:src/index.ts:3:2
981
+ properties:
982
+ order: 1
983
+ '400':
984
+ $ref: '#/components/responses/BadRequest'
985
+ '401':
986
+ $ref: '#/components/responses/Unauthorized'
987
+ '403':
988
+ $ref: '#/components/responses/Forbidden'
989
+ '404':
990
+ $ref: '#/components/responses/NotFound'
991
+ '429':
992
+ $ref: '#/components/responses/TooManyRequests'
993
+ '500':
994
+ $ref: '#/components/responses/InternalError'
995
+ '502':
996
+ description: Bad Gateway
997
+ content:
998
+ application/json:
999
+ schema:
1000
+ $ref: '#/components/schemas/Error'
1001
+ /v1/graphs/supermodel:
1002
+ post:
1003
+ tags:
1004
+ - Data Plane
1005
+ summary: Supermodel graph
1006
+ description: Upload a zipped repository snapshot to generate the Supermodel Intermediate Representation (SIR) artifact bundle.
1007
+ operationId: generateSupermodelGraph
1008
+ security:
1009
+ - ApiKeyAuth: []
1010
+ parameters:
1011
+ - $ref: '#/components/parameters/IdempotencyKey'
1012
+ requestBody:
1013
+ required: true
1014
+ content:
1015
+ multipart/form-data:
1016
+ schema:
1017
+ type: object
1018
+ required:
1019
+ - file
1020
+ properties:
1021
+ file:
1022
+ type: string
1023
+ format: binary
1024
+ description: Zipped repository archive containing the code to analyze.
1025
+ x-codeSamples:
1026
+ - lang: cURL
1027
+ label: cURL
1028
+ source: |
1029
+ curl -X POST 'https://api.supermodeltools.com/v1/graphs/supermodel' \
1030
+ -H 'Idempotency-Key: <idempotency-key>' \
1031
+ -H 'X-Api-Key: <api-key>' \
1032
+ -F 'file=@/path/to/your/repo-snapshot.zip;type=application/zip'
1033
+ - lang: javascript
1034
+ label: JavaScript (fetch)
1035
+ source: |
1036
+ import { readFile } from 'node:fs/promises';
1037
+ const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
1038
+ const apiKey = '<api-key>';
1039
+ const idempotencyKey = '<idempotency-key>';
1040
+ const archivePath = '/path/to/your/repo-snapshot.zip';
1041
+
1042
+ const buffer = await readFile(archivePath);
1043
+ const form = new FormData();
1044
+ form.append('file', new Blob([buffer], { type: 'application/zip' }), 'repo-snapshot.zip');
1045
+
1046
+ const res = await fetch(`${baseUrl}/v1/graphs/supermodel`, {
1047
+ method: 'POST',
1048
+ headers: {
1049
+ 'Idempotency-Key': idempotencyKey,
1050
+ 'X-Api-Key': apiKey
1051
+ },
1052
+ body: form
1053
+ });
1054
+
1055
+ if (!res.ok) throw new Error(await res.text());
1056
+ console.log(await res.json());
1057
+ - lang: typescript
1058
+ label: TypeScript (SDK)
1059
+ source: |
1060
+ import { Configuration, DefaultApi } from '@supermodel/public-api-typescript';
1061
+ import { readFile } from 'node:fs/promises';
1062
+
1063
+ const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
1064
+ const apiKey = '<api-key>';
1065
+ const idempotencyKey = '<idempotency-key>';
1066
+ const archivePath = '/path/to/your/repo-snapshot.zip';
1067
+
1068
+ const buffer = await readFile(archivePath);
1069
+ const archiveBlob = new Blob([buffer], { type: 'application/zip' });
1070
+
1071
+ const configuration = new Configuration({ basePath: baseUrl });
1072
+
1073
+ const apiKeyOverride = async ({ init }) => ({
1074
+ headers: { ...(init.headers ?? {}), 'X-Api-Key': apiKey }
1075
+ });
1076
+
1077
+ const api = new DefaultApi(configuration);
1078
+ const result = await api.generateSupermodelGraph(
1079
+ { idempotencyKey, file: archiveBlob },
1080
+ apiKeyOverride
1081
+ );
1082
+
1083
+ console.log(result);
1084
+ - lang: java
1085
+ label: Java (generated client)
1086
+ source: |
1087
+ import org.openapitools.client.ApiClient;
1088
+ import org.openapitools.client.api.DefaultApi;
1089
+
1090
+ import java.io.File;
1091
+
1092
+ public class Example {
1093
+ public static void main(String[] args) throws Exception {
1094
+ String baseUrl = System.getenv().getOrDefault("API_BASE_URL", "https://api.supermodeltools.com");
1095
+ String apiKey = "<api-key>";
1096
+ String idempotencyKey = "<idempotency-key>";
1097
+ File archive = new File("/path/to/your/repo-snapshot.zip");
1098
+
1099
+ ApiClient client = new ApiClient();
1100
+ client.updateBaseUri(baseUrl);
1101
+ client.setRequestInterceptor(rb -> {
1102
+ rb.header("X-Api-Key", apiKey);
1103
+ });
1104
+
1105
+ DefaultApi api = new DefaultApi(client);
1106
+ api.generateSupermodelGraph(idempotencyKey, archive);
1107
+ }
1108
+ }
1109
+ - lang: python
1110
+ label: Python (generated client)
1111
+ source: |
1112
+ import os
1113
+ from supermodel_public_api import ApiClient, Configuration
1114
+ from supermodel_public_api.api.default_api import DefaultApi
1115
+
1116
+ base_url = os.environ.get("API_BASE_URL", "https://api.supermodeltools.com")
1117
+ api_key = "<api-key>"
1118
+ idempotency_key = "<idempotency-key>"
1119
+
1120
+ configuration = Configuration(host=base_url)
1121
+ configuration.api_key["ApiKeyAuth"] = api_key
1122
+
1123
+ api_client = ApiClient(configuration)
1124
+ api = DefaultApi(api_client)
1125
+
1126
+ with open("/path/to/your/repo-snapshot.zip", "rb") as f:
1127
+ payload = f.read()
1128
+
1129
+ result = api.generate_supermodel_graph(idempotency_key, file=payload)
1130
+ print(result)
1131
+ - lang: rust
1132
+ label: Rust (reqwest)
1133
+ source: |
1134
+ use bytes::Bytes;
1135
+ use reqwest::multipart::{Form, Part};
1136
+
1137
+ #[tokio::main]
1138
+ async fn main() -> anyhow::Result<()> {
1139
+ let base_url = std::env::var("API_BASE_URL")
1140
+ .unwrap_or_else(|_| "https://api.supermodeltools.com".to_string());
1141
+ let api_key = "<api-key>";
1142
+ let idempotency_key = "<idempotency-key>";
1143
+
1144
+ let archive_bytes = Bytes::from(tokio::fs::read("/path/to/your/repo-snapshot.zip").await?);
1145
+ let url = format!("{}/v1/graphs/supermodel", base_url.trim_end_matches('/'));
1146
+
1147
+ let file_part = Part::bytes(archive_bytes.to_vec())
1148
+ .file_name("repo.zip")
1149
+ .mime_str("application/zip")?;
1150
+ let form = Form::new().part("file", file_part);
1151
+
1152
+ let response = reqwest::Client::new()
1153
+ .post(url)
1154
+ .header("Idempotency-Key", idempotency_key)
1155
+ .header("X-Api-Key", api_key)
1156
+ .multipart(form)
1157
+ .send()
1158
+ .await?;
1159
+ let status = response.status();
1160
+ let body = response.bytes().await?;
1161
+
1162
+ if status.is_success() {
1163
+ println!("{}", String::from_utf8_lossy(&body));
1164
+ } else {
1165
+ anyhow::bail!(
1166
+ "Request failed ({}): {}",
1167
+ status.as_u16(),
1168
+ String::from_utf8_lossy(&body)
1169
+ );
1170
+ }
1171
+
1172
+ Ok(())
1173
+ }
1174
+ responses:
1175
+ '200':
1176
+ description: Supermodel IR document
1177
+ headers:
1178
+ X-Request-Id:
1179
+ $ref: '#/components/headers/X-Request-Id'
1180
+ X-API-Version:
1181
+ $ref: '#/components/headers/X-API-Version'
1182
+ RateLimit-Limit:
1183
+ $ref: '#/components/headers/RateLimit-Limit'
1184
+ RateLimit-Remaining:
1185
+ $ref: '#/components/headers/RateLimit-Remaining'
1186
+ RateLimit-Reset:
1187
+ $ref: '#/components/headers/RateLimit-Reset'
1188
+ X-Usage-Units:
1189
+ $ref: '#/components/headers/X-Usage-Units'
1190
+ content:
1191
+ application/json:
1192
+ schema:
1193
+ $ref: '#/components/schemas/SupermodelIR'
1194
+ example:
1195
+ repo: supermodel/supermodel-public-api
1196
+ version: sir-2025-02-05
1197
+ schemaVersion: 1.2.0
1198
+ generatedAt: '2025-02-05 15:42:10.000000000 Z'
1199
+ summary:
1200
+ repoSizeBytes: 123456
1201
+ filesProcessed: 42
1202
+ classes: 8
1203
+ functions: 156
1204
+ types: 12
1205
+ primaryLanguage: typescript
1206
+ domains: 5
1207
+ graph:
1208
+ nodes:
1209
+ - id: src/index.ts
1210
+ labels:
1211
+ - File
1212
+ properties:
1213
+ path: src/index.ts
1214
+ name: index.ts
1215
+ language: typescript
1216
+ - id: fn:src/index.ts:main
1217
+ labels:
1218
+ - Function
1219
+ properties:
1220
+ name: main
1221
+ filePath: src/index.ts
1222
+ startLine: 10
1223
+ endLine: 25
1224
+ - id: fn:src/utils.ts:helper
1225
+ labels:
1226
+ - Function
1227
+ properties:
1228
+ name: helper
1229
+ filePath: src/utils.ts
1230
+ - id: domain:Core
1231
+ labels:
1232
+ - Domain
1233
+ properties:
1234
+ name: Core
1235
+ description: Core application logic
1236
+ - id: subdomain:Core:Initialization
1237
+ labels:
1238
+ - Subdomain
1239
+ properties:
1240
+ name: Initialization
1241
+ parentDomain: Core
1242
+ relationships:
1243
+ - id: src/index.ts_contains_fn:src/index.ts:main
1244
+ type: contains
1245
+ startNode: src/index.ts
1246
+ endNode: fn:src/index.ts:main
1247
+ - id: src/index.ts_imports_src/utils.ts
1248
+ type: imports
1249
+ startNode: src/index.ts
1250
+ endNode: src/utils.ts
1251
+ - id: fn:src/index.ts:main_calls_fn:src/utils.ts:helper
1252
+ type: calls
1253
+ startNode: fn:src/index.ts:main
1254
+ endNode: fn:src/utils.ts:helper
1255
+ - id: fn:src/index.ts:main_belongsTo_subdomain:Core:Initialization
1256
+ type: belongsTo
1257
+ startNode: fn:src/index.ts:main
1258
+ endNode: subdomain:Core:Initialization
1259
+ artifacts:
1260
+ - id: artifact-usage-summary
1261
+ kind: summary
1262
+ label: Usage Insights
1263
+ metadata:
1264
+ repoSizeBytes: 123456
1265
+ filesProcessed: 42
1266
+ functions: 156
1267
+ classes: 8
1268
+ - id: parse-graph
1269
+ kind: graph
1270
+ label: Parse Graph
1271
+ metadata:
1272
+ nodeCount: 150
1273
+ relationshipCount: 280
1274
+ - id: call-graph
1275
+ kind: graph
1276
+ label: Call Graph
1277
+ metadata:
1278
+ totalFunctions: 156
1279
+ totalCalls: 423
1280
+ - id: domain-classification
1281
+ kind: classification
1282
+ label: Domain Classification
1283
+ metadata:
1284
+ domainCount: 5
1285
+ relationshipCount: 8
1286
+ fileAssignments: 42
1287
+ functionAssignments: 120
1288
+ '400':
1289
+ $ref: '#/components/responses/BadRequest'
1290
+ '401':
1291
+ $ref: '#/components/responses/Unauthorized'
1292
+ '403':
1293
+ $ref: '#/components/responses/Forbidden'
1294
+ '429':
1295
+ $ref: '#/components/responses/TooManyRequests'
1296
+ '500':
1297
+ $ref: '#/components/responses/InternalError'
1298
+ '502':
1299
+ description: Bad Gateway
1300
+ content:
1301
+ application/json:
1302
+ schema:
1303
+ $ref: '#/components/schemas/Error'
1304
+ components:
1305
+ securitySchemes:
1306
+ ApiKeyAuth:
1307
+ type: apiKey
1308
+ in: header
1309
+ name: X-Api-Key
1310
+ description: API key issued by the control plane for accessing data plane resources.
1311
+ BearerAuth:
1312
+ type: http
1313
+ scheme: bearer
1314
+ description: HTTP Bearer authentication using an OAuth provider-issued access token presented via the Authorization header.
1315
+ StripeSecret:
1316
+ type: apiKey
1317
+ in: header
1318
+ name: Stripe-Secret
1319
+ description: Shared secret used to authorize Stripe webhook callbacks.
1320
+ parameters:
1321
+ IdempotencyKey:
1322
+ name: Idempotency-Key
1323
+ in: header
1324
+ required: true
1325
+ description: Unique identifier for this request for idempotency and tracing.
1326
+ schema:
1327
+ type: string
1328
+ headers:
1329
+ X-Request-Id:
1330
+ description: Unique request identifier echoed back from the Idempotency-Key header.
1331
+ schema:
1332
+ type: string
1333
+ X-API-Version:
1334
+ description: Semantic version of the API service handling the request.
1335
+ schema:
1336
+ type: string
1337
+ RateLimit-Limit:
1338
+ description: Maximum number of requests allowed in the current rate limit window.
1339
+ schema:
1340
+ type: integer
1341
+ format: int32
1342
+ RateLimit-Remaining:
1343
+ description: Remaining number of requests available in the current rate limit window.
1344
+ schema:
1345
+ type: integer
1346
+ format: int32
1347
+ RateLimit-Reset:
1348
+ description: UTC epoch seconds when the current rate limit window resets.
1349
+ schema:
1350
+ type: integer
1351
+ format: int64
1352
+ X-Usage-Units:
1353
+ description: Metered usage units consumed by this request.
1354
+ schema:
1355
+ type: number
1356
+ format: float
1357
+ responses:
1358
+ BadRequest:
1359
+ description: The request could not be processed because of a client error.
1360
+ headers:
1361
+ X-Request-Id:
1362
+ $ref: '#/components/headers/X-Request-Id'
1363
+ X-API-Version:
1364
+ $ref: '#/components/headers/X-API-Version'
1365
+ RateLimit-Limit:
1366
+ $ref: '#/components/headers/RateLimit-Limit'
1367
+ RateLimit-Remaining:
1368
+ $ref: '#/components/headers/RateLimit-Remaining'
1369
+ RateLimit-Reset:
1370
+ $ref: '#/components/headers/RateLimit-Reset'
1371
+ X-Usage-Units:
1372
+ $ref: '#/components/headers/X-Usage-Units'
1373
+ content:
1374
+ application/json:
1375
+ schema:
1376
+ $ref: '#/components/schemas/Error'
1377
+ example:
1378
+ status: 400
1379
+ code: invalid_request
1380
+ message: Missing required query parameter 'repo'.
1381
+ timestamp: '2025-02-05 16:35:12.000000000 Z'
1382
+ requestId: req_01HZYJ9CE0ABCDEF1234
1383
+ details:
1384
+ - field: repo
1385
+ issue: This field is required.
1386
+ location: query
1387
+ Unauthorized:
1388
+ description: Authentication failed or was not provided.
1389
+ headers:
1390
+ X-Request-Id:
1391
+ $ref: '#/components/headers/X-Request-Id'
1392
+ X-API-Version:
1393
+ $ref: '#/components/headers/X-API-Version'
1394
+ RateLimit-Limit:
1395
+ $ref: '#/components/headers/RateLimit-Limit'
1396
+ RateLimit-Remaining:
1397
+ $ref: '#/components/headers/RateLimit-Remaining'
1398
+ RateLimit-Reset:
1399
+ $ref: '#/components/headers/RateLimit-Reset'
1400
+ X-Usage-Units:
1401
+ $ref: '#/components/headers/X-Usage-Units'
1402
+ content:
1403
+ application/json:
1404
+ schema:
1405
+ $ref: '#/components/schemas/Error'
1406
+ example:
1407
+ status: 401
1408
+ code: unauthorized
1409
+ message: Provide a valid OAuth token to access this resource.
1410
+ timestamp: '2025-02-05 16:35:12.000000000 Z'
1411
+ requestId: req_01HZYJ9CE0ABCDEFXYZ1
1412
+ Forbidden:
1413
+ description: The authenticated principal lacks the required permissions.
1414
+ headers:
1415
+ X-Request-Id:
1416
+ $ref: '#/components/headers/X-Request-Id'
1417
+ X-API-Version:
1418
+ $ref: '#/components/headers/X-API-Version'
1419
+ RateLimit-Limit:
1420
+ $ref: '#/components/headers/RateLimit-Limit'
1421
+ RateLimit-Remaining:
1422
+ $ref: '#/components/headers/RateLimit-Remaining'
1423
+ RateLimit-Reset:
1424
+ $ref: '#/components/headers/RateLimit-Reset'
1425
+ X-Usage-Units:
1426
+ $ref: '#/components/headers/X-Usage-Units'
1427
+ content:
1428
+ application/json:
1429
+ schema:
1430
+ $ref: '#/components/schemas/Error'
1431
+ example:
1432
+ status: 403
1433
+ code: forbidden
1434
+ message: The token lacks the required keys:write scope.
1435
+ timestamp: '2025-02-05 16:35:12.000000000 Z'
1436
+ requestId: req_01HZYJ9CE0ABCDEFFORB
1437
+ NotFound:
1438
+ description: The requested resource could not be found.
1439
+ headers:
1440
+ X-Request-Id:
1441
+ $ref: '#/components/headers/X-Request-Id'
1442
+ X-API-Version:
1443
+ $ref: '#/components/headers/X-API-Version'
1444
+ RateLimit-Limit:
1445
+ $ref: '#/components/headers/RateLimit-Limit'
1446
+ RateLimit-Remaining:
1447
+ $ref: '#/components/headers/RateLimit-Remaining'
1448
+ RateLimit-Reset:
1449
+ $ref: '#/components/headers/RateLimit-Reset'
1450
+ X-Usage-Units:
1451
+ $ref: '#/components/headers/X-Usage-Units'
1452
+ content:
1453
+ application/json:
1454
+ schema:
1455
+ $ref: '#/components/schemas/Error'
1456
+ example:
1457
+ status: 404
1458
+ code: not_found
1459
+ message: API key ak_live_missing was not found.
1460
+ timestamp: '2025-02-05 16:35:12.000000000 Z'
1461
+ requestId: req_01HZYJ9CE0ABCDEFF404
1462
+ TooManyRequests:
1463
+ description: The rate limit for the resource has been exceeded.
1464
+ headers:
1465
+ X-Request-Id:
1466
+ $ref: '#/components/headers/X-Request-Id'
1467
+ X-API-Version:
1468
+ $ref: '#/components/headers/X-API-Version'
1469
+ RateLimit-Limit:
1470
+ $ref: '#/components/headers/RateLimit-Limit'
1471
+ RateLimit-Remaining:
1472
+ $ref: '#/components/headers/RateLimit-Remaining'
1473
+ RateLimit-Reset:
1474
+ $ref: '#/components/headers/RateLimit-Reset'
1475
+ X-Usage-Units:
1476
+ $ref: '#/components/headers/X-Usage-Units'
1477
+ content:
1478
+ application/json:
1479
+ schema:
1480
+ $ref: '#/components/schemas/Error'
1481
+ example:
1482
+ status: 429
1483
+ code: rate_limit_exceeded
1484
+ message: Too many requests. Try again after the reset window.
1485
+ timestamp: '2025-02-05 16:35:12.000000000 Z'
1486
+ requestId: req_01HZYJ9CE0ABCDEFRATE
1487
+ InternalError:
1488
+ description: The server encountered an unexpected condition.
1489
+ headers:
1490
+ X-Request-Id:
1491
+ $ref: '#/components/headers/X-Request-Id'
1492
+ X-API-Version:
1493
+ $ref: '#/components/headers/X-API-Version'
1494
+ RateLimit-Limit:
1495
+ $ref: '#/components/headers/RateLimit-Limit'
1496
+ RateLimit-Remaining:
1497
+ $ref: '#/components/headers/RateLimit-Remaining'
1498
+ RateLimit-Reset:
1499
+ $ref: '#/components/headers/RateLimit-Reset'
1500
+ X-Usage-Units:
1501
+ $ref: '#/components/headers/X-Usage-Units'
1502
+ content:
1503
+ application/json:
1504
+ schema:
1505
+ $ref: '#/components/schemas/Error'
1506
+ example:
1507
+ status: 500
1508
+ code: internal_error
1509
+ message: Unexpected error processing request. Please retry.
1510
+ timestamp: '2025-02-05 16:35:12.000000000 Z'
1511
+ requestId: req_01HZYJ9CE0ABCDEFFAIL
1512
+ schemas:
1513
+ CodeGraphNode:
1514
+ type: object
1515
+ properties:
1516
+ id:
1517
+ type: string
1518
+ labels:
1519
+ type: array
1520
+ items:
1521
+ type: string
1522
+ properties:
1523
+ type: object
1524
+ additionalProperties: true
1525
+ required:
1526
+ - id
1527
+ CodeGraphRelationship:
1528
+ type: object
1529
+ properties:
1530
+ id:
1531
+ type: string
1532
+ type:
1533
+ type: string
1534
+ startNode:
1535
+ type: string
1536
+ endNode:
1537
+ type: string
1538
+ properties:
1539
+ type: object
1540
+ additionalProperties: true
1541
+ required:
1542
+ - id
1543
+ - type
1544
+ - startNode
1545
+ - endNode
1546
+ CodeGraphStats:
1547
+ type: object
1548
+ properties:
1549
+ filesProcessed:
1550
+ type: integer
1551
+ format: int64
1552
+ classes:
1553
+ type: integer
1554
+ format: int64
1555
+ functions:
1556
+ type: integer
1557
+ format: int64
1558
+ types:
1559
+ type: integer
1560
+ format: int64
1561
+ processingTimeMs:
1562
+ type: number
1563
+ CodeGraphEnvelope:
1564
+ type: object
1565
+ properties:
1566
+ generatedAt:
1567
+ type: string
1568
+ format: date-time
1569
+ message:
1570
+ type: string
1571
+ stats:
1572
+ $ref: '#/components/schemas/CodeGraphStats'
1573
+ graph:
1574
+ type: object
1575
+ properties:
1576
+ nodes:
1577
+ type: array
1578
+ items:
1579
+ $ref: '#/components/schemas/CodeGraphNode'
1580
+ relationships:
1581
+ type: array
1582
+ items:
1583
+ $ref: '#/components/schemas/CodeGraphRelationship'
1584
+ required:
1585
+ - nodes
1586
+ - relationships
1587
+ required:
1588
+ - graph
1589
+ Error:
1590
+ type: object
1591
+ description: Standardized error payload returned by the API.
1592
+ required:
1593
+ - status
1594
+ - code
1595
+ - message
1596
+ - timestamp
1597
+ properties:
1598
+ status:
1599
+ type: integer
1600
+ format: int32
1601
+ description: HTTP status code associated with the error.
1602
+ minimum: 100
1603
+ maximum: 599
1604
+ code:
1605
+ type: string
1606
+ description: Stable, machine-readable error identifier.
1607
+ message:
1608
+ type: string
1609
+ description: Human-readable description of the error.
1610
+ timestamp:
1611
+ type: string
1612
+ format: date-time
1613
+ description: ISO-8601 timestamp indicating when the error occurred.
1614
+ requestId:
1615
+ type: string
1616
+ description: Correlation identifier for tracing the failing request.
1617
+ details:
1618
+ type: array
1619
+ description: Optional list of contextual error details.
1620
+ items:
1621
+ type: object
1622
+ required:
1623
+ - field
1624
+ - issue
1625
+ properties:
1626
+ field:
1627
+ type: string
1628
+ description: Name of the field or parameter related to the error.
1629
+ issue:
1630
+ type: string
1631
+ description: Description of the specific issue encountered.
1632
+ location:
1633
+ type: string
1634
+ description: Where the field resides (e.g., query, path, body).
1635
+ SupermodelArtifact:
1636
+ type: object
1637
+ required:
1638
+ - id
1639
+ - kind
1640
+ - label
1641
+ properties:
1642
+ id:
1643
+ type: string
1644
+ description: Unique identifier for the artifact.
1645
+ kind:
1646
+ type: string
1647
+ description: Artifact kind such as graph, summary, or embedding.
1648
+ label:
1649
+ type: string
1650
+ description: Human-readable name for the artifact.
1651
+ metadata:
1652
+ type: object
1653
+ description: Additional metadata for consuming the artifact.
1654
+ additionalProperties: true
1655
+ SupermodelIR:
1656
+ type: object
1657
+ required:
1658
+ - repo
1659
+ - version
1660
+ - schemaVersion
1661
+ - generatedAt
1662
+ - graph
1663
+ properties:
1664
+ repo:
1665
+ type: string
1666
+ description: Repository slug the IR was generated from.
1667
+ version:
1668
+ type: string
1669
+ description: Version identifier for the IR content.
1670
+ schemaVersion:
1671
+ type: string
1672
+ description: Version of the IR schema.
1673
+ generatedAt:
1674
+ type: string
1675
+ format: date-time
1676
+ description: Timestamp when the IR was generated.
1677
+ summary:
1678
+ type: object
1679
+ description: High-level metadata and summary insights including filesProcessed, classes, functions, types, primaryLanguage, and domains count.
1680
+ additionalProperties: true
1681
+ graph:
1682
+ type: object
1683
+ description: Unified code graph containing all nodes and relationships.
1684
+ properties:
1685
+ nodes:
1686
+ type: array
1687
+ description: All nodes from parse graph, call graph, and domain classification.
1688
+ items:
1689
+ $ref: '#/components/schemas/CodeGraphNode'
1690
+ relationships:
1691
+ type: array
1692
+ description: All relationships including contains, imports, calls, and belongsTo.
1693
+ items:
1694
+ $ref: '#/components/schemas/CodeGraphRelationship'
1695
+ required:
1696
+ - nodes
1697
+ - relationships
1698
+ artifacts:
1699
+ type: array
1700
+ description: Per-source statistics and metadata for parse graph, call graph, and domain classification.
1701
+ items:
1702
+ $ref: '#/components/schemas/SupermodelArtifact'
1703
+ DomainClassificationResponse:
1704
+ type: object
1705
+ properties:
1706
+ runId:
1707
+ type: string
1708
+ description: Unique identifier for this classification run
1709
+ domains:
1710
+ type: array
1711
+ items:
1712
+ $ref: '#/components/schemas/DomainSummary'
1713
+ description: Array of primary domain entities
1714
+ relationships:
1715
+ type: array
1716
+ items:
1717
+ $ref: '#/components/schemas/DomainRelationship'
1718
+ description: High-level relationships between domains/subdomains
1719
+ fileAssignments:
1720
+ type: array
1721
+ items:
1722
+ $ref: '#/components/schemas/DomainFileAssignment'
1723
+ description: Mapping of files to domains
1724
+ functionAssignments:
1725
+ type: array
1726
+ items:
1727
+ $ref: '#/components/schemas/DomainFunctionAssignment'
1728
+ description: Mapping of functions to subdomains
1729
+ unassignedFunctions:
1730
+ type: array
1731
+ items:
1732
+ $ref: '#/components/schemas/UnassignedFunction'
1733
+ description: Functions that could not be assigned to a domain/subdomain
1734
+ classAssignments:
1735
+ type: array
1736
+ items:
1737
+ $ref: '#/components/schemas/DomainClassAssignment'
1738
+ description: Mapping of classes to domains
1739
+ functionDescriptions:
1740
+ type: array
1741
+ items:
1742
+ $ref: '#/components/schemas/FunctionDescription'
1743
+ description: Optional enriched descriptions per function
1744
+ stats:
1745
+ $ref: '#/components/schemas/ClassificationStats'
1746
+ required:
1747
+ - runId
1748
+ - domains
1749
+ - relationships
1750
+ - fileAssignments
1751
+ - functionAssignments
1752
+ - unassignedFunctions
1753
+ - classAssignments
1754
+ - stats
1755
+ DomainSummary:
1756
+ type: object
1757
+ properties:
1758
+ name:
1759
+ type: string
1760
+ description: Domain name (e.g., BillingAccount)
1761
+ descriptionSummary:
1762
+ type: string
1763
+ description: Human-readable description of the domain
1764
+ keyFiles:
1765
+ type: array
1766
+ items:
1767
+ type: string
1768
+ description: Representative files backing the domain
1769
+ responsibilities:
1770
+ type: array
1771
+ items:
1772
+ type: string
1773
+ description: Key responsibilities/concerns of the domain
1774
+ subdomains:
1775
+ type: array
1776
+ items:
1777
+ $ref: '#/components/schemas/SubdomainSummary'
1778
+ description: Subdomains for this domain
1779
+ required:
1780
+ - name
1781
+ - descriptionSummary
1782
+ - keyFiles
1783
+ - responsibilities
1784
+ - subdomains
1785
+ SubdomainSummary:
1786
+ type: object
1787
+ properties:
1788
+ name:
1789
+ type: string
1790
+ description: Subdomain name
1791
+ descriptionSummary:
1792
+ type: string
1793
+ description: Concise description of the subdomain
1794
+ required:
1795
+ - name
1796
+ - descriptionSummary
1797
+ DomainRelationship:
1798
+ type: object
1799
+ properties:
1800
+ from:
1801
+ type: string
1802
+ description: Source domain or subdomain name/id
1803
+ to:
1804
+ type: string
1805
+ description: Target domain or subdomain name/id
1806
+ type:
1807
+ type: string
1808
+ description: Relationship type (e.g., aggregates, dependsOn, relatesTo)
1809
+ strength:
1810
+ type: number
1811
+ description: Numeric strength/weight (0-1 or small integer)
1812
+ reason:
1813
+ type: string
1814
+ description: Optional explanation for the relationship
1815
+ required:
1816
+ - from
1817
+ - to
1818
+ - type
1819
+ - strength
1820
+ DomainFileAssignment:
1821
+ type: object
1822
+ properties:
1823
+ filePath:
1824
+ type: string
1825
+ description: Repository-relative file path
1826
+ domainName:
1827
+ type: string
1828
+ description: Assigned domain
1829
+ required:
1830
+ - filePath
1831
+ - domainName
1832
+ DomainFunctionAssignment:
1833
+ type: object
1834
+ properties:
1835
+ functionId:
1836
+ type: string
1837
+ description: Stable function identifier (matching codegraph/function models)
1838
+ subdomainName:
1839
+ type: string
1840
+ description: Subdomain assigned to the function
1841
+ parentDomain:
1842
+ type: string
1843
+ description: Optional parent domain containing the subdomain
1844
+ required:
1845
+ - functionId
1846
+ - subdomainName
1847
+ UnassignedFunction:
1848
+ type: object
1849
+ properties:
1850
+ functionId:
1851
+ type: string
1852
+ description: Function that could not be assigned
1853
+ reason:
1854
+ type: string
1855
+ description: Reason it was left unassigned
1856
+ required:
1857
+ - functionId
1858
+ - reason
1859
+ DomainClassAssignment:
1860
+ type: object
1861
+ properties:
1862
+ classId:
1863
+ type: string
1864
+ description: Class identifier
1865
+ domainName:
1866
+ type: string
1867
+ description: Assigned domain
1868
+ required:
1869
+ - classId
1870
+ - domainName
1871
+ FunctionDescription:
1872
+ type: object
1873
+ properties:
1874
+ functionId:
1875
+ type: string
1876
+ description: Function identifier
1877
+ descriptionSummary:
1878
+ type: string
1879
+ description: Short summary of behavior
1880
+ domainName:
1881
+ type: string
1882
+ description: Optional domain/subdomain association
1883
+ required:
1884
+ - functionId
1885
+ - descriptionSummary
1886
+ ClassificationStats:
1887
+ type: object
1888
+ properties:
1889
+ domainCount:
1890
+ type: integer
1891
+ description: Number of domains discovered
1892
+ relationshipCount:
1893
+ type: integer
1894
+ description: Number of relationships
1895
+ fileAssignments:
1896
+ type: integer
1897
+ description: Count of file assignments
1898
+ functionAssignments:
1899
+ type: integer
1900
+ description: Count of function assignments
1901
+ unassignedFunctions:
1902
+ type: integer
1903
+ description: Count of unassigned functions
1904
+ classAssignments:
1905
+ type: integer
1906
+ description: Count of class assignments
1907
+ required:
1908
+ - domainCount
1909
+ - relationshipCount
1910
+ - fileAssignments
1911
+ - functionAssignments
1912
+ - unassignedFunctions
1913
+ - classAssignments