cURL
curl -X POST 'https://api.supermodeltools.com/v1/graphs/call' \
-H 'Idempotency-Key: <idempotency-key>' \
-H 'X-Api-Key: <api-key>' \
-F 'file=@/path/to/your/repo-snapshot.zip;type=application/zip'import { readFile } from 'node:fs/promises';
const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
const apiKey = '<api-key>';
const idempotencyKey = '<idempotency-key>';
const archivePath = '/path/to/your/repo-snapshot.zip';
const buffer = await readFile(archivePath);
const form = new FormData();
form.append('file', new Blob([buffer], { type: 'application/zip' }), 'repo-snapshot.zip');
const res = await fetch(`${baseUrl}/v1/graphs/call`, {
method: 'POST',
headers: {
'Idempotency-Key': idempotencyKey,
'X-Api-Key': apiKey
},
body: form
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());import { Configuration, DefaultApi } from '@supermodel/public-api-typescript';
import { readFile } from 'node:fs/promises';
const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
const apiKey = '<api-key>';
const idempotencyKey = '<idempotency-key>';
const archivePath = '/path/to/your/repo-snapshot.zip';
const buffer = await readFile(archivePath);
const archiveBlob = new Blob([buffer], { type: 'application/zip' });
const configuration = new Configuration({ basePath: baseUrl });
const apiKeyOverride = async ({ init }) => ({
headers: { ...(init.headers ?? {}), 'X-Api-Key': apiKey }
});
const api = new DefaultApi(configuration);
const result = await api.generateCallGraph(
{ idempotencyKey, file: archiveBlob },
apiKeyOverride
);
console.log(result);import org.openapitools.client.ApiClient;
import org.openapitools.client.api.DefaultApi;
import java.io.File;
public class Example {
public static void main(String[] args) throws Exception {
String baseUrl = System.getenv().getOrDefault("API_BASE_URL", "https://api.supermodeltools.com");
String apiKey = "<api-key>";
String idempotencyKey = "<idempotency-key>";
File archive = new File("/path/to/your/repo-snapshot.zip");
ApiClient client = new ApiClient();
client.updateBaseUri(baseUrl);
client.setRequestInterceptor(rb -> {
rb.header("X-Api-Key", apiKey);
});
DefaultApi api = new DefaultApi(client);
api.generateCallGraph(idempotencyKey, archive);
}
}import os
from supermodel_public_api import ApiClient, Configuration
from supermodel_public_api.api.default_api import DefaultApi
base_url = os.environ.get("API_BASE_URL", "https://api.supermodeltools.com")
api_key = "<api-key>"
idempotency_key = "<idempotency-key>"
configuration = Configuration(host=base_url)
configuration.api_key["ApiKeyAuth"] = api_key
api_client = ApiClient(configuration)
api = DefaultApi(api_client)
with open("/path/to/your/repo-snapshot.zip", "rb") as f:
payload = f.read()
result = api.generate_call_graph(idempotency_key, file=payload)
print(result)use bytes::Bytes;
use reqwest::multipart::{Form, Part};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let base_url = std::env::var("API_BASE_URL")
.unwrap_or_else(|_| "https://api.supermodeltools.com".to_string());
let api_key = "<api-key>";
let idempotency_key = "<idempotency-key>";
let archive_bytes = Bytes::from(tokio::fs::read("/path/to/your/repo-snapshot.zip").await?);
let url = format!("{}/v1/graphs/call", base_url.trim_end_matches('/'));
let file_part = Part::bytes(archive_bytes.to_vec())
.file_name("repo.zip")
.mime_str("application/zip")?;
let form = Form::new().part("file", file_part);
let response = reqwest::Client::new()
.post(url)
.header("Idempotency-Key", idempotency_key)
.header("X-Api-Key", api_key)
.multipart(form)
.send()
.await?;
let status = response.status();
let body = response.bytes().await?;
if status.is_success() {
println!("{}", String::from_utf8_lossy(&body));
} else {
anyhow::bail!(
"Request failed ({}): {}",
status.as_u16(),
String::from_utf8_lossy(&body)
);
}
Ok(())
}<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.supermodeltools.com/v1/graphs/call",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Content-Type: multipart/form-data; boundary=---011000010111000001101001",
"Idempotency-Key: <idempotency-key>",
"X-Api-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.supermodeltools.com/v1/graphs/call"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
req.Header.Add("X-Api-Key", "<api-key>")
req.Header.Add("Content-Type", "multipart/form-data; boundary=---011000010111000001101001")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}require 'uri'
require 'net/http'
url = URI("https://api.supermodeltools.com/v1/graphs/call")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["X-Api-Key"] = '<api-key>'
request["Content-Type"] = 'multipart/form-data; boundary=---011000010111000001101001'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"status": "completed",
"jobId": "abc-123-def",
"result": {
"generatedAt": "2025-02-05 15:42:10.000000000 Z",
"message": "Call graph generated successfully",
"stats": {
"filesProcessed": 2,
"classes": 0,
"functions": 2,
"types": 0,
"processingTimeMs": 8
},
"graph": {
"nodes": [
{
"id": "fn:index.ts:init",
"labels": [
"Function"
],
"properties": {
"file": "src/index.ts"
}
},
{
"id": "fn:service.ts:handle",
"labels": [
"Function"
],
"properties": {
"file": "src/service.ts"
}
}
],
"relationships": [
{
"id": "fn:index.ts:init_calls_fn:service.ts:handle",
"type": "calls",
"startNode": "fn:index.ts:init",
"endNode": "fn:service.ts:handle",
"properties": {
"count": 4
}
}
]
}
}
}{
"status": "processing",
"jobId": "abc-123-def",
"retryAfter": 5
}{
"status": 400,
"code": "invalid_request",
"message": "Missing required query parameter 'repo'.",
"timestamp": "2025-02-05 16:35:12.000000000 Z",
"requestId": "req_01HZYJ9CE0ABCDEF1234",
"details": [
{
"field": "repo",
"issue": "This field is required.",
"location": "query"
}
]
}{
"status": 401,
"code": "unauthorized",
"message": "Provide a valid OAuth token to access this resource.",
"timestamp": "2025-02-05 16:35:12.000000000 Z",
"requestId": "req_01HZYJ9CE0ABCDEFXYZ1"
}{
"status": 403,
"code": "forbidden",
"message": "The token lacks the required keys:write scope.",
"timestamp": "2025-02-05 16:35:12.000000000 Z",
"requestId": "req_01HZYJ9CE0ABCDEFFORB"
}{
"status": 404,
"code": "not_found",
"message": "API key ak_live_missing was not found.",
"timestamp": "2025-02-05 16:35:12.000000000 Z",
"requestId": "req_01HZYJ9CE0ABCDEFF404"
}{
"status": 429,
"code": "rate_limit_exceeded",
"message": "Too many requests. Try again after the reset window.",
"timestamp": "2025-02-05 16:35:12.000000000 Z",
"requestId": "req_01HZYJ9CE0ABCDEFRATE"
}{
"status": 500,
"code": "internal_error",
"message": "Unexpected error processing request. Please retry.",
"timestamp": "2025-02-05 16:35:12.000000000 Z",
"requestId": "req_01HZYJ9CE0ABCDEFFAIL"
}{
"status": 349,
"code": "<string>",
"message": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"requestId": "<string>",
"details": [
{
"field": "<string>",
"issue": "<string>",
"location": "<string>"
}
]
}Data Plane
Call graph
Upload a zipped repository snapshot to generate the function-level call graph.
POST
/
v1
/
graphs
/
call
cURL
curl -X POST 'https://api.supermodeltools.com/v1/graphs/call' \
-H 'Idempotency-Key: <idempotency-key>' \
-H 'X-Api-Key: <api-key>' \
-F 'file=@/path/to/your/repo-snapshot.zip;type=application/zip'import { readFile } from 'node:fs/promises';
const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
const apiKey = '<api-key>';
const idempotencyKey = '<idempotency-key>';
const archivePath = '/path/to/your/repo-snapshot.zip';
const buffer = await readFile(archivePath);
const form = new FormData();
form.append('file', new Blob([buffer], { type: 'application/zip' }), 'repo-snapshot.zip');
const res = await fetch(`${baseUrl}/v1/graphs/call`, {
method: 'POST',
headers: {
'Idempotency-Key': idempotencyKey,
'X-Api-Key': apiKey
},
body: form
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());import { Configuration, DefaultApi } from '@supermodel/public-api-typescript';
import { readFile } from 'node:fs/promises';
const baseUrl = process.env.API_BASE_URL || 'https://api.supermodeltools.com';
const apiKey = '<api-key>';
const idempotencyKey = '<idempotency-key>';
const archivePath = '/path/to/your/repo-snapshot.zip';
const buffer = await readFile(archivePath);
const archiveBlob = new Blob([buffer], { type: 'application/zip' });
const configuration = new Configuration({ basePath: baseUrl });
const apiKeyOverride = async ({ init }) => ({
headers: { ...(init.headers ?? {}), 'X-Api-Key': apiKey }
});
const api = new DefaultApi(configuration);
const result = await api.generateCallGraph(
{ idempotencyKey, file: archiveBlob },
apiKeyOverride
);
console.log(result);import org.openapitools.client.ApiClient;
import org.openapitools.client.api.DefaultApi;
import java.io.File;
public class Example {
public static void main(String[] args) throws Exception {
String baseUrl = System.getenv().getOrDefault("API_BASE_URL", "https://api.supermodeltools.com");
String apiKey = "<api-key>";
String idempotencyKey = "<idempotency-key>";
File archive = new File("/path/to/your/repo-snapshot.zip");
ApiClient client = new ApiClient();
client.updateBaseUri(baseUrl);
client.setRequestInterceptor(rb -> {
rb.header("X-Api-Key", apiKey);
});
DefaultApi api = new DefaultApi(client);
api.generateCallGraph(idempotencyKey, archive);
}
}import os
from supermodel_public_api import ApiClient, Configuration
from supermodel_public_api.api.default_api import DefaultApi
base_url = os.environ.get("API_BASE_URL", "https://api.supermodeltools.com")
api_key = "<api-key>"
idempotency_key = "<idempotency-key>"
configuration = Configuration(host=base_url)
configuration.api_key["ApiKeyAuth"] = api_key
api_client = ApiClient(configuration)
api = DefaultApi(api_client)
with open("/path/to/your/repo-snapshot.zip", "rb") as f:
payload = f.read()
result = api.generate_call_graph(idempotency_key, file=payload)
print(result)use bytes::Bytes;
use reqwest::multipart::{Form, Part};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let base_url = std::env::var("API_BASE_URL")
.unwrap_or_else(|_| "https://api.supermodeltools.com".to_string());
let api_key = "<api-key>";
let idempotency_key = "<idempotency-key>";
let archive_bytes = Bytes::from(tokio::fs::read("/path/to/your/repo-snapshot.zip").await?);
let url = format!("{}/v1/graphs/call", base_url.trim_end_matches('/'));
let file_part = Part::bytes(archive_bytes.to_vec())
.file_name("repo.zip")
.mime_str("application/zip")?;
let form = Form::new().part("file", file_part);
let response = reqwest::Client::new()
.post(url)
.header("Idempotency-Key", idempotency_key)
.header("X-Api-Key", api_key)
.multipart(form)
.send()
.await?;
let status = response.status();
let body = response.bytes().await?;
if status.is_success() {
println!("{}", String::from_utf8_lossy(&body));
} else {
anyhow::bail!(
"Request failed ({}): {}",
status.as_u16(),
String::from_utf8_lossy(&body)
);
}
Ok(())
}<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.supermodeltools.com/v1/graphs/call",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Content-Type: multipart/form-data; boundary=---011000010111000001101001",
"Idempotency-Key: <idempotency-key>",
"X-Api-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.supermodeltools.com/v1/graphs/call"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
req.Header.Add("X-Api-Key", "<api-key>")
req.Header.Add("Content-Type", "multipart/form-data; boundary=---011000010111000001101001")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}require 'uri'
require 'net/http'
url = URI("https://api.supermodeltools.com/v1/graphs/call")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["X-Api-Key"] = '<api-key>'
request["Content-Type"] = 'multipart/form-data; boundary=---011000010111000001101001'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"status": "completed",
"jobId": "abc-123-def",
"result": {
"generatedAt": "2025-02-05 15:42:10.000000000 Z",
"message": "Call graph generated successfully",
"stats": {
"filesProcessed": 2,
"classes": 0,
"functions": 2,
"types": 0,
"processingTimeMs": 8
},
"graph": {
"nodes": [
{
"id": "fn:index.ts:init",
"labels": [
"Function"
],
"properties": {
"file": "src/index.ts"
}
},
{
"id": "fn:service.ts:handle",
"labels": [
"Function"
],
"properties": {
"file": "src/service.ts"
}
}
],
"relationships": [
{
"id": "fn:index.ts:init_calls_fn:service.ts:handle",
"type": "calls",
"startNode": "fn:index.ts:init",
"endNode": "fn:service.ts:handle",
"properties": {
"count": 4
}
}
]
}
}
}{
"status": "processing",
"jobId": "abc-123-def",
"retryAfter": 5
}{
"status": 400,
"code": "invalid_request",
"message": "Missing required query parameter 'repo'.",
"timestamp": "2025-02-05 16:35:12.000000000 Z",
"requestId": "req_01HZYJ9CE0ABCDEF1234",
"details": [
{
"field": "repo",
"issue": "This field is required.",
"location": "query"
}
]
}{
"status": 401,
"code": "unauthorized",
"message": "Provide a valid OAuth token to access this resource.",
"timestamp": "2025-02-05 16:35:12.000000000 Z",
"requestId": "req_01HZYJ9CE0ABCDEFXYZ1"
}{
"status": 403,
"code": "forbidden",
"message": "The token lacks the required keys:write scope.",
"timestamp": "2025-02-05 16:35:12.000000000 Z",
"requestId": "req_01HZYJ9CE0ABCDEFFORB"
}{
"status": 404,
"code": "not_found",
"message": "API key ak_live_missing was not found.",
"timestamp": "2025-02-05 16:35:12.000000000 Z",
"requestId": "req_01HZYJ9CE0ABCDEFF404"
}{
"status": 429,
"code": "rate_limit_exceeded",
"message": "Too many requests. Try again after the reset window.",
"timestamp": "2025-02-05 16:35:12.000000000 Z",
"requestId": "req_01HZYJ9CE0ABCDEFRATE"
}{
"status": 500,
"code": "internal_error",
"message": "Unexpected error processing request. Please retry.",
"timestamp": "2025-02-05 16:35:12.000000000 Z",
"requestId": "req_01HZYJ9CE0ABCDEFFAIL"
}{
"status": 349,
"code": "<string>",
"message": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"requestId": "<string>",
"details": [
{
"field": "<string>",
"issue": "<string>",
"location": "<string>"
}
]
}Authorizations
API key issued by the control plane for accessing data plane resources.
Headers
Unique identifier for this request for idempotency and tracing.
Body
multipart/form-data
Zipped repository archive containing the code to analyze.
Response
Call graph (job completed)
Async response envelope for code graph operations.
Current status of the job.
Available options:
pending, processing, completed, failed Unique identifier for the job.
Recommended seconds to wait before polling again.
Error message (present when status is failed).
The result (present when status is completed).
Show child attributes
Show child attributes
⌘I