Skip to main content
POST
/
v1
/
graphs
/
parse
cURL
curl -X POST 'https://api.supermodeltools.com/v1/graphs/parse' \
  -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/parse`, {
  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.generateParseGraph(
  { 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.generateParseGraph(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_parse_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/parse", 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/parse",
  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/parse"

	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/parse")

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": "Parse graph generated successfully",
    "stats": {
      "filesProcessed": 1,
      "classes": 0,
      "functions": 1,
      "types": 0,
      "processingTimeMs": 12
    },
    "graph": {
      "nodes": [
        {
          "id": "ast:src/index.ts:1:0",
          "labels": [
            "Program"
          ],
          "properties": {
            "kind": "Program"
          }
        },
        {
          "id": "ast:src/index.ts:3:2",
          "labels": [
            "FunctionDeclaration"
          ],
          "properties": {
            "name": "init"
          }
        }
      ],
      "relationships": [
        {
          "id": "ast:src/index.ts:1:0_contains_ast:src/index.ts:3:2",
          "type": "contains",
          "startNode": "ast:src/index.ts:1:0",
          "endNode": "ast:src/index.ts:3:2",
          "properties": {
            "order": 1
          }
        }
      ]
    }
  }
}
{
  "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

Parse 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).