OpenAPI Linting
OpenAPI Linting
Creating and publishing an OpenAPI spec of your Rest API is fundamental first step to documenting your API. An OpenAPI spec serves as both a convenient way to compose documentation for your API and a source for client code generation tools. Publicly published Trimble APIs are expected to have a properly formed and linted OpenAPI specification document.
OpenAPI spec documents are typically generated in one of two different ways. The most common method would be to use an embedded or add-on extension to your development environment and generate the OpenAPI spec from your API code. Teams can alternatively define an API using an OpenAPI spec and then generate server stub code to be implemented by developers. Check out the open source OpenAPI Generator for an example, and more information.
Ultimately our goal here is to make it easier for teams across Trimble to create high quality API products that are consistent and help result in a great customer experience.
Understanding the Guidelines
Trimble has created a basis for OpenAPI guidelines from multiple sources. We use the OpenAPI Specification and the Trimble HTTP API Standards as a starting point. We use Spectral from Stoplight for linting OpenAPI specs. We have a ruleset that extends the Spectral OAS base ruleset. We have further refined these rules base on feedback from several Trimble product teams and will continue to collaborate with teams to ensure quality, consistency and flexibility.
Linting OpenAPI specifications
As stated above, we maintain a Spectral ruleset that extends the OAS rules created by Stoplight (Spectral) and adds a set of rules built upon the Trimble API Standard. Access these rules via our GitHub repository. This repository contains instructions for installing and using Spectral with the Trimble ruleset. However, if you are already familiar with Spectral the following is a handy code snippet to quickly get started using our ruleset:
spectral lint ./openapi.yaml \ --ruleset https://raw.githubusercontent.com/trimble-oss/openapi-spectral-rules/main/spectral.yaml \ --format html > ./results.htmlSpecification Guidelines by Section
The following outlines the Trimble OpenAPI specification guidelines by specification section. OpenAPI Specifications have REQUIRED elements that are defined by the OpenAPI Initiative.
OpenAPI Version
OpenAPI specifications should be version 3.0.0 or later. We recommend version 3.1.0 or later.
"openapi": "3.1.0"Info Object :modus-solid-launch:{.icon-16}
Provides metadata about the API and is required by the OpenAPI Specification. Title and version are required by OAS
{ "title": "Trimble Service API", "version": "1.1"}We recommend that contact is included with valid support information (name and email). License and terms of service are recommend but not required. For license you may reference an existing license that covers you API, if you do not have an appropriate license you can exclude the license object.
"info": { "title": "TC API", "description": "The Trimble Connect API allows one to read, write and update...", "termsOfService": "https://connect.trimble.com/terms_of_service.html", "contact": { "name": "Trimble Connect Integrate Support", "url": "http://connect.trimble.com", "email": "connect-integrate@trimble.com" }, "license": { "name": "Trimble Connect API License", "url": "https://community.trimble.com/docs/DOC-10021" }, "version": "2.0" }You may include a copyright notice in the description such as:
© 2025, Trimble Inc. All rights reserved. Unauthorized copying prohibited. Software functions, including our APIs and their specification, are subject to change without notice. Information contained herein is Trimble Confidential Information, used under license.
Servers Array :modus-solid-launch:{.icon-16}
List of publicly accessible servers only - The specification will be published publicly and therefore servers should only contain a list of those servers that public consumers can access.
Description - Each server should have a description that describes what it is used for.
"servers": [ { "url": "http://api.trimblecloud.com/path" }]??? info “Servers Linting Rules” OpenAPI v3
Servers must be present and not empty
Servers should not point to example.com
Server url should not have a trailing slash
Paths :modus-solid-launch:{.icon-16}
Paths are synonymous with resource and should follow the Trimble HTTP API Standards.
Paths must begin with a forward slash ”/”
Example
"paths": { "/comments": {... }, "/comments/{commentId}": {... }, "/comments/{commentId}/attachments": {... }}??? info “Path Linting Rules” OpenAPI v2 & v3
Path must not include query strings
Operations :modus-solid-launch:{.icon-16}
Operations are child elements of the path object (resources). They are synonymous with actions in the Trimble HTTP API Standards and must be unique by verb (GET, POST, PUT, etc.).
Examples
"/comments/{commentId}": { "get": { "operationId": "view-comment-details" "summary": "View Comment Details", "description": "Get comment details for a specific comment by Id", ... }, "delete": { "operationId": "delete-comment" "summary": "Delete Comment", "description": "Delete a specific comment by Id", ... }, "patch": { "operationId": "update-comment", "summary": "Patch partially updates comment", "description": "Updates a portion of the specific comment", ... }},Both summary and description are required and should be spell- and grammar-checked.
- Summary - a high-level definition of the operation/action being defined.
- Description - a more in-depth description of what the object can be used for as well as any exceptions or specific information that helps the developer understand how to use the object in terms of their application development. Use markdown for richer representation.
- operationId - should be lower hyphen case and make sense for the operation.
??? info “Operation Linting Rules” OpenAPI v2 & v3
Operation must have a description
Operations must have at least one success response
Operation Id should be well formed
Operations should have a non-empty tag array
Operation tags should be defined in global tags
Parameter :modus-solid-launch:{.icon-16}
Parameter descriptions should not be repeated parameter names. Use as much text as needed to capture the following:
- What is unique about this parameter? The descriptions need to be generic for objects not specific to how the objects will be used based on the customer.
- How is it helpful to the developer?
- Is there a business context that would help the end-user/developer understand the purpose or significance of the parameter being described?
- Are there exceptions or caveats for any of the parameters?
- Are there any dependencies for any of the methods, calls, or parameters?
- Are there any min/max values?
- Are there default values?
- Are there any related functions or APIs? Should there be links to additional APIs?
- Can the description be reused from another parameter or call? Have you looked into creating a reusable definition list. Here’s a writeup from the OpenAPI spec about reusing parameters (why rewrite many times if you can write once, and reuse): Reusing Descriptions
- Have you run the linter against your spec? Linting with Spectral
- If you use industry-specific terms make sure you define them. For example, if you use an acronym, on first use, you should spell it out, for example, ERP (Enterprise Resource Planning)
- Do not use terminology that may not translate (use, “for example” as opposed to “ie”). When in doubt, use the most basic phrasing. Your audience may not be familiar with English and may not understand what you are trying to say
??? info “Parameter Linting Rules” OpenAPI v3
Parameters must have a description
OpenAPI v2 & v3Parameters must be unique and non-repeating
Parameters must be correct and valid
Responses :modus-solid-launch:{.icon-16}
Responses should be complete and have sample code that can be interpreted for the operation being outlined.
Descriptions are required by the OpenAPI spec and can contain markdown for a richer text representation.
The Trimble Web API Standards outline best practices for defining response. All possible response, both success and failure, should documented in your OpenAPI spec.
??? info “Response Linting Rules” OpenAPI v2 & v3
Operations must have at least one success response
Components :modus-solid-launch:{.icon-16}
The components object is unique from the other objects in the OpenAPI specification. In components, you store re-usable definitions that might appear in multiple places in your specification document.
The components object can store definitions for many types of objects.
"components": { "schemas": {}, "responses": {}, "parameters": { "limit": { "name": "limit", "in": "query", "description": "Specifies the maximum number of items to include in...", "required": false, "style": "form", "explode": true, "schema": { "type": "integer", "default": 20 } }, "offset": { "name": "offset", "in": "query", "description": "Specifies the number of items to skip before...", "required": false, "style": "form", "explode": true, "schema": { "type": "integer", "default": 0 } } }, "examples": {}, "requestBodies": {}, "headers": {}, "securitySchemes": {}, "links": {}, "callbacks": {}, "pathItems": {}}Reference the component definition throughout you spec document using the $ref tag
"/orders/{orderId}/consignee": { "get": { "summary": "Retrieve order consignee information", "description": "Retrieves the consignee information record for...", "operationId": "OrdersGetConsignee", "security": [], "tags": [], "parameters": [ { "$ref": "#/components/parameters/limit" }, { "$ref": "#/components/parameters/offset" }, ], "responses": {} }}??? info “Component Linting Rules” OpenAPI v2 & v3
Security :modus-solid-launch:{.icon-16}
Add one or more security schemes to the component object and a security array of support schemes to your spec operations.
Define security schemes in the root of your spec
"components": { ... "securitySchemes": { "tidJwtAuth": { "type": "http", "description": "A time-limited JSON Web Token generated...", "scheme": "bearer" }, "webuserJwtAuth": { "type": "http", "description": "A fresh JSON Web Token expires in four hours...", "scheme": "bearer" }, "clientApiKeyAuth": { "type": "http", "description": "Client API Key", "scheme": "bearer" }, "truckmateApiKeyAuth": { "type": "http", "description": "TruckMate API Key", "scheme": "bearer" }, "vendorApiKeyAuth": { "type": "http", "description": "Vendor API Key", "scheme": "bearer" } } ...}Add supported security schemes to the security array for each operation
"/orders/{orderId}/consignee": { "get": { "summary": "Retrieve order consignee information", "description": "Retrieves the consignee information record...", "operationId": "OrdersGetConsignee", "security": [ { "tidJwtAuth": [] }, { "truckmateApiKeyAuth": [] }, { "webuserJwtAuth": [] } ], "tags": [ ], "parameters": [ ], "responses": { } }}Tags :modus-solid-launch:{.icon-16}
We need to have a consistent way that the APIs are grouped so that as developers move from one API spec to the next, it provides the same high-level organization between APIs.
Encouraged Approach
- Plural Noun - Industry specific plural term.
Do Not
- Use a singular noun
- Use additional strings such as “API”, “Endpoints”, “Management”, etc.
Additional Linting Rules
The following are linting rules that do not easily fit into any of the above sections.
OpenAPI v3
Example for request body or response can have externalValue or value but not both
Validate structure of OpenAPI specification
OpenAPI v2 & v3
No $ref siblings (prior to v3.1)
Enums must not have duplicate values
References
For a visual representation of some OpenAPI objects, see this page about the OpenAPI object tutorial.