2012-09-06 03:50:47 -04:00
# GitLab API
2012-07-05 09:57:45 -04:00
2016-01-18 05:38:54 -05:00
Automate GitLab via a simple and powerful API. All definitions can be found
2016-01-18 15:49:04 -05:00
under [`/lib/api` ](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/api ).
2016-01-18 05:38:54 -05:00
2014-04-15 08:52:02 -04:00
## Resources
2014-03-27 05:53:26 -04:00
2016-01-18 05:38:54 -05:00
Documentation for various API resources can be found separately in the
following locations:
2016-06-17 16:03:57 -04:00
- [Award Emoji ](award_emoji.md )
2014-04-24 18:48:22 -04:00
- [Branches ](branches.md )
2016-09-23 08:38:57 -04:00
- [Broadcast Messages ](broadcast_messages.md )
2016-06-09 12:32:17 -04:00
- [Builds ](builds.md )
2016-09-03 03:57:52 -04:00
- [Build Triggers ](build_triggers.md )
2016-06-09 12:32:17 -04:00
- [Build Variables ](build_variables.md )
- [Commits ](commits.md )
2016-09-03 03:57:52 -04:00
- [Deployments ](deployments.md )
2016-06-09 12:32:17 -04:00
- [Deploy Keys ](deploy_keys.md )
2016-08-08 07:42:24 -04:00
- [Gitignores templates ](templates/gitignores.md )
- [GitLab CI Config templates ](templates/gitlab_ci_ymls.md )
2016-06-09 12:32:17 -04:00
- [Groups ](groups.md )
2016-06-23 11:14:31 -04:00
- [Group Access Requests ](access_requests.md )
- [Group Members ](members.md )
2014-04-24 18:48:22 -04:00
- [Issues ](issues.md )
2016-06-09 12:32:17 -04:00
- [Keys ](keys.md )
2014-08-12 08:16:25 -04:00
- [Labels ](labels.md )
2016-06-09 12:32:17 -04:00
- [Merge Requests ](merge_requests.md )
2014-04-24 18:48:22 -04:00
- [Milestones ](milestones.md )
2016-08-08 07:42:24 -04:00
- [Open source license templates ](templates/licenses.md )
2015-05-25 16:51:37 -04:00
- [Namespaces ](namespaces.md )
2016-06-09 12:32:17 -04:00
- [Notes ](notes.md ) (comments)
2016-08-02 16:52:55 -04:00
- [Notification settings ](notification_settings.md )
2016-08-17 09:23:58 -04:00
- [Pipelines ](pipelines.md )
2016-06-09 12:32:17 -04:00
- [Projects ](projects.md ) including setting Webhooks
2016-06-23 11:14:31 -04:00
- [Project Access Requests ](access_requests.md )
- [Project Members ](members.md )
2016-06-09 12:32:17 -04:00
- [Project Snippets ](project_snippets.md )
- [Repositories ](repositories.md )
- [Repository Files ](repository_files.md )
2016-02-01 08:31:49 -05:00
- [Runners ](runners.md )
2016-06-09 12:32:17 -04:00
- [Services ](services.md )
- [Session ](session.md )
- [Settings ](settings.md )
2016-06-21 13:21:13 -04:00
- [Sidekiq metrics ](sidekiq_metrics.md )
2016-06-09 12:32:17 -04:00
- [System Hooks ](system_hooks.md )
- [Tags ](tags.md )
2016-06-16 05:12:42 -04:00
- [Todos ](todos.md )
2016-08-31 05:16:25 -04:00
- [Users ](users.md )
2016-09-01 07:49:34 -04:00
- [Validate CI configuration ](ci/lint.md )
2016-10-12 07:32:48 -04:00
- [Version ](version.md )
2016-06-09 12:32:17 -04:00
### Internal CI API
The following documentation is for the [internal CI API ](ci/README.md ):
- [Builds ](ci/builds.md )
- [Runners ](ci/runners.md )
2014-03-27 05:53:26 -04:00
2016-01-18 04:10:33 -05:00
## Authentication
2014-03-27 05:53:26 -04:00
2016-09-19 07:49:12 -04:00
All API requests require authentication via a session cookie or token. There are
three types of tokens available: private tokens, OAuth 2 tokens, and personal
access tokens.
2012-07-05 09:57:45 -04:00
2016-09-19 07:49:12 -04:00
If authentication information is invalid or omitted, an error message will be
returned with status code `401` :
2012-07-05 09:57:45 -04:00
```json
{
"message": "401 Unauthorized"
}
```
2016-04-28 07:48:49 -04:00
### Private Tokens
2012-07-05 09:57:45 -04:00
2016-06-17 16:03:57 -04:00
You need to pass a `private_token` parameter via query string or header. If passed as a
header, the header name must be `PRIVATE-TOKEN` (uppercase and with a dash instead of
2016-04-28 07:48:49 -04:00
an underscore). You can find or reset your private token in your account page
(`/profile/account`).
2012-07-05 09:57:45 -04:00
2016-04-28 07:48:49 -04:00
### OAuth 2 Tokens
2012-07-05 09:57:45 -04:00
2016-04-28 07:48:49 -04:00
You can use an OAuth 2 token to authenticate with the API by passing it either in the
`access_token` parameter or in the `Authorization` header.
Example of using the OAuth2 token in the header:
2013-01-28 08:49:27 -05:00
2016-01-18 04:10:33 -05:00
```shell
2016-08-08 03:47:17 -04:00
curl --header "Authorization: Bearer OAUTH-TOKEN" https://gitlab.example.com/api/v3/projects
2013-01-28 08:49:27 -05:00
```
2016-04-28 07:48:49 -04:00
Read more about [GitLab as an OAuth2 client ](oauth2.md ).
### Personal Access Tokens
2012-07-05 09:57:45 -04:00
2016-08-08 04:09:54 -04:00
> [Introduced][ce-3749] in GitLab 8.8.
2015-01-12 18:30:34 -05:00
2016-06-17 16:03:57 -04:00
You can create as many personal access tokens as you like from your GitLab
2016-04-28 07:48:49 -04:00
profile (`/profile/personal_access_tokens`); perhaps one for each application
that needs access to the GitLab API.
2015-01-12 18:30:34 -05:00
2016-05-11 00:46:23 -04:00
Once you have your token, pass it to the API using either the `private_token`
parameter or the `PRIVATE-TOKEN` header.
2016-04-28 07:48:49 -04:00
2016-09-19 07:49:12 -04:00
2016-09-29 01:07:17 -04:00
### Session Cookie
2016-09-19 07:49:12 -04:00
When signing in to GitLab as an ordinary user, a `_gitlab_session` cookie is
set. The API will use this cookie for authentication if it is present, but using
the API to generate a new session cookie is currently not supported.
2016-04-28 07:48:49 -04:00
## Basic Usage
API requests should be prefixed with `api` and the API version. The API version
is defined in [`lib/api.rb`][lib-api-url].
Example of a valid API request:
2015-01-12 18:30:34 -05:00
2016-01-18 04:10:33 -05:00
```shell
2016-04-28 07:48:49 -04:00
GET https://gitlab.example.com/api/v3/projects?private_token=9koXpg98eAheJpvBs5tK
2015-01-12 18:30:34 -05:00
```
2016-04-28 07:48:49 -04:00
Example of a valid API request using cURL and authentication via header:
2015-01-12 18:30:34 -05:00
2016-01-18 04:10:33 -05:00
```shell
2016-04-28 07:48:49 -04:00
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects"
2015-01-12 18:30:34 -05:00
```
2016-04-28 07:48:49 -04:00
The API uses JSON to serialize data. You don't need to specify `.json` at the
end of an API URL.
2015-01-12 18:30:34 -05:00
2013-03-06 18:15:57 -05:00
## Status codes
2016-01-18 04:10:33 -05:00
The API is designed to return different status codes according to context and
2016-01-18 05:38:54 -05:00
action. This way, if a request results in an error, the caller is able to get
2016-01-18 04:10:33 -05:00
insight into what went wrong.
The following table gives an overview of how the API functions generally behave.
2016-01-18 05:38:54 -05:00
| Request type | Description |
2016-01-18 04:10:33 -05:00
| ------------ | ----------- |
| `GET` | Access one or more resources and return the result as JSON. |
| `POST` | Return `201 Created` if the resource is successfully created and return the newly created resource as JSON. |
| `GET` / `PUT` / `DELETE` | Return `200 OK` if the resource is accessed, modified or deleted successfully. The (modified) result is returned as JSON. |
2016-01-18 05:38:54 -05:00
| `DELETE` | Designed to be idempotent, meaning a request to a resource still returns `200 OK` even it was deleted before or is not available. The reasoning behind this, is that the user is not really interested if the resource existed before or not. |
2016-01-18 04:10:33 -05:00
The following table shows the possible return codes for API requests.
2016-01-18 05:38:54 -05:00
| Return values | Description |
2016-01-18 04:10:33 -05:00
| ------------- | ----------- |
| `200 OK` | The `GET` , `PUT` or `DELETE` request was successful, the resource(s) itself is returned as JSON. |
| `201 Created` | The `POST` request was successful and the resource is returned as JSON. |
2016-04-06 09:52:16 -04:00
| `304 Not Modified` | Indicates that the resource has not been modified since the last request. |
2016-01-18 15:49:04 -05:00
| `400 Bad Request` | A required attribute of the API request is missing, e.g., the title of an issue is not given. |
2016-01-18 04:10:33 -05:00
| `401 Unauthorized` | The user is not authenticated, a valid [user token ](#authentication ) is necessary. |
2016-01-18 15:49:04 -05:00
| `403 Forbidden` | The request is not allowed, e.g., the user is not allowed to delete a project. |
| `404 Not Found` | A resource could not be accessed, e.g., an ID for a resource could not be found. |
2016-01-18 04:10:33 -05:00
| `405 Method Not Allowed` | The request is not supported. |
2016-01-18 15:49:04 -05:00
| `409 Conflict` | A conflicting resource already exists, e.g., creating a project with a name that already exists. |
2016-01-18 04:10:33 -05:00
| `422 Unprocessable` | The entity could not be processed. |
2016-01-18 05:38:54 -05:00
| `500 Server Error` | While handling the request something went wrong server-side. |
2013-03-06 18:15:57 -05:00
2013-03-28 14:37:44 -04:00
## Sudo
2014-04-24 18:48:22 -04:00
2016-01-18 04:10:33 -05:00
All API requests support performing an API call as if you were another user,
2016-01-18 05:38:54 -05:00
provided your private token is from an administrator account. You need to pass
2016-01-18 15:49:04 -05:00
the `sudo` parameter either via query string or a header with an ID/username of
the user you want to perform the operation as. If passed as a header, the
header name must be `SUDO` (uppercase).
2013-03-06 18:15:57 -05:00
2016-01-18 04:10:33 -05:00
If a non administrative `private_token` is provided, then an error message will
be returned with status code `403` :
2013-03-28 14:37:44 -04:00
```json
{
2016-06-23 11:14:31 -04:00
"message": "403 Forbidden - Must be admin to use sudo"
2013-03-28 14:37:44 -04:00
}
```
2016-01-18 15:49:04 -05:00
If the sudo user ID or username cannot be found, an error message will be
2016-01-18 04:10:33 -05:00
returned with status code `404` :
2013-03-28 14:37:44 -04:00
```json
{
"message": "404 Not Found: No user id or username for: < id / username > "
}
```
2016-01-18 05:38:54 -05:00
---
Example of a valid API call and a request using cURL with sudo request,
providing a username:
2013-03-28 14:37:44 -04:00
2016-01-18 04:10:33 -05:00
```shell
GET /projects?private_token=9koXpg98eAheJpvBs5tK& sudo=username
2013-03-28 14:37:44 -04:00
```
2014-04-24 18:48:22 -04:00
2016-01-18 04:10:33 -05:00
```shell
2016-01-18 05:38:54 -05:00
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --header "SUDO: username" "https://gitlab.example.com/api/v3/projects"
2013-03-28 14:37:44 -04:00
```
2016-01-18 05:38:54 -05:00
Example of a valid API call and a request using cURL with sudo request,
providing an ID:
2013-03-28 14:37:44 -04:00
2016-01-18 04:10:33 -05:00
```shell
2016-01-18 05:38:54 -05:00
GET /projects?private_token=9koXpg98eAheJpvBs5tK& sudo=23
2013-03-28 14:37:44 -04:00
```
2014-04-24 18:48:22 -04:00
2016-01-18 04:10:33 -05:00
```shell
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --header "SUDO: 23" "https://gitlab.example.com/api/v3/projects"
2013-03-28 14:37:44 -04:00
```
2013-03-06 18:15:57 -05:00
2013-10-14 09:40:16 -04:00
## Pagination
2012-09-03 07:46:29 -04:00
2016-01-18 15:49:04 -05:00
Sometimes the returned result will span across many pages. When listing
resources you can pass the following parameters:
2012-09-03 07:46:29 -04:00
2016-01-18 04:10:33 -05:00
| Parameter | Description |
| --------- | ----------- |
2016-01-18 05:38:54 -05:00
| `page` | Page number (default: `1` ) |
| `per_page` | Number of items to list per page (default: `20` , max: `100` ) |
2012-09-03 07:46:29 -04:00
2016-01-18 04:10:33 -05:00
In the example below, we list 50 [namespaces ](namespaces.md ) per page.
```bash
2016-08-08 03:47:17 -04:00
curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/namespaces?per_page=50
2016-01-18 04:10:33 -05:00
```
2016-01-18 04:55:25 -05:00
### Pagination Link header
2016-01-14 11:14:20 -05:00
2016-01-18 04:10:33 -05:00
[Link headers ](http://www.w3.org/wiki/LinkHeader ) are sent back with each
2016-01-18 04:55:25 -05:00
response. They have `rel` set to prev/next/first/last and contain the relevant
URL. Please use these links instead of generating your own URLs.
2016-01-14 11:14:20 -05:00
2016-01-18 04:55:25 -05:00
In the cURL example below, we limit the output to 3 items per page (`per_page=3`)
and we request the second page (`page=2`) of [comments ](notes.md ) of the issue
with ID `8` which belongs to the project with ID `8` :
```bash
2016-08-08 03:47:17 -04:00
curl --head --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/8/issues/8/notes?per_page=3& page=2
2016-01-14 11:14:20 -05:00
```
2016-01-18 04:55:25 -05:00
The response will then be:
```
HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Length: 1103
Content-Type: application/json
Date: Mon, 18 Jan 2016 09:43:18 GMT
Link: < https: / / gitlab . example . com / api / v3 / projects / 8 / issues / 8 / notes ? page = 1&per_page=3 > ; rel="prev", < https: / / gitlab . example . com / api / v3 / projects / 8 / issues / 8 / notes ? page = 3&per_page=3 > ; rel="next", < https: / / gitlab . example . com / api / v3 / projects / 8 / issues / 8 / notes ? page = 1&per_page=3 > ; rel="first", < https: / / gitlab . example . com / api / v3 / projects / 8 / issues / 8 / notes ? page = 3&per_page=3 > ; rel="last"
Status: 200 OK
Vary: Origin
X-Next-Page: 3
X-Page: 2
X-Per-Page: 3
X-Prev-Page: 1
X-Request-Id: 732ad4ee-9870-4866-a199-a9db0cde3c86
X-Runtime: 0.108688
X-Total: 8
X-Total-Pages: 3
2016-01-14 11:14:20 -05:00
```
### Other pagination headers
2016-01-18 04:55:25 -05:00
Additional pagination headers are also sent back.
| Header | Description |
| ------ | ----------- |
| `X-Total` | The total number of items |
| `X-Total-Pages` | The total number of pages |
| `X-Per-Page` | The number of items per page |
| `X-Page` | The index of the current page (starting at 1) |
| `X-Next-Page` | The index of the next page |
| `X-Prev-Page` | The index of the previous page |
2014-03-31 07:16:52 -04:00
2016-01-18 15:49:04 -05:00
## `id` vs `iid`
2013-10-14 09:40:16 -04:00
2016-01-18 04:10:33 -05:00
When you work with the API, you may notice two similar fields in API entities:
`id` and `iid` . The main difference between them is scope.
For example, an issue might have `id: 46` and `iid: 5` .
2014-04-24 18:48:22 -04:00
2016-01-18 04:10:33 -05:00
| Parameter | Description |
| --------- | ----------- |
2016-01-18 05:38:54 -05:00
| `id` | Is unique across all issues and is used for any API call |
| `iid` | Is unique only in scope of a single project. When you browse issues or merge requests with the Web UI, you see the `iid` |
2013-10-14 09:40:16 -04:00
2016-01-18 05:38:54 -05:00
That means that if you want to get an issue via the API you should use the `id` :
2016-01-18 04:10:33 -05:00
```bash
2016-01-18 05:38:54 -05:00
GET /projects/42/issues/:id
2016-01-18 04:10:33 -05:00
```
2013-10-14 09:40:16 -04:00
2016-01-18 05:38:54 -05:00
On the other hand, if you want to create a link to a web page you should use
the `iid` :
2013-10-14 09:40:16 -04:00
2016-01-18 04:10:33 -05:00
```bash
2016-01-18 05:38:54 -05:00
GET /projects/42/issues/:iid
2016-01-18 04:10:33 -05:00
```
2014-08-18 14:09:09 -04:00
## Data validation and error reporting
2016-01-18 15:49:04 -05:00
When working with the API you may encounter validation errors, in which case
2016-01-18 04:10:33 -05:00
the API will answer with an HTTP `400` status.
2014-08-18 14:09:09 -04:00
Such errors appear in two cases:
2016-01-18 15:49:04 -05:00
- A required attribute of the API request is missing, e.g., the title of an
2016-01-18 04:10:33 -05:00
issue is not given
2016-01-18 15:49:04 -05:00
- An attribute did not pass the validation, e.g., user bio is too long
2014-08-18 14:09:09 -04:00
When an attribute is missing, you will get something like:
2016-01-18 05:45:04 -05:00
```
2016-01-18 04:10:33 -05:00
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"message":"400 (Bad request) \"title\" not given"
}
```
2014-08-18 14:09:09 -04:00
2016-01-18 04:10:33 -05:00
When a validation error occurs, error messages will be different. They will
hold all details of validation errors:
2014-10-23 05:11:53 -04:00
2016-01-18 05:45:04 -05:00
```
2016-01-18 04:10:33 -05:00
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"message": {
"bio": [
"is too long (maximum is 255 characters)"
]
2014-08-18 14:09:09 -04:00
}
2016-01-18 04:10:33 -05:00
}
```
2014-08-18 14:09:09 -04:00
2016-01-18 04:10:33 -05:00
This makes error messages more machine-readable. The format can be described as
follows:
2014-08-18 14:09:09 -04:00
2016-01-18 04:10:33 -05:00
```json
{
"message": {
"< property-name > ": [
"< error-message > ",
"< error-message > ",
...
],
"< embed-entity > ": {
2014-08-18 14:09:09 -04:00
"< property-name > ": [
"< error-message > ",
"< error-message > ",
...
],
}
}
2016-01-18 04:10:33 -05:00
}
```
2016-10-10 09:04:05 -04:00
## Unknown route
2016-10-07 11:39:04 -04:00
2016-10-10 09:04:05 -04:00
When you try to access an API URL that does not exist you will receive 404 Not Found.
2016-10-07 11:39:04 -04:00
```
2016-10-07 13:18:02 -04:00
HTTP/1.1 404 Not Found
2016-10-07 11:39:04 -04:00
Content-Type: application/json
{
2016-10-07 13:18:02 -04:00
"error": "404 Not Found"
2016-10-07 11:39:04 -04:00
}
```
2016-01-18 04:10:33 -05:00
## Clients
There are many unofficial GitLab API Clients for most of the popular
2016-01-18 15:49:04 -05:00
programming languages. Visit the [GitLab website] for a complete list.
2016-01-18 04:10:33 -05:00
2016-01-18 05:38:54 -05:00
[GitLab website]: https://about.gitlab.com/applications/#api-clients "Clients using the GitLab API"
[lib-api-url]: https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/api/api.rb
2016-04-28 07:48:49 -04:00
[ce-3749]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/3749