Interlynk
API Docs
API Docs
  • API Docs
Powered by GitBook
On this page
  • API Details
  • Authentication
  • Endpoint
  • Requests
  • Use-cases

API Docs

To create integrations, retrieve/ingest data and automate workflows use Interlynk's GraphQL api. Interlynk's GraphQL api offers precise and flexible queries to match your integration needs.

Last updated 7 months ago

API Details

Authentication

The primary method of authenticating your API is via Security Tokens. You can obtain your security token by logging into the dashboard and following the steps below.

  • Login to the

  • Click on settings on the left-hand bar

  • Click on "Personal" on the top right.

  • Click on "Security Tokens"

  • Click on "+" to generate a new token.

You can name your security token at this stage and set its expiration date. Depending on the type of integration being done, its recommended to choose the appropriate expiration date. Interlynk's security token looks like lynk_live_CgzGW2qLk5C73o7SgsKyBT3wVcm*********

Please remember to copy the token once generated, you will not be able to retrieve it once you close the window.

The security token assumes the role of the user who created it. If a user with admin role creates the token it will have admin privileges.

Endpoint

Interlynk's GraphQL has a single endpoint. The same endpoint supports both queries and mutations.

https://api.interlynk.io/lynkapi

Requests

The curl command below demonstrates a simple call to the endpoint to retrieve your organizations name.

curl 'https://api.interlynk.io/lynkapi' \
  -H 'authorization: Bearer _<SECURITY_TOKEN>' \
  -H 'content-type: application/json' \
  -d '{
    "operationName": "GetOrgName",
    "variables": {},
    "query": "query GetOrgName { organization { name } }"
  }'
$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession

Invoke-WebRequest -UseBasicParsing -Uri "https://api.interlynk.io/lynkapi" -Method "POST" -WebSession $session -Headers @{
    "authorization" = "Bearer lynk_live_<SECURITY_TOKEN>"
} -ContentType "application/json" -Body '{
    "operationName": "GetOrgName",
    "variables": {},
    "query": "query GetOrgName { organization { name } }"
}'
require 'net/http'
require 'uri'
require 'json'

uri = URI.parse("https://api.interlynk.io/lynkapi")
r
header = {
  "Authorization" => "Bearer lynk_live_<SECURITY_TOKEN>",
  "Content-Type" => "application/json"
}

body = {
  operationName: "GetOrgName",
  variables: {},
  query: "query GetOrgName { organization { name } }"
}.to_json

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Post.new(uri.request_uri, header)
request.body = body

response = http.request(request)

puts response.body
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        var url = "https://api.interlynk.io/lynkapi";
        var securityToken = "lynk_live_<SECURITY_TOKEN>"; // Replace with your actual token

        using (var client = new HttpClient())
        {
            client.DefaultRequestHeaders.Add("Authorization", $"Bearer {securityToken}");
            client.DefaultRequestHeaders.Add("Content-Type", "application/json");

            var jsonBody = new
            {
                operationName = "GetOrgName",
                variables = new { },
                query = "query GetOrgName { organization { name } }"
            };

            var content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(jsonBody), Encoding.UTF8, "application/json");

            var response = await client.PostAsync(url, content);

            string responseString = await response.Content.ReadAsStringAsync();
            Console.WriteLine(responseString);
        }
    }
}

Pagination

For most of the queries we support cursor based pagination. Cursor-based pagination is an efficient method for traversing large datasets in GraphQL. It uses a unique identifier (cursor) to determine the starting point for each subsequent query, allowing for consistent and performant data retrieval.

For all queries we always provide the total number of records for each query. If the number of entries to be returned is not provided it always defaults to 25.

The below example provides an example of a pagination request.

query GetProjectGroups() {
  organization {
    id
    projectGroups(
      first: $first
      last: $last
      after: $after
      before: $before
    ) {
      totalCount
      pageInfo {
        endCursor
        hasNextPage
        startCursor
        hasPreviousPage
        __typename
      }
      nodes {
        id
      }
    }
  }
}
{
  "data": {
    "organization": {
      "id": "72219448-e3cf-47f4-8e54-49199fc47f52",
      "projectGroups": {
        "totalCount": 3,
        "pageInfo": {
          "endCursor": "Mw",
          "hasNextPage": false,
          "startCursor": "MQ",
          "hasPreviousPage": false
        },
        "nodes": [
          {
            "id": "006b70d7-0cb9-4194-ad81-7fb03a886b09",
          }
        ]      
      }
    }
  }
}

Things to note

  • ProjectGroup takes params to control the pagination e.g first, last, after, before

    • (first, after): these params go together, first 100 starting after this offset.

    • (last, before): these params go together, last 30 before this offset.

  • totalCount is requested, which provides the total number of items in the dataset.

  • PageInfo: Server provided response which can be used for the next request.

    • (hasNextPage, endCursor): these allow for forward progression, if hasNextPage is true.

    • (hasPreviousPage, startCursor): these allow for backward progression, if hasPreviousPage is true.

Introspection

The production endpoint does not support introspection.

Search

For most of the queries we support search. The search fields are context dependent.

Ordering

For most of the queries we support ordering.

Use-cases

Below are a list of use cases which can help you build integrations

Get all projects and associated environments

query GetProjectsAndEnv($search: String, $enabled: Boolean, $first: Int, $last: Int, $after: String, $before: String, $field: ProjectGroupOrderByFields!, $direction: OrderByDirection!) {
  organization {
    id
    projectGroups(
      search: $search
      enabled: $enabled
      first: $first
      last: $last
      after: $after
      before: $before
      orderBy: {field: $field, direction: $direction}
    ) {
      totalCount
      pageInfo {
        endCursor
        hasNextPage
        startCursor
        hasPreviousPage
      }
      nodes {
        id
        name
        enabled
        versionCount: sbomsCount
        updatedAt
        environments: projects {
          id
          name
          versionCount: sbomsCount
        }
      }
    }
  }
}
{
  "field": "PROJECT_GROUPS_UPDATED_AT",
  "direction": "DESC",
  "enabled": true,
  "first": 25
}
{
  "data": {
    "organization": {
      "id": "72219448-e3cf-47f4-8e54-49199fc47f52",
      "projectGroups": {
        "totalCount": 3,
        "pageInfo": {
          "endCursor": "Mw",
          "hasNextPage": false,
          "startCursor": "MQ",
          "hasPreviousPage": false
        },
        "nodes": [
          {
            "id": "006b70d7-0cb9-4194-ad81-7fb03a886b09",
            "name": "aqqq",
            "enabled": true,
            "versionCount": 1,
            "updatedAt": "2024-08-04T01:00:29Z",
            "environments": [
              {
                "id": "d70a3087-a8cd-4795-883b-d1c505b6244d",
                "name": "default",
                "versionCount": 1
              },
              {
                "id": "c549a170-573b-49d5-adf6-b00777a6bab1",
                "name": "development",
                "versionCount": 0
              },
              {
                "id": "37e7cc15-b4d3-4af6-b04c-656d81df81e0",
                "name": "production",
                "versionCount": 0
              },
              ....
              
            ]
          }
        ]
      }
    }
  }
}

List versions for project id

query GetVersions($id: Uuid!, $first: Int, $after: String, $last: Int, $before: String, $search: String, $field: SbomOrderByFields!, $direction: OrderByDirection!) {
  project(id: $id) {
    id
    versions: sbomVersions(
      first: $first
      after: $after
      last: $last
      before: $before
      search: $search
      orderBy: {direction: $direction, field: $field}
    ) {
      totalCount
      pageInfo {
        endCursor
        hasNextPage
        startCursor
        hasPreviousPage
      }
      nodes {
        id
        createdAt
        updatedAt
        lifecycle
        projectVersion
        vulnRunStatus
      }
    }
  }
}
{
  "id": "d70a3087-a8cd-4795-883b-d1c505b6244d",
  "field": "SBOMS_CREATED_AT",
  "direction": "DESC",
  "first": 25
}
{
  "data": {
    "project": {
      "id": "d70a3087-a8cd-4795-883b-d1c505b6244d",
      "versions": {
        "totalCount": 1,
        "pageInfo": {
          "endCursor": "MQ",
          "hasNextPage": false,
          "startCursor": "MQ",
          "hasPreviousPage": false
        },
        "nodes": [
          {
            "id": "966a5022-6ff5-4768-909c-0181f9804540",
            "createdAt": "2024-08-01T00:00:04Z",
            "updatedAt": "2024-08-04T01:00:29Z",
            "lifecycle": "edited",
            "projectVersion": "2.0.31",
            "vulnRunStatus": "FINISHED"
          }
        ]
      }
    }
  }
}

Upload SBOM as version for Project

mutation UploadSbom($doc: Upload!, $projectId: ID!) {
  sbomUpload(input: {doc: $doc, projectId: $projectId}) {
    errors
  }
}
{
  "doc": null,
  "projectId": "d70a3087-a8cd-4795-883b-d1c505b6244d"
}
{
  "data": {
    "sbomUpload": {
      "errors": []
    }
  }
}

Download CycloneDX SBOM for a version

query downloadSbom($environmentId: Uuid!, $versionId: Uuid!, $includeVulns: Boolean) {
  sbom(projectId: $environmentId, sbomId: $sbomId) {
    download(sbomId: $versionId, includeVulns: $includeVulns)
    __typename
  }
}
{
  "environmentId": "d70a3087-a8cd-4795-883b-d1c505b6244d",
  "versionId": "966a5022-6ff5-4768-909c-0181f9804540",
  "includeVulns": false
}
{
   "data":{
      "sbom":{
         "download":"Base 64 encoded string"
      }
   }
}

Version Quality Score

query GetVersionQualityScores($versionIds: [ID!]!, $reportFormat: ComplianceReportFormat) {
  complianceReports(sbomIds: $versionIds, reportFormat: $reportFormat) {
    nodes {
      reportFormat
      score
      scoreByCategory {
        category
        score
      }
    }
  }
}
{
  "versionIds": [
    "966a5022-6ff5-4768-909c-0181f9804540"
  ],
  "reportFormat": "NTIA"
}
{
  "data": {
    "complianceReports": {
      "nodes": [
        {
          "reportFormat": "NTIA",
          "score": 66.66666666666667,
          "scoreByCategory": [
            {
              "category": "Timestamp",
              "score": 100
            },
            {
              "category": "Supplier Name",
              "score": 0
            },
            {
              "category": "Unique ID",
              "score": 100
            },
            {
              "category": "Author",
              "score": 0
            },
            {
              "category": "Component Name",
              "score": 100
            },
            {
              "category": "Component Version",
              "score": 100
            },
            {
              "category": "Component Supplier Name",
              "score": 0
            },
            {
              "category": "Component Other unique identifiers",
              "score": 100
            },
            {
              "category": "Component Relationships",
              "score": 100
            }
          ],
        }
      ]
    }
  }
}

Version Status

After an sbom is uploaded to a version, various post-processing tasks are run. Tasks like vulnerability detection, automation and policies. All of these tasks have statuses associated with them, which can help determine if its the right time to download the SBOM.

STARTED and FINISHED are the only two statuses that are displayed.

query GetVersion($projectId: Uuid!, $versionId: Uuid!) {
  sbom(projectId: $projectId, sbomId: $versionId) {
    id
    vulnRunStatus
    automationRunStatus
    policyRunStatus
  }
}
{
  "projectId": "4f30f239-1058-4858-82f7-083aa5305e2d",
  "versionId": "f460ff4f-324f-4c9a-bafc-fdd76c9372e6"
}
{
  "data": {
    "sbom": {
      "id": "f460ff4f-324f-4c9a-bafc-fdd76c9372e6",
      "vulnRunStatus": "FINISHED",
      "automationRunStatus": "FINISHED",
      "policyRunStatus": "FINISHED"
    }
  }
}
Authentication
Endpoint
Requests
Pagination
Introspection
Search
Ordering
Use Cases
Interlynk's dashboard