Harness API

Updated 3 days ago by Michael Katz

Harness' public GraphQL API unlocks the Harness Continuous Delivery platform, enabling you to build third-party applications that leverage Harness' power to meet your needs. This topic gets you started with our API by covering:

See Next Steps for links to our Secrets Management APIs.

Intended Audience

  • Developers
  • Account Administrators
  • DevOps

Harness Your Way

Using our public API, you can build applications that customize Harness' power to suit your organization's (or your customers') needs. Your applications' queries can return a rich selection of Harness setup parameters and runtime data.

Virtually all of Harness' meaningful entities are exposed through the API: Applications, Services, artifacts, Cloud Providers, Environments, Workflows, Pipelines, deployed instances, deployment data, etc.

Why GraphQL

Harness exposes its public API in GraphQL format. GraphQL offers these efficiency and reliability features for your consuming applications:

  • Scoping – Each request can query for all the resources and data you want, and only the data you want.
  • Introspection – Your client applications can query the API schema for details about the API.
  • Hierarchical Organization – Your queries' nested fields mirror the organization of the JSON data that the queries return.
  • Strong Typing – Applications can specify expected data types per field, and receive clear and specific error notifications.
  • Future-Proofing – GraphQL allows us to incrementally expose new fields and types, and retire obsolete fields, without versioning the API or breaking your existing queries.

For comparisons of GraphQL to REST, and for related resources, please see Facebook's GraphQL.org site (which includes links to client libraries) and GitHub's v4 API orientation.

API Explorer

Harness' API is largely self-documenting. You can use the Harness API Explorer to examine the API's structure, to build and test queries against your data, and to optimize your queries.

The Harness API Explorer is intended primarily as a testing tool. When you're ready to build your queries into working code, see Building Applications below.

To get started: In Harness Manager, select Setup > Harness API Explorer.

This displays the Harness API Explorer shown below.

Harness' API Explorer is based on the GraphiQL IDE. For general instructions on using this GraphiQL explorer, please see GitHub's documentation.

You're now ready to query the API.

Querying the API

Curious to see what kinds of data your applications can obtain? You can easily explore the API schema's nested fields and properties, using these options:

Use Our Sample Queries

Adapt one of the sample queries below into the API Explorer's query pane, and click Run. (Click highlighted keywords to link to descriptions in the right Documentation Explorer pane.)

Traverse or Search the Schema

Click Query in the Documentation Explorer pane to see top-level API objects. Or, type field or property names into the Documentation Explorer's search box to see child properties.

Authentication

Your authentication determines what data you can query and retrieve via the API. By default, when you open the API Explorer, you authenticate using a session key:

As outlined just below, authenticating with an alternative key can provide access to a different scope of data.

Switch Keys (Administrators)

Members of your Account Administrator User Group can use the Authentication drop-down list to select a different API key from your Harness account:

Enter Keys (Non-Administrators)

Non-administrators (with appropriate access) can authenticate using an alternative API key as follows:

  1. Obtain the key from your organization, and copy it to your clipboard, as outlined in API Keys.
  2. In the API Explorer, select Authentication > Use API Key:
  3. In the resulting dialog, paste the key from your clipboard into the API Key field:
  4. Click SUBMIT. The key is now active, and is displayed in the Authentication drop-down.
To query the Harness API in your custom applications, your working code must pass an appropriate API Key from your Harness account as an x-api-key header. See Building Applications, below.

Building Applications

This section outlines how to use Postman (version 7.2 or higher) to run a GraphQL query, and to automatically regenerate your query in any programming language that Postman supports.

Query Harness GraphQL in Postman

This section shows how to transfer a GraphQL query from the Harness API Explorer to Postman. You'll copy and paste your Harness account ID, API Key, and the query itself.

  1. Copy your Harness account ID from your browser's address bar.
  2. In Postman, set up a POST request of this form, ending in your Harness account ID: https://app.harness.io/gateway/api/graphql?accountId=<your-harness-account-id>

    For on-prem installations, substitute your organization's subdomain and domain, in this form:
    https://harness.<your-domain>/gateway/api/graphql?accountId=<your-harness-account-id>\

    For example:
    https://harness.bigcompany.com/gateway/api/graphql?accountId=<your-harness-account-id>
  3. Select Postman's Authorization tab.
  4. Set the Type drop-down to API Key.
  5. In the resulting right panel, set the Key to x-api-key.
  6. From Harness Manager, copy your API key's value to your clipboard, as outlined in API Keys.
  7. In Postman's right panel, paste this value into the Value field. (Accept the Add to: Header default.)

    Your Postman setup will now look something like this:
  8. In the Harness API Explorer, click COPY to grab your query.
  9. In Postman, select the Body tab > GraphQL radio button.
  10. Paste your query into Postman's QUERY box.
  11. Click Send to run the query. Verify the response in the response Body panel below.

Build Language-Specific Queries in Postman

Here is how to convert your query into your programming language of choice. We assume that you've already pasted your GraphQL query into Postman's QUERY box.

  1. In Postman, select the raw radio button (not the GraphQL radio button).
  2. Select Postman's Code tab.
  3. In the resulting GENERATE CODE SNIPPETS window, select your target language from the drop-down at upper left. This displays the generated snippet for that language.
  4. Click Copy to Clipboard.
  5. Paste and verify the translated query in your chosen environment.

API Schema and Structure

Harness' schema determines what parameters your queries can specify as arguments, and what data we can return.

Following GraphQL conventions, we represent our schema in terms of fields, types, enums, nodes, edges, and connections.

Where a ! character appears at the end of a parameter's name, this indicates a required parameter.

For details about GraphQL's structure and conventions, please see Facebook's and GitHub's GraphQL overviews.

Fields

The Harness API's schema includes fields representing the following Harness entities. Note that many of these <entityId> or <entity> fields are also transformed within the schema into an <entity>Aggregation, <entity>Connection, and/or <entity>Filter. Use the API Explorer's search box to discover the available fields and their usage.

Field Name

Harness Entity/Notes

applicationId

Harness Application.

serviceId

Harness Service.

environmentId

Harness Environment.

workflowId

Harness Workflow.

pipelineId

Harness Pipeline.

executionId

A Harness deployment (execution).

artifactId

Artifact deployed via Harness.

cloudProviderId

Cloud Provider configured in Harness.

Instance

Instance deployed via Harness.

connectorId

Connector configured in Harness.

description

Description of a Workflow, Pipeline, etc.

id

Unique ID of a Harness entity.

name

Name of a Workflow, Pipeline, etc.

total

Total number of a parent Harness entity.

status, ExecutionStatus

Deployment's execution status.

createdAt

Time when deployment was queued in Harness.

startedAt

Time when deployment's execution began.

TimeSeriesAggregation

Used to group returned statistics (on deployments, instances, etc.) by time.

TriggerFilter

One or more Harness Triggers.

limit

Pagination throttler.

offset

Pagination pointer.

Sample Queries: Basic

The following examples show some common basic queries that your applications can execute against the Harness API.

Fetch the List of Services for a Given Application

This sample queries by applicationId to return id and name values for up to 1,000 Services.

{
services(
filters: [
{ application: { operator: EQUALS, values: ["<applicationId>"] } }
]
limit: 1000
) {
pageInfo {
total
}
nodes {
id
name
}
}
}

Show Executions for a Given Workflow

This sample queries by workflowId to return up to 30 deployments.

{
executions(
filters: [
{ workflow: { operator: EQUALS, values: ["<workflowId>"] } }
]
limit: 30
) {
pageInfo {
total
}
nodes {
id
}
}
}

Show Execution Details

This sample retrieves rich details on the parameters and results of (up to) 100 recent executions.

{
executions(limit: 100) {
pageInfo {
limit
offset
total
}
nodes {
id
application {
id
name
}
status
cause {
... on ExecutedByUser {
user {
email
}
}
... on ExecutedByTrigger {
trigger {
id
name
}
}
}
... on PipelineExecution {
pipeline {
id
name
}
}
... on WorkflowExecution {
workflow {
id
name
}
outcomes{
nodes{
... on DeploymentOutcome{
service{
id
name
}
environment{
id
name
}
}
}
}

}
}
}
}

Fetch a list of Pipelines

This example iterates through Pipelines—using specified limit and offsetvalues—to return basic details.

{
pipelines(limit: 20, offset: 20) {
nodes {
id
name
description
createdAt
}
pageInfo {
total
}
}
}

Show Details about a Pipeline

This example returns basic information about a specified Pipeline. It corresponds to a GET operation in a REST API.

{
pipeline(pipelineId: "<pipelineId>") {
id
name
description
}
}

Show Deployments for a Given Pipeline

This sample queries by pipelineId to return details on up to 3 deployments.

{
executions(
filters: [{ pipeline: { operator: EQUALS, values: ["<pipelineId>"] } }]
limit: 3
) {
pageInfo {
total
}
nodes {
id
}
}
}

Show Pipelines for a Given Application

This sample queries by applicationId to return details about corresponding Pipelines.

{
pipelines(
filters: [
{ application: { operator: EQUALS, values: ["<ApplicationID>"] } }
]
limit: 5
offset: 2
) {
nodes {
id
name
description
createdAt
}
pageInfo {
total
}
}
}

Show Services for a Given Application

This nested query by applicationId returns the names of the specified Application's contained Services.

{
application(applicationId:"<applicationId>") {
services(limit:100, offset:0) {
pageInfo{
total
}
nodes{
name
}
}
}
}

Paginating Results

Several sample queries above specify pagination for large result sets. Here's a simplified excerpt:

{
pipelines(
...
limit: 5
offset: 2
)
...

You can specify pagination criteria as follows:

  • limit is a throttler, specifying how many results to return per page.
  • offset is an index from 0.

Using Nodes and IDs

Where a query returns a list of multiple objects, each returned object is treated as a GraphQL node. Several of the above sample queries use nodes sub-elements to reference, or iterate through, individual objects in your results. Here is an example:

 nodes {
id
name
description
createdAt
}

As arguments, several of the above sample queries take an Application ID (applicationId,) User ID (userIds), or User Group ID (userGroupId). As outlined just below, you can obtain these IDs via the API itself, using Harness' by-name queries.

Retrieving IDs by Name

You can easily retrieve applicationId, userIds, and userGroupId object IDs by using (respectively) the applicationByName, userByName, and userGroupByName operations. Each of these queries takes a required name argument, as a string.

Below is a sample query for each of these retrieval operations, followed by a round-trip example of looking up an ID by name and then passing it as an argument to a second query.

Fetch Application ID by Name

This sample retrieves the applicationId for a named Harness Application.

{
applicationByName(name:"Harness Sample App") {
id
}
}

Fetch User ID and Details by Name

This sample retrieves the userGroupId value for a named Harness User, and also confirms the user's name and email verification status.

{
userByName(name:"Admin"){
name
id
isEmailVerified
}
}

Fetch User Group ID by Name

This sample retrieves the userGroupId value for a named Harness User Group, and also confirms the group's name.

{
userGroupByName(name:"Account Administrator"){
name
id
}
}

Round-Trip Example

After using one of the above queries to obtain an object's ID, you can pass this ID to queries that require an ID argument.

In this example, we first query for an Application's ID:

{
applicationByName(name:"Harness Sample App") {
id
}
}

This returns something like this:

{
"data": {
"applicationByName": {
"id": "xkZzxocSQ3-ne2m92mUVQw"
}
}
}

We can now use the returned id as the applicationId argument in a query for this Application's list of Workflows:

{
workflows(filters: {application: {values: ["xkZzxocSQ3-ne2m92mUVQw"], operator: IN}}, limit: 5) {
nodes {
id
name
createdAt
}
}
}

This returns something like this:

{
"data": {
"workflows": {
"nodes": [
{
"id": "xqZzrmcSQ3-ne2m53mUVQw",
"name": "Verification Service-simple",
"createdAt": 1582246743673
},
{
"id": "iPLNQBZATYKEB9Lgx_JyJQ",
"name": "Redis Sentinel PR",
"createdAt": 1581945346231
}
]
}
}
}

Query Variables

Using the Harness API Explorer, you can test the use of variables for your production code. Define your variables in the API Explorer's QUERY VARIABLES pane, and call them in the query pane.

As a simple example, here is a revision of the Show Details about a Pipeline sample query above. Here, we pass the required pipelineId argument as a variable named $thisPipeline:

Where a ! character appears at the end of a parameter's name, this indicates a required parameter.

Here is the revised query, incorporating the new variable:

query($thisPipeline: String!) {
pipeline(pipelineId: $thisPipeline) {
id
name
description
}
}

Here is the format for passing the value in the QUERY VARIABLES pane:

{
"thisPipeline": "<pipelineId>"
}

For background information on query variables, see GraphQL.org's Queries and Mutations documentation. For details about the syntax shown above, see GraphQL.org's How to Pass Variables in GraphiQL Quick Tip.

Sample Queries: Create/Update Applications

The following examples show how to create and update Harness Applications using API calls.

Where a ! character appears at the end of a parameter's name, this indicates a required parameter.

Create Application

This sample creates an Application in Harness. It returns an id, which you can use as the applicationId value in other Application operations below.

mutation createapp($app: CreateApplicationInput!) {
createApplication(input: $app) {
clientMutationId
application {
name
id
}
}
}

Here are sample query variables for the above operation. The name variable requires a value, which must be unique in your Harness account.

{
"app": {
"clientMutationId": "req9",
"name": "AMI App",
"description": "Application to deploy AMIs"
}
}

Values for other variables are optional. In this and other mutation requests, a clientMutationId is needed only when multiple clients make updates to the same entity, and each client needs a way to identify the request-response. In this case, each update should supply an arbitrary, unique clientMutationId.

Update Application

This sample updates an existing Application.

mutation updateApp($app: UpdateApplicationInput!) {
updateApplication(input: $app) {
clientMutationId
application {
name
id
description
}
}
}

Here are sample query variables for the above operation. You must supply an applicationId, corresponding to an existing Harness Application.

{
"app": {
"clientMutationId": "req9",
"applicationId": "1YO5rmoaTdSyqnfvLOgb7g",
"name": "AMI App",
"description": "Deploy AMIs with a better description"
}
}

Enable Git Sync for an Application

This sample enables Git sync on a Harness Application.

mutation updateGitConfig($gitConfig: UpdateApplicationGitSyncConfigInput!) {
updateApplicationGitSyncConfig(input: $gitConfig) {
clientMutationId
gitSyncConfig {
branch
syncEnabled
gitConnector {
id
name
description
createdAt
createdBy {
id
name
}
}
}
}
}

Here are sample query variables for the above operation. You must supply an applicationId corresponding to an existing Harness Application, and a gitConnectorId corresponding to an existing Git Connector on your Harness account.

{
"gitConfig": {
"clientMutationId": "req321",
"applicationId": "1YO5rmoaTdSyqnfvLOgb7g",
"gitConnectorId": "YF6tO-SRTHmoZsfg8NCNyA",
"branch": "temp_branch",
"syncEnabled": true
}
}

Sample Queries: Users, Groups, Permissions

The following examples show how to create Harness users and User Groups, and how to assign permissions, using API calls.

Create User

This sample creates a user in your Harness account, and assigns the user to up to five Harness User Groups.

mutation createUser($user: CreateUserInput!) {
createUser(input: $user) {
user {
id
email
name
userGroups(limit: 5) {
nodes {
id
name
}
}
}
clientMutationId
}
}

Here are sample query variables for the above operation. Values are required for the email, name, and userGroupIds variables.

{
"user": {
"name": "Joyce Silva",
"email": "jsilva@example.com",
"clientMutationId": "ssdsdsecved",
"userGroupIds": ["7mejLPDtRvOCF8K3roIEVg"]
}
}

Create Group

This sample creates a User Group in your Harness account, and (optionally) assigns users to the new group.

mutation($userGroup: CreateUserGroupInput!){
createUserGroup (input:$userGroup) {
userGroup {
id
name
description
isSSOLinked
importedByScim
users(limit: 190, offset: 0) {
pageInfo {
total
}
nodes {
name
email
}
}
notificationSettings {
sendNotificationToMembers
sendMailToNewMembers
slackNotificationSetting {
slackChannelName
slackWebhookURL
}
groupEmailAddresses
}
}
}
}

Here are sample query variables for the above operation. The name variable requires a value, which must be unique in your Harness account.

{
"userGroup": {
"name" : "Notification",
"userIds": ["SArz5MsSS8y2PNbwhc8INw","W_zq_nwvTCm50wX3cI6Nhw","Pbx8egtqTMCClUGNg00PTw"]
}
}

Assign Permissions

This sample assigns permissions to Harness User Groups.

mutation($userGroup: UpdateUserGroupPermissionsInput!){
updateUserGroupPermissions (input:$userGroup) {
permissions {
accountPermissions{
accountPermissionTypes
}
appPermissions {
permissionType
applications {
filterType
appIds
}
services {
filterType
serviceIds
}
environments {
filterTypes
envIds
}
workflows {
filterTypes
envIds
}
deployments {
filterTypes
envIds
}
pipelines {
filterTypes
envIds
}
provisioners {
filterType
provisionerIds
}
actions
}
}
}
}

Here are sample query variables for the above operation. A value is required for the userGroupId variable.

{
"userGroup": {
"userGroupId": "KYppi5LjSdCYH8DLT34exA",
"permissions": {
"accountPermissions": {
"accountPermissionTypes": ["READ_USERS_AND_GROUPS","MANAGE_USERS_AND_GROUPS","MANAGE_TAGS","ADMINISTER_OTHER_ACCOUNT_FUNCTIONS","MANAGE_TEMPLATE_LIBRARY","VIEW_AUDITS"]
},
"appPermissions": [
{
"permissionType": "ALL",
"applications": {
"appIds": ["A0M4nZJJTQekFfp4lX71Zw","g7sJZKmMRd-oHWdjsjF0ZQ"]
},
"actions": ["CREATE","DELETE","READ","UPDATE"]
},
{
"permissionType": "SERVICE",
"applications": {
"filterType": "ALL"
},
"services": {
"filterType": "ALL"
},
"actions": ["CREATE","DELETE","READ","UPDATE"]
},
{
"permissionType": "ENV",
"applications": {
"appIds": ["A0M4nZJJTQekFfp4lX71Zw","g7sJZKmMRd-oHWdjsjF0ZQ"]
},
"environments": {
"envIds": ["hRCUcsHmSPaHA7LXKzosAw","m7d7Kg2TQlKrrlbcnPUY5A"]
},
"actions": ["READ","UPDATE"]
}
]
}
}
}

The JSON above sets three sets of permissions, which we can break down. This first permission enables the User Group's members to perform all four CRUD operations on two Applications, specified by appIds:

{
"permissionType": "ALL",
"applications": {
"appIds": [
"A0M4nZJJTQekFfp4lX71Zw",
"g7sJZKmMRd-oHWdjsjF0ZQ"
]
},
"actions": ["CREATE", "DELETE", "READ", "UPDATE"]
}

This second element grants permission to perform all CRUD operations on all Services, across all Applications:

 {
"permissionType": "SERVICE",
"applications": {
"filterType": "ALL"
},
"services": {
"filterType": "ALL"
},
"actions": ["CREATE", "DELETE", "READ", "UPDATE"]
}

Finally, this third element grants permission to perform the specified operations on the specified Environments:

{
"permissionType": "ENV",
"applications": {
"appIds": [
"A0M4nZJJTQekFfp4lX71Zw",
"g7sJZKmMRd-oHWdjsjF0ZQ"
]
},
"environments": {
"envIds": [
"hRCUcsHmSPaHA7LXKzosAw",
"m7d7Kg2TQlKrrlbcnPUY5A"
]
},
"actions": ["READ","UPDATE"]
}

Notes on updateUserGroupPermissions

Beyond the userGroupId requirement, note these usage details for the updateUserGroupPermissions operation:

  1. This API completely overwrites any permissions previously set for the specified User Groups.
  2. To scope the Harness Applications on which you are granting permission, you should either supply specific appIds, or supply a filterType.
  3. You cannot set the MANAGE_USERS_AND_GROUPS permission without first setting READ_USERS_AND_GROUPS.

Sample Queries: Audit Trails

The following examples show common audit trail queries.

Generic Change Set

This query shows how to retrieve the 100 most recent audit records and generic change set information.

{
audits(limit: 100, offset: 0) {
nodes {
id
changes {
appId
resourceName
operationType
}
triggeredAt
... on GenericChangeSet {
request {
resourcePath
remoteIpAddress
responseStatusCode
}
}
}
}
}

User Change Set

This query shows how to retrieve the 100 most recent audit records and user change set information.

{
audits(limit: 100, offset: 0) {
nodes {
id
changes{
appId
resourceName
operationType
}
triggeredAt
request{
resourcePath
remoteIpAddress
responseStatusCode
}
... on UserChangeSet {
triggeredBy {
name
id
userGroups(limit: 5, offset: 0) {
nodes {
name
}
}
}
}
}
}
}

API Key Change Set

This query shows how to retrieve the 100 most recent audit records and API key change set information.

{
audits(limit: 100, offset: 0) {
nodes {
id
changes {
appId
resourceName
operationType
}
triggeredAt
request {
resourcePath
remoteIpAddress
responseStatusCode
}
... on ApiKeyChangeSet {
id
apiKeyId
changes {
createdAt
resourceName
resourceType
}
}
}
}
}

Git Change Set

This query shows how to retrieve the 100 most recent audit records and Git change set information.

{
audits(limit: 100, offset: 0) {
nodes {
id
changes {
appId
resourceName
operationType
}
triggeredAt
request {
resourcePath
remoteIpAddress
responseStatusCode
}
... on GitChangeSet{
gitCommitId
author
repoUrl
}
}
}
}

Other Examples

The audits API enables you to retrieve and export records from Harness' Audit Trail. This first sample query has no time filters.

{
audits(limit:5){
nodes{
id
triggeredAt
request{
url
resourcePath
requestMethod
remoteIpAddress
requestMethod
}
changes{
appId
appName
operationType
}
}
pageInfo{
hasMore
limit
total
offset
}
}
}

This second query shows filtering by a specific time range (UNIX epochs).

{
audits(
filters:{
time: {
specific:{
from:1577567777550
to: 1577567829417
}
}
}
limit:20){
nodes{
id
triggeredAt
request{
url
resourcePath
requestMethod
remoteIpAddress
requestMethod
}
changes{
appId

resourceId
appName
operationType
}
}
pageInfo{
hasMore
limit
total
offset
}
}
}

This third query demonstrates filtering by a relative time offset.

{
audits(
filters:{
time: {
relative:{
timeUnit:WEEKS
noOfUnits: 2
}
}
}
limit:20){
nodes{
id
triggeredAt
request{
url
resourcePath
requestMethod
remoteIpAddress
requestMethod
}
changes{
appId
resourceId
appName
operationType
}
}
pageInfo{
hasMore
limit
total
offset
}
}
}

Rate/Data Limiting

The Harness API imposes a (sliding-window) rate limit of 30 requests per minute, per account. Each request is limited to a maximum query depth of 10 properties. Harness reserves the right to change these limits, in order to optimize performance for all API consumers.

Next Steps


How did we do?