# GitLab API ## Resources - [Users](users.md) - [Session](session.md) - [Projects](projects.md) including setting Webhooks - [Project Snippets](project_snippets.md) - [Services](services.md) - [Repositories](repositories.md) - [Repository Files](repository_files.md) - [Commits](commits.md) - [Tags](tags.md) - [Branches](branches.md) - [Merge Requests](merge_requests.md) - [Issues](issues.md) - [Labels](labels.md) - [Milestones](milestones.md) - [Notes](notes.md) (comments) - [Deploy Keys](deploy_keys.md) - [System Hooks](system_hooks.md) - [Groups](groups.md) - [Namespaces](namespaces.md) - [Settings](settings.md) - [Keys](keys.md) - [Builds](builds.md) - [Build triggers](build_triggers.md) - [Build Variables](build_variables.md) ## Authentication All API requests require authentication. You need to pass a `private_token` parameter by URL or header. If passed as a header, the header name must be **PRIVATE-TOKEN** (capital and with dash instead of underscore). You can find or reset your private token in your account page (`/profile/account`). If `private_token` is invalid or omitted, then an error message will be returned with status code `401`: ```json { "message": "401 Unauthorized" } ``` API requests should be prefixed with `api` and the API version. The API version is defined in `lib/api.rb`. Example of a valid API request: ```shell GET https://gitlab.example.com/api/v3/projects?private_token=9koXpg98eAheJpvBs5tK ``` Example of a valid API request using curl and authentication via header: ```shell curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects" ``` The API uses JSON to serialize data. You don't need to specify `.json` at the end of API URL. ## Authentication with OAuth2 token Instead of the `private_token` you can transmit the OAuth2 access token as a header or as a parameter. Example of OAuth2 token as a parameter: ```shell curl https://gitlab.example.com/api/v3/user?access_token=OAUTH-TOKEN ``` Example of OAuth2 token as a header: ```shell curl -H "Authorization: Bearer OAUTH-TOKEN" https://example.com/api/v3/user ``` Read more about [GitLab as an OAuth2 client](oauth2.md). ## Status codes The API is designed to return different status codes according to context and action. This way if a request results in an error, the caller is able to get insight into what went wrong. The following table gives an overview of how the API functions generally behave. | Request type | Explanation | | ------------ | ----------- | | `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. | | `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 it is the user is not really interested if the resource existed before or not. | The following table shows the possible return codes for API requests. | Return values | Explanation | | ------------- | ----------- | | `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. | | `400 Bad Request` | A required attribute of the API request is missing, e.g. the title of an issue is not given. | | `401 Unauthorized` | The user is not authenticated, a valid [user token](#authentication) is necessary. | | `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. | | `405 Method Not Allowed` | The request is not supported. | | `409 Conflict` | A conflicting resource already exists, e.g. creating a project with a name that already exists. | | `422 Unprocessable` | The entity could not be processed. | | `500 Server Error` | While handling the request something went wrong on the server side. | ## Sudo All API requests support performing an API call as if you were another user, provided your private token is from an administration account. You need to pass the `sudo` parameter by URL or header with an ID or username of the user you want to perform the operation as. If passed as a header, the header name must be **SUDO** (capitals). If a non administrative `private_token` is provided, then an error message will be returned with status code `403`: ```json { "message": "403 Forbidden: Must be admin to use sudo" } ``` If the sudo user id or username cannot be found, an error message will be returned with status code `404`: ```json { "message": "404 Not Found: No user id or username for: " } ``` Example of a valid API call with sudo request providing a username and an ID respectively: ```shell GET /projects?private_token=9koXpg98eAheJpvBs5tK&sudo=username ``` ```shell GET /projects?private_token=9koXpg98eAheJpvBs5tK&sudo=23 ``` Example of a valid API request with sudo using curl and authentication via header: ```shell curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --header "SUDO: username" "https://gitlab.example.com/api/v3/projects" ``` ```shell curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --header "SUDO: 23" "https://gitlab.example.com/api/v3/projects" ``` ## Pagination Sometimes the returned result will span across many lines. When listing resources you can pass the following parameters. | Parameter | Description | | --------- | ----------- | | `page` | Page number (default: `1`). | | `per_page`| Number of items to list per page (default: `20`, max: `100`). | In the example below, we list 50 [namespaces](namespaces.md) per page. ```bash curl -X PUT -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/namespaces?per_page=50 ``` [Link headers](http://www.w3.org/wiki/LinkHeader) are sent back with each response. These have `rel` prev/next/first/last and contain the relevant URL. Please use these instead of generating your own URLs. ## id vs iid 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`. | Parameter | Description | | --------- | ----------- | | 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 Web UI, you see the `iid`. | That means that if you want to get an issue via the API you should use: ```bash https://gitlab.example.com/api/v3/projects/42/issues/:id.json ``` On the other hand, if you want to create a link to a web page you should use: ```bash https://gitlab.example.com/api/v3/projects/42/issues/:iid.json ``` ## Data validation and error reporting When working with the API you may encounter validation errors. In such case, the API will answer with an HTTP `400` status. Such errors appear in two cases: - A required attribute of the API request is missing, e.g. the title of an issue is not given - An attribute did not pass the validation, e.g. user bio is too long When an attribute is missing, you will get something like: ``` HTTP/1.1 400 Bad Request Content-Type: application/json { "message":"400 (Bad request) \"title\" not given" } ``` When a validation error occurs, error messages will be different. They will hold all details of validation errors: ``` HTTP/1.1 400 Bad Request Content-Type: application/json { "message": { "bio": [ "is too long (maximum is 255 characters)" ] } } ``` This makes error messages more machine-readable. The format can be described as follows: ```json { "message": { "": [ "", "", ... ], "": { "": [ "", "", ... ], } } } ``` ## Clients There are many unofficial GitLab API Clients for most of the popular programming languages. Visit the [GitLab website][] for a complete list. [GitLab website]: https://about.gitlab.com/applications/#api-clients