Accessing Altium 365 design data

Modified on Fri, 29 Jul 2022 at 07:52 PM

The Nexar API is a GraphQL based API for accessing the Altium ecosystem, including supply chain data from Octopart, design data from Altium 365 and manufacturing services from Altimade.

This guide is a quick guide to accessing design data in the Nexar API. It uses the Banana Cake Pop IDE for most of the examples and shows off some of the query capabilities of the API. It is not exhaustive, nor a complete reference, but designed to get you started, quickly.

This guide assumes you are familiar with Altium 365 and that you are a member of at least one workspace.

Step 1: Nexar Accounts

Nexar.com is the home of Nexar on the web. Today, we have a simple portal that you can go to to get started with the Nexar API.

Navigate to the landing page and click on the “Sign In” link.

This will redirect you to the Nexar identity server to authenticate you:

Sign in with your Altium 365 credentials. These credentials are the same as your Altium Live credentials, which are a common set of credentials used across Altium’s digital properties, Nexar included.

The first time you sign in to Nexar, you will need to create an organization (unless you have already been invited to join one in which case you’ll skip this step). Give your organization a name:

Click create and you’ll be logged into the portal:

Step 2: Nexar Applications

Applications are a fundamental concept in Nexar - you need an application to be able to interact with the API. The application essentially provides an “identity” to the API - whenever an API call is made, it is in the context of an application. Things like query limits, scopes (what API endpoints the application is authorized to call), etc. are part of the application definition and configuration.

Before you query the API, you will need to create an application. Click on the “Click to Create Application” button:

Enter some details for the application, including a name and a description, and only enable the “Design” scope as we will only be querying design data with this application:

You will get a confirmation dialog:

The application will show up in your dashboard. Click the “Manage applications” link or the “Applications” menu item to go to the list of applications:

You can create a maximum of 3 applications at present.

Click on the “Show Details” button on an application to take a peek inside:

The application details page show you various information about the application:

You can:

  • Find the Client ID and Client Secret (needed for OAuth2 flow)

  • Configure redirect URLs (part of Authorization Code OAuth2 flow)

  • Generate time limited OAuth2 access token for API access

  • Run examples and get access to source code on GitHub

Step 3: The Banana Cake Pop IDE

The Nexar API is built on top of an open source GraphQL server called Hot Chocolate. There is a built-in IDE called Banana Cake Pop, or BCP for short. This is a really powerful web based IDE for running queries.

Go to https://api.nexar.com/graphql to access the IDE:

To learn how to configure this to use your Nexar application credentials visit the FAQ for using OAuth2 with the Nexar/BCP IDE. If there is no error from the ‘Fetch Token’ action the IDE is ready for the next step.

BCP will authenticate. You may be asked to login as below, but this will likely not happen if you are already logged into nexar.com:

BCP will now be authenticated using your application details, and crucially, the user details that you are logged into nexar.com with. This is important to understand - the application is working on behalf of you, the user, and when you query the design API, you are querying data based on what you have access to!

Authentication tokens used by Nexar will be valid for 24 hours. After that time the queries in the rest of this guide will produce a response similar to this:

When you see this simply go back to the connection settings and click on fetch token to re-authorize BCP.

Step 4: Running Queries

Now that we have BCP authenticated, you are ready to start executing some queries. GraphQL provides an introspection capability that means the IDE has a full understanding of the Nexar API schema, so we get really nice things like intellisense style code suggestions and autocomplete. Use <ctrl>space to trigger a list of code options that fit in the context of the current line position as shown below:

The first query we are going to run is to get a list of our workspaces. Type out the following query to see it in action, or simple copy and paste the below into the document tab:

query GetWorkspaces {
  desWorkspaces {
    name
    description
    url
    location {
      apiServiceUrl
    } 
  }
}


Click the “Execute” link to run the query:

This query has asked for the workspace name, description and URL, and returned it in the response:

That’s it! We’ve completed our first query!

Get Projects in a Workspace

After getting a list of workspaces, we can then create another query to get a list of projects in a specific workspace. Construct a query like that shown below - you’ll need to provide your own URL. We are going to use the result from the previous GetWorkspaces query here.

Before executing the query, we are going to change the GraphQL query endpoint to the optimal query endpoint, the “apiServiceUrl”, returned in the GetWorkspaces query. Click the settings icon and change the Schema Endpoint:

Note that we don’t have to do this - we could continue using the api.nexar.com/graphql endpoint and it will work. The reason we change it is so that we get the best performance, as the workspace data is hosted in the region that we are connecting to, so we don’t end up with unnecessary latencies.

Type the following query and execute it:

query GetProjects {
  desProjects(workspaceUrl: "https://solvethirteen.365.altium.com/") {
    nodes {
      id
      name
      description
    }
  }
}


You’ll get results like the following:

Note in this query we have the fields we want to query wrapped in this strange “nodes” element. This is because this query uses cursor based paging. For queries that will potentially return large amounts of data, we use paging to make things efficient such that we return smaller chunks of data, and only the data we are interested in.

Let's take a close look at what we can do. Change the query to be the same as below:

query GetProjects {
  desProjects(workspaceUrl: "https://solvethirteen.365.altium.com/") {
    totalCount
    pageInfo {
      hasNextPage
      hasPreviousPage
      startCursor
      endCursor
    }
    nodes {
      id
      name
      description
    }
  }
}


Then take a look at the result:

{
  "data": {
    "desProjects": {
      "totalCount": 49,
      "pageInfo": {
        "hasNextPage": true,
        "hasPreviousPage": false,
        "startCursor": "MA==",
        "endCursor": "OQ=="
      },
      "nodes": [
        {


Here, we now have the total number of items which is 49, and we have cursor information telling us the beginning and end of the page.

Let’s adjust the query to get the next page:

query GetProjects {
  desProjects(workspaceUrl: "https://solvethirteen.365.altium.com/", after: "OQ==") {
    totalCount
    pageInfo {
      hasNextPage
      hasPreviousPage
      startCursor
      endCursor
    }
    nodes {
      id
      name
      description
    }
  }
}


Here we have said “Give me the projects after the page “OQ==” and that is exactly what we got back. Note, if you have less than 10 projects in your workspace, everything will fit in one page and the above query will return nothing

Get a Project By Name

We can also build a query to get a specific project by name:

query GetProject {
  desProjects(workspaceUrl: "https://solvethirteen.365.altium.com/",
    where: {name: {eq: "AltimadeTest01"}}) {
    nodes {
      id
      name
      description
    }
  }
}


Here we use the “Where” clause to specify the name of the project. The response will be something like:

{
  "data": {
    "desProjects": {
      "nodes": [
        {
          "id": "RGVzUHJvamVjdApkaHR0cHM6Ly9zb2x2ZXRoaXJ0ZWVuLjM2NS5hbHRpdW0uY29tL3xEOTkwN0QwQy1EQjI3LTRDNDgtODdDMi02MTZDMzgxMTA3OTV8MA==",
          "name": "AltimadeTest01",
          "description": ""
        }
      ]
    }
  }
}


Get Project By Id

In the previous query we got an ID for a project. This next query will drill down into the data model to show just how much information can be obtained from the design. Let’s start with a basic query that queries by ID:

query GetProjectById {
  desProjectById(id: "RGVzUHJvamVjdApkaHR0cHM6Ly9zb2x2ZXRoaXJ0ZWVuLjM2NS5hbHRpdW0uY29tL3xEOTkwN0QwQy1EQjI3LTRDNDgtODdDMi02MTZDMzgxMTA3OTV8MA==") {
    name
    description
  }
}


The result we get will be something like:

{
  "data": {
    "desProjectById": {
      "name": "AltimadeTest01",
      "description": ""
    }
  }
}


Get PCB Nets and Pads

Example query for getting nets and pads:

query GetDesignInfo {
  desProjectById(id: "RGVzUHJvamVjdApkaHR0cHM6Ly9zb2x2ZXRoaXJ0ZWVuLjM2NS5hbHRpdW0uY29tL3xEOTkwN0QwQy1EQjI3LTRDNDgtODdDMi02MTZDMzgxMTA3OTV8MA==") {
    name
    description
    design {
      workInProgress {
        variants {
          pcb {
            nets {
              name
              cumulativeLength {
                xMm
              }
            }
            pads {
              radius
              holeSize {
                xMm
              }
              position {
                xMm
                yMm
              }
            }
          }
        }
      }
    }
  }
}


Get PCB Comments

Example query for getting components on the PCB:

query GetDesignInfo {
  desProjectById(id: "RGVzUHJvamVjdApkaHR0cHM6Ly9zb2x2ZXRoaXJ0ZWVuLjM2NS5hbHRpdW0uY29tL3xEOTkwN0QwQy1EQjI3LTRDNDgtODdDMi02MTZDMzgxMTA3OTV8MA==") {
    name
    description
    design {
      workInProgress {
        variants {
          pcb {
            commentThreads {
              comments {
                text
              }
            }
          }
        }
      }
    }
  }
}


Get BOM

Example query for getting BOM information:

query GetDesignInfo {
  desProjectById(id: "RGVzUHJvamVjdApkaHR0cHM6Ly9zb2x2ZXRoaXJ0ZWVuLjM2NS5hbHRpdW0uY29tL3xEOTkwN0QwQy1EQjI3LTRDNDgtODdDMi02MTZDMzgxMTA3OTV8MA==") {
    name
    description
    design {
      workInProgress {
        variants {
          bom {
            bomItems {
              bomItemInstances {
                isFitted
                designator
              }
              component {
                name
                details {
                  symbols {
                    imageThumbnailUrl
                  }
                  footprints {
                    imageThumbnailUrl
                  }
                }
                manufacturerParts {
                  companyName
                  partNumber
                  supplierParts {
                    companyName
                    partNumber
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}


Get Component Library

The component library is paged. Here is any example query:

query GetLibrary {
  desLibrary(workspaceUrl: "https://solvethirteen.365.altium.com/") {
    components {
      nodes {
        name
        comment
        description
        manufacturerParts {
          companyName
          partNumber
          priority
        }
        details {
          parameters {
            name
            value
            type
          }
          symbols {
            imageThumbnailUrl
          }
          footprints {
            imageThumbnailUrl
          }
        }
      }
    }
  }
}


And a fragment from the response:

{
            "name": "CMP-00114-1",
            "comment": "0603YD334KAT2A",
            "description": "CAP,.33UF,16V,X5R,10%,SMD, 0603,TR<AZ",
            "manufacturerParts": [
              {
                "companyName": "Kyocera AVX",
                "partNumber": "0603YD334KAT2A",
                "priority": 0
              }
            ],
            "details": {
              "parameters": [
                {
                  "name": "Case Code (Metric)",
                  "value": "1608",
                  "type": "TEXT"
                },
                {
                  "name": "Mount",
                  "value": "Surface Mount,PCB",
                  "type": "TEXT"
                },
                {
                  "name": "Tolerance",
                  "value": "10%",
                  "type": "TEXT"
                }
              ],
              "symbols": [
                {
                  "imageThumbnailUrl": "https://ccv-eu.s3.eu-central-1.amazonaws.com/…"
                }
              ],
              "footprints": [
                {
                  "imageThumbnailUrl": "https://ccv-eu.s3.eu-central-1.amazonaws.com/…"
                },
                {
                  "imageThumbnailUrl": "https://ccv-eu.s3.eu-central-1.amazonaws.com/…"
                },
                {
                  "imageThumbnailUrl": "https://ccv-eu.s3.eu-central-1.amazonaws.com/…"
                }
              ]
            }
          },

 

Summary and Resources

As you can see, the Nexar API is really flexible and powerful, allowing you to build your own queries and get access to the things that you are interested in.

Here are some further resources:

Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select atleast one of the reasons

Feedback sent

We appreciate your effort and will try to fix the article