> ## Documentation Index
> Fetch the complete documentation index at: https://docs.supermodeltools.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Call graph

> Upload a zipped repository snapshot to generate the function-level call graph.



## OpenAPI

````yaml /openapi.yaml post /v1/graphs/call
openapi: 3.0.0
info:
  title: Supermodel
  description: Code Graphing & Analysis API
  version: 0.9.6
  license:
    name: Supermodel API Terms of Service
    url: https://supermodeltools.com/legal/api-terms
servers:
  - url: https://api.supermodeltools.com
    description: Production server
security: []
tags:
  - name: Data Plane
    description: >-
      Calls the data plane to retrieve Supermodel analysis artifacts derived
      from repositories.
paths:
  /v1/graphs/call:
    post:
      tags:
        - Data Plane
      summary: Call graph
      description: >-
        Upload a zipped repository snapshot to generate the function-level call
        graph.
      operationId: generateCallGraph
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - file
              properties:
                file:
                  type: string
                  format: binary
                  description: Zipped repository archive containing the code to analyze.
      responses:
        '200':
          description: Call graph (job completed)
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            X-API-Version:
              $ref: '#/components/headers/X-API-Version'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimit-Limit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimit-Remaining'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimit-Reset'
            X-Usage-Units:
              $ref: '#/components/headers/X-Usage-Units'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CodeGraphEnvelopeAsync'
              example:
                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
        '202':
          description: Job accepted and processing
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            X-API-Version:
              $ref: '#/components/headers/X-API-Version'
            Retry-After:
              description: Recommended wait time in seconds before polling again.
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CodeGraphEnvelopeAsync'
              example:
                status: processing
                jobId: abc-123-def
                retryAfter: 5
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '502':
          description: Bad Gateway
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            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'
        - lang: javascript
          label: JavaScript (fetch)
          source: >
            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());
        - lang: typescript
          label: TypeScript (SDK)
          source: >
            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);
        - lang: java
          label: Java (generated client)
          source: |
            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);
              }
            }
        - lang: python
          label: Python (generated client)
          source: >
            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)
        - lang: rust
          label: Rust (reqwest)
          source: |
            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(())
            }
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: true
      description: Unique identifier for this request for idempotency and tracing.
      schema:
        type: string
  headers:
    X-Request-Id:
      description: Unique request identifier echoed back from the Idempotency-Key header.
      schema:
        type: string
    X-API-Version:
      description: Semantic version of the API service handling the request.
      schema:
        type: string
    RateLimit-Limit:
      description: Maximum number of requests allowed in the current rate limit window.
      schema:
        type: integer
        format: int32
    RateLimit-Remaining:
      description: Remaining number of requests available in the current rate limit window.
      schema:
        type: integer
        format: int32
    RateLimit-Reset:
      description: UTC epoch seconds when the current rate limit window resets.
      schema:
        type: integer
        format: int64
    X-Usage-Units:
      description: Metered usage units consumed by this request.
      schema:
        type: number
        format: float
  schemas:
    CodeGraphEnvelopeAsync:
      allOf:
        - $ref: '#/components/schemas/JobStatus'
        - type: object
          description: Async response envelope for code graph operations.
          properties:
            result:
              $ref: '#/components/schemas/CodeGraphEnvelope'
              description: The result (present when status is completed).
    Error:
      type: object
      description: Standardized error payload returned by the API.
      required:
        - status
        - code
        - message
        - timestamp
      properties:
        status:
          type: integer
          format: int32
          description: HTTP status code associated with the error.
          minimum: 100
          maximum: 599
        code:
          type: string
          description: Stable, machine-readable error identifier.
        message:
          type: string
          description: Human-readable description of the error.
        timestamp:
          type: string
          format: date-time
          description: ISO-8601 timestamp indicating when the error occurred.
        requestId:
          type: string
          description: Correlation identifier for tracing the failing request.
        details:
          type: array
          description: Optional list of contextual error details.
          items:
            type: object
            required:
              - field
              - issue
            properties:
              field:
                type: string
                description: Name of the field or parameter related to the error.
              issue:
                type: string
                description: Description of the specific issue encountered.
              location:
                type: string
                description: Where the field resides (e.g., query, path, body).
    JobStatus:
      type: object
      description: Common fields for async job status tracking.
      required:
        - status
        - jobId
      properties:
        status:
          type: string
          description: Current status of the job.
          enum:
            - pending
            - processing
            - completed
            - failed
        jobId:
          type: string
          description: Unique identifier for the job.
        retryAfter:
          type: integer
          format: int32
          description: Recommended seconds to wait before polling again.
        error:
          type: string
          description: Error message (present when status is failed).
    CodeGraphEnvelope:
      type: object
      properties:
        generatedAt:
          type: string
          format: date-time
        message:
          type: string
        stats:
          $ref: '#/components/schemas/CodeGraphStats'
        metadata:
          type: object
          properties:
            analysisStartTime:
              type: string
              format: date-time
            analysisEndTime:
              type: string
              format: date-time
            fileCount:
              type: integer
            languages:
              type: array
              items:
                type: string
          description: Analysis metadata including timing and file information
        graph:
          type: object
          properties:
            nodes:
              type: array
              items:
                $ref: '#/components/schemas/CodeGraphNode'
            relationships:
              type: array
              items:
                $ref: '#/components/schemas/CodeGraphRelationship'
          required:
            - nodes
            - relationships
      required:
        - graph
    CodeGraphStats:
      type: object
      properties:
        nodeCount:
          type: integer
          format: int64
          description: Total number of nodes in the graph
        relationshipCount:
          type: integer
          format: int64
          description: Total number of relationships in the graph
        nodeTypes:
          type: object
          additionalProperties:
            type: integer
          description: Count of nodes by type
        relationshipTypes:
          type: object
          additionalProperties:
            type: integer
          description: Count of relationships by type
        filesProcessed:
          type: integer
          format: int64
        classes:
          type: integer
          format: int64
        functions:
          type: integer
          format: int64
        types:
          type: integer
          format: int64
        processingTimeMs:
          type: number
    CodeGraphNode:
      type: object
      properties:
        id:
          type: string
        labels:
          type: array
          items:
            type: string
        properties:
          type: object
          additionalProperties: true
      required:
        - id
    CodeGraphRelationship:
      type: object
      properties:
        id:
          type: string
        type:
          type: string
        startNode:
          type: string
        endNode:
          type: string
        properties:
          type: object
          additionalProperties: true
      required:
        - id
        - type
        - startNode
        - endNode
  responses:
    BadRequest:
      description: The request could not be processed because of a client error.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
        X-API-Version:
          $ref: '#/components/headers/X-API-Version'
        RateLimit-Limit:
          $ref: '#/components/headers/RateLimit-Limit'
        RateLimit-Remaining:
          $ref: '#/components/headers/RateLimit-Remaining'
        RateLimit-Reset:
          $ref: '#/components/headers/RateLimit-Reset'
        X-Usage-Units:
          $ref: '#/components/headers/X-Usage-Units'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            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
    Unauthorized:
      description: Authentication failed or was not provided.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
        X-API-Version:
          $ref: '#/components/headers/X-API-Version'
        RateLimit-Limit:
          $ref: '#/components/headers/RateLimit-Limit'
        RateLimit-Remaining:
          $ref: '#/components/headers/RateLimit-Remaining'
        RateLimit-Reset:
          $ref: '#/components/headers/RateLimit-Reset'
        X-Usage-Units:
          $ref: '#/components/headers/X-Usage-Units'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            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
    Forbidden:
      description: The authenticated principal lacks the required permissions.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
        X-API-Version:
          $ref: '#/components/headers/X-API-Version'
        RateLimit-Limit:
          $ref: '#/components/headers/RateLimit-Limit'
        RateLimit-Remaining:
          $ref: '#/components/headers/RateLimit-Remaining'
        RateLimit-Reset:
          $ref: '#/components/headers/RateLimit-Reset'
        X-Usage-Units:
          $ref: '#/components/headers/X-Usage-Units'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            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
    NotFound:
      description: The requested resource could not be found.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
        X-API-Version:
          $ref: '#/components/headers/X-API-Version'
        RateLimit-Limit:
          $ref: '#/components/headers/RateLimit-Limit'
        RateLimit-Remaining:
          $ref: '#/components/headers/RateLimit-Remaining'
        RateLimit-Reset:
          $ref: '#/components/headers/RateLimit-Reset'
        X-Usage-Units:
          $ref: '#/components/headers/X-Usage-Units'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            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
    TooManyRequests:
      description: The rate limit for the resource has been exceeded.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
        X-API-Version:
          $ref: '#/components/headers/X-API-Version'
        RateLimit-Limit:
          $ref: '#/components/headers/RateLimit-Limit'
        RateLimit-Remaining:
          $ref: '#/components/headers/RateLimit-Remaining'
        RateLimit-Reset:
          $ref: '#/components/headers/RateLimit-Reset'
        X-Usage-Units:
          $ref: '#/components/headers/X-Usage-Units'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            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
    InternalError:
      description: The server encountered an unexpected condition.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
        X-API-Version:
          $ref: '#/components/headers/X-API-Version'
        RateLimit-Limit:
          $ref: '#/components/headers/RateLimit-Limit'
        RateLimit-Remaining:
          $ref: '#/components/headers/RateLimit-Remaining'
        RateLimit-Reset:
          $ref: '#/components/headers/RateLimit-Reset'
        X-Usage-Units:
          $ref: '#/components/headers/X-Usage-Units'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            status: 500
            code: internal_error
            message: Unexpected error processing request. Please retry.
            timestamp: '2025-02-05 16:35:12.000000000 Z'
            requestId: req_01HZYJ9CE0ABCDEFFAIL
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-Api-Key
      description: API key issued by the control plane for accessing data plane resources.

````