Skip to main content
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

X-Api-Key
string
header
required

API key issued by the control plane for accessing data plane resources.

Headers

Idempotency-Key
string
required

Unique identifier for this request for idempotency and tracing.

Body

multipart/form-data
file
file
required

Zipped repository archive containing the code to analyze.

Response

Call graph (job completed)

Async response envelope for code graph operations.

status
enum<string>
required

Current status of the job.

Available options:
pending,
processing,
completed,
failed
jobId
string
required

Unique identifier for the job.

retryAfter
integer<int32>

Recommended seconds to wait before polling again.

error
string

Error message (present when status is failed).

result
object

The result (present when status is completed).