Code Climate API

Code Climate's API exposes repository information and analysis results in accordance with the standards of REST and the JSON API specification.

Beta

The Code Climate API is currently in Beta. Some endpoints and responses may change without warning.

Ruby Example

See this public gist for an example of using the Code Climate API (in Ruby) which incorporates authentication and pagination.

Authentication

Viewing data on the API requires a token provided in the Authorization header of the request. You can generate a new Code Climate personal access token on codeclimate.com in the token settings area of your Code Climate user profile.

curl \
  -H "Accept: application/vnd.api+json" \
  -H "Authorization: Token token={TOKEN}" \
  https://api.codeclimate.com/v1/user

Rate Limit

The API enforces a limit of 5,000 requests per token per hour

Endpoints

This API conforms to jsonapi. Except where noted, list endpoints accept filter and page parameters.

GET /repos/123/ref_points?page[size]=1&filter[branch]=master

All endpoints are prefixed by the API version. The current version is /v1.

Note

In the sample values shown below, "ObjectId" means a stringified BSON object id and "Timestamp" means an ISO8601-formatted timestamp (e.g. "2015-12-17T18:58:07.301Z"). Some resources are built from multiple database records. In such cases, they'll have the form ObjectId+ObjectId and be referred to below as "CompoundObjectId".

GET /user

Return information about the currently authenticating user.

{
  "data": {
    "id": "ObjectId",
    "type": "users",
    "attributes": {
      "email": "joe@example.com",
      "full_name": "Joe Smith",
      "staff": true
    },
    "links":{
      "avatar":"https://avatars.githubusercontent.com/u/123"
    }
  }
}

GET /orgs

List organizations for the current user

  {
    "data": [{
      "id": "ObjectId",
      "type": "orgs",
      "attributes": {
        "name": "My Great Org",
      },
      "meta": {
        "counts": {
          "repos": 3
        },
        "permissions": {
          "admin": true
        } 
      }
    }]
  }

POST /orgs

Create a new organization

{
    "data": {
      "type": "orgs",
      "attributes": {
        "name": "My Great Org",
      }
    }
  }

If the organization was created successfully, this endpoint responds with the created resource and status 201

POST /orgs/:org_id/repos

Code Climate repositories may be added as public or private. Use this endpoint to create a private repository in one of your organizations.

{
  "data": {
    "type": "repos",
    "attributes": {
      "url": "https://github.com/foo/bar"
    }
  }
}

What URL?

Code Climate uses the url parameter to determine where your repository is hosted and how to clone it. Currently, only repositories hosted on GitHub are supported, so we only accept https://github.com URLs. Once created, users will still find a Deploy Key added on GitHub and an SSH-based clone URL in their repo settings.

If the repo was created successfully, this endpoint responds with the created resource and status 201.

GET /repos?github_slug=

Required Parameter

The github_slug parameter is required, as this route is not paginated.

  {
    "data": [{
      "id": "ObjectId",
      "type": "repos",
      "attributes": {
        "analysis_version": 1234,
        "badge_token": "abc123",
        "branch": "master",
        "github_slug": "foo/bar",
        "score": 3.54
      },
      "links": {
        "self": "https://codeclimate.com/repos/123",
        "services": "https://api.codeclimate.com/v1/repos/123/services",
        "web_coverage": "https://codeclimate.com/repos/123/coverage",
        "web_issues": "https://codeclimate.com/repos/123/issues",
      },
      "meta": {
        "permissions": {
          "admin": true
        }
      },
      "relationships": {
        "account": {
          "data": {
            "id": ObjectId,
            "type": "orgs"
          }
        },
      	"latest_default_branch_test_report": {
          "data": {
            "id": "ObjectId",
            "type": "test_reports"
          }
        }
      }
    }]
  }

You may also access this response via GET /repos/:repo_id

GET /repos/:repo_id/metrics/:name

Read repository metrics for a given time-range. Available metrics by name:

  • gpa: the repository's GPA
  • ratings.A: the number of files with an A rating
  • ratings.B: the number of files with a B rating
  • ratings.C: the number of files with a C rating
  • ratings.D: the number of files with a D rating
  • ratings.F: the number of files with an F rating

Required Parameter

This endpoint requires filtering with from and to parameters:

?filter[from]=YYYY-MM-DD&filter[to]=YYYY-MM-DD
{
  "data": {
    "id": "ObjectId",
    "type": "metrics",
    "attributes": {
      "points": [
        {
          "timestamp": "UnixEpoch",
          "value": "Numeric"
        }
      ]
  }
}

GET /repos/:repo_id/ref_points

What's a RefPoint?

A RefPoint is an observation of a commit on a branch at a moment in time. Whenever we hear about a commit (e.g. through webhook events), we create a RefPoint for it. It's sort of like our own git log of the actions that occurred on the repository and won't change if you force-push and change history.

  {
    "data": [{
      "id": "ObjectId",
      "type": "ref_points",
      "attributes": {
        "analyzed": true,
        "branch": "master",
        "commit_sha": "abc123",
        "created_at": "Timestamp",
        "ref": "refs/heads/master"
      },
      "relationships": {
        "snapshot": {
          "data": {
            "id": "ObjectId",
            "type": "snapshots"
          }
        }
      }
    }]
  }

Passing filter & page params

As with any other API endpoint, except where noted, you may pass additional page and filter parameters:

GET /repos/123/ref_points?page[size]=1&filter[branch]=master&filter[analyzed]=true

GET /repos/:repo_id/builds

  {
    "data": [{
      "id": "ObjectId",
      "type": "builds",
      "attributes": {
        "commit_sha": "abc123",
        "error_code": "U10",
        "finished_at": "Timestamp",
        "number": 1,
        "state": "running"
      },
      "relationships": {
        "pull_request": {
          "data": {
            "id": ObjectId,
            "type": "pull_requests"
          }
        },
        "snapshot": {
          "data": {
            "id": "ObjectId",
            "type": "snapshots"
          }
        }
      },
      "links": {
        "self": "https://codeclimate.com/..."
      }
    }]
  }

GET /repos/:repo_id/builds/:number

  {
    "data": {
      "id": "ObjectId",
      "type": "builds",
      "attributes": {
        "commit_sha": "abc123",
        "error_code": "U10",
        "finished_at": "Timestamp",
        "number": 1,
        "state": "complete"
      },
      "relationships": {
        "pull_request": {
          "data": {
            "id": ObjectId,
            "type": "pull_requests"
          }
        },
        "snapshot": {
          "data": {
            "id": "ObjectId",
            "type": "snapshots"
          }
        }
      },
      "links": {
        "self": "https://codeclimate.com/..."
      }
    }
  }

GET /repos/:repo_id/snapshots/:snapshot_id

{  
  "data":{  
    "id":"ObjectId",
    "type":"snapshots",
    "attributes":{  
      "commit_sha":"abc123",
      "committed_at":"Timestamp",
      "analysis_version":1234
    }
  }
}

GET /repos/:repo_id/snapshots/:snapshot_id/files

  {
    "data": [{
      "id": "ObjectId",
      "type": "units",
      "attributes": {
        "blob_id": "abc123",
        "path": "foo/bar.rb",
        "rating": "A"
      }
    }]
  }

GET /repos/:repo_id/snapshots/:snapshot_id/issues

  {
    "data": [
      {
        "id": "ObjectId",
        "type": "issues",
        "attributes": {
          "categories": ["Complexity"],
          "check_name": "Rubocop/ComplexMethod",
          "content": {
            "body": "markdown content"
          },
          "description": "Issue description",
          "engine_name": "rubocop",
          "fingerprint": "abc123",
          "location": {
            "path": "foo/bar.rb",
            "start_line": 1,
            "end_line": 10
          },
          "other_locations": [],
          "remediation_points": 100000,
          "severity": "normal"
        }
      }
    ]
  }

GET /repos/:repo_id/test_reports

  {
    "data": [{
      "id": "ObjectId",
      "type": "test_reports",
      "attributes": {
        "commit_sha": "abc123",
        "committed_at": "Timestamp",
        "covered_percent": 12.34
      }
    }]
  }

GET /repos/:repo_id/test_reports/:test_report_id/test_file_reports

{
  "data": [{
    "id": "ObjectId",
    "type": "test_file_reports",
    "attributes": {
      "coverage": [null,null,0,1,2,2,3,1,0,null,0],
      "covered_percent": 91.38,
      "covered_strength": 2.84,
      "path": "foo/bar.rb",
      "line_counts": {
        "total": 58,
        "missed": 5,
        "covered": 53
      }
    }
  }]
}

GET /repos/:repo_id/services

{
  "data": [
    {
      "id": "ObjectId",
      "type": "services",
      "attributes": {
        "slug": "githubissues",
        "title": "GitHub Issues",
        "description": "Open issues on GitHub",
      },
      "links": {
        "events": "https://api.codeclimate.com/v1/repos/1/services/2/events"
      }
    }
  ]
}

POST /repos/:repo_id/services/:service_id/events

{
  "data": {
    "attributes": {
      "issue": {
      "check_name": "Metrics/CyclomaticComplexity",
      "description": "Cyclomatic complexity for method is too high.",
      "details_url": "http://example.com/repos/1/issues#issue_12345",
      "id": "12345",
      "location": {
        "path": "foo.rb"
      },
      "name": "issue"
    }
  }
}
{
  "data": {
    "attributes": {
      "ok": true,
      "message": "Success"
    },
    "id": "ObjectId",
    "type": "service_events",
    "links": {
      "external": "https://github.com/example/repo/issues/100"
    }
  }
}

GET /repos/:repo_id/pulls/:number/files

Required Parameter

The filter[path] parameter is required for this endpoint.

{ 
  filter: { 
    path: { $in: [ "app/controllers/foo_controller.rb" ] } 
  }
}
{
  "data": [
    {
      "id": "CompoundObjectId",
      "type": "file_diffs",
      "attributes": {
      	"to_rating": "A",
        "from_rating": "B",
        "path": "foo/bar.rb"
     	}
    }
  ]
}

POST /test_reports

Create a new test report. This endpoint does not require an API token, but does require a Test Reporter ID in the X-CC-Test-Reporter-Id header. This value used to be known as "Test Reporter Token" and can be found in your repository settings.

curl \
  -H "Accept: application/vnd.api+json" \
  -H "X-CC-Test-Reporter-Id: {cc_test_reporter_id}" \
  -d @json_payload
  https://api.codeclimate.com/v1/test_reports
{
  "data": {
    "type": "test_reports",
    "attributes": {
      "ci_branch": "some-branch",
      "ci_build_identifier": "123",
      "ci_build_url": "ci-build-url",
      "ci_commit_sha": "b320e7902f50f8a9231329fa15a9aa667ab9d14e",
      "ci_committed_at": 1490221044,
      "ci_service_name": "CI name",
      "environment": {
        "gem_version": "2.4.8",
        "package_version": "",
        "pwd": "app",
        "rails_root": "",
        "reporter_version": "0.1.0",
        "simplecov_root": ""
      },
      "git_branch" : "some-branch",
      "commit_sha": "b320e7902f50f8a9231329fa15a9aa667ab9d14e",
      "committed_at": 1490221044,
      "run_at": 1490221123,
      "covered_percent": 86,
      "covered_strength": 0,
      "line_counts": {
        "missed": 14,
        "covered": 86,
        "total": 100
      }
    }
  }
}
{
  "data": {
    "type": "test_reports",
    "attributes": {
    	"id": "ObjectId"
    }
  },
  "links": {
    "post_batch": "https://api.codeclimate.com/v1/repos/:repo_id/test_reports/:id/test_file_reports/batch"
  }
}

If the test report was created successfully, this endpoint responds with a 201 status and the location to submit related test_file_report batches in links.

POST repos/:repo_id/test_reports/:id/test_file_reports/batch

Create new test file reports for a test report. This endpoint does not require an API token, but does require a Test Reporter ID in the X-CC-Test-Reporter-Id header. This value used to be known as "Test Reporter Token" and can be found in your repository settings.

Batch details

This endpoint expects batches of test_file_reports in each request, up to 500 elements in size. This allows for more efficient processing of large coverage payloads.

The client is responsible for including current and total identifiers in the meta information, which indicate which batch this request represents and how many batches to expect. Batches must be sent in order, and when a request is submitted where current equals total, the test report will be considered complete.

curl \
  -H "Accept: application/vnd.api+json" \
  -H "X-CC-Test-Reporter-Id: {cc_test_reporter_id}" \
  -d @json_payload
  https://api.codeclimate.com/v1/test_reports/:id/test_file_reports/batch
{
  "data": [
    {
      "type": "test_file_reports",    	
      "coverage": [null,null,0,1,2,2,3,1,0,null,0],
      "covered_percent": 91.38,
      "covered_strength": 2.84,
      "path": "foo/bar.rb",
      "line_counts": {
        "total": 58,
        "missed": 5,
        "covered": 53
      } 	
    },
    {
      "type": "test_file_reports",
      "coverage": [null,null,0,1,2,2,3,1,0,null,0],
      "covered_percent": 80,
      "covered_strength": 0,
      "path": "foo.rb",
      "line_counts": {
        "total": 10,
        "missed": 2,
        "covered": 8
      }
    }
  ],
  "meta": {
    "current": 1,
    "total": 3
  }
}

If all test_file_reports in the batch were created successfully, this endpoint responds with status 201.

Code Climate API