README.md 9.86 KB
Newer Older
1
# GitLab API
Nihad Abbasov's avatar
Nihad Abbasov committed
2

3
## Resources
4

5 6
- [Users](users.md)
- [Session](session.md)
7
- [Projects](projects.md) including setting Webhooks
8
- [Project Snippets](project_snippets.md)
Kevin Lyda's avatar
Kevin Lyda committed
9
- [Services](services.md)
10 11 12
- [Repositories](repositories.md)
- [Repository Files](repository_files.md)
- [Commits](commits.md)
13
- [Tags](tags.md)
14 15 16
- [Branches](branches.md)
- [Merge Requests](merge_requests.md)
- [Issues](issues.md)
17
- [Labels](labels.md)
18 19 20 21 22
- [Milestones](milestones.md)
- [Notes](notes.md) (comments)
- [Deploy Keys](deploy_keys.md)
- [System Hooks](system_hooks.md)
- [Groups](groups.md)
23
- [Namespaces](namespaces.md)
24
- [Settings](settings.md)
25
- [Keys](keys.md)
Tomasz Maczukin's avatar
Tomasz Maczukin committed
26
- [Builds](builds.md)
27
- [Build triggers](build_triggers.md)
28
- [Build Variables](build_variables.md)
29

30
## Authentication
31

32 33 34 35
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`).
Nihad Abbasov's avatar
Nihad Abbasov committed
36

37 38
If `private_token` is invalid or omitted, then an error message will be
returned with status code `401`:
Nihad Abbasov's avatar
Nihad Abbasov committed
39 40 41 42 43 44 45

```json
{
  "message": "401 Unauthorized"
}
```

46 47
API requests should be prefixed with `api` and the API version. The API version
is defined in `lib/api.rb`.
Nihad Abbasov's avatar
Nihad Abbasov committed
48

49
Example of a valid API request:
Nihad Abbasov's avatar
Nihad Abbasov committed
50

51 52
```shell
GET https://gitlab.example.com/api/v3/projects?private_token=9koXpg98eAheJpvBs5tK
Nihad Abbasov's avatar
Nihad Abbasov committed
53 54
```

55
Example of a valid API request using curl and authentication via header:
56

57 58
```shell
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects"
59 60
```

Nihad Abbasov's avatar
Nihad Abbasov committed
61 62
The API uses JSON to serialize data. You don't need to specify `.json` at the end of API URL.

63 64
## Authentication with OAuth2 token

65 66
Instead of the `private_token` you can transmit the OAuth2 access token as a
header or as a parameter.
67

68
Example of OAuth2 token as a parameter:
69

70 71
```shell
curl https://gitlab.example.com/api/v3/user?access_token=OAUTH-TOKEN
72 73
```

74
Example of OAuth2 token as a header:
75

76 77
```shell
curl -H "Authorization: Bearer OAUTH-TOKEN" https://example.com/api/v3/user
78 79
```

80
Read more about [GitLab as an OAuth2 client](oauth2.md).
81

82 83
## Status codes

84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
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. |
111

112
## Sudo
113

114 115 116 117 118
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).
119

120 121
If a non administrative `private_token` is provided, then an error message will
be returned with status code `403`:
122 123 124 125 126 127 128

```json
{
  "message": "403 Forbidden: Must be admin to use sudo"
}
```

129 130
If the sudo user id or username cannot be found, an error message will be
returned with status code `404`:
131 132 133 134 135 136 137

```json
{
  "message": "404 Not Found: No user id or username for: <id/username>"
}
```

138 139
Example of a valid API call with sudo request providing a username and an ID
respectively:
140

141 142
```shell
GET /projects?private_token=9koXpg98eAheJpvBs5tK&sudo=username
143
```
144

145 146
```shell
GET /projects?private_token=9koXpg98eAheJpvBs5tK&sudo=23
147 148
```

149 150
Example of a valid API request with sudo using curl and authentication via
header:
151

152 153
```shell
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --header "SUDO: username" "https://gitlab.example.com/api/v3/projects"
154
```
155

156 157
```shell
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --header "SUDO: 23" "https://gitlab.example.com/api/v3/projects"
158
```
159

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
160
## Pagination
Nihad Abbasov's avatar
Nihad Abbasov committed
161

162 163
Sometimes the returned result will span across many lines. When listing
resources you can pass the following parameters.
Nihad Abbasov's avatar
Nihad Abbasov committed
164

165 166 167 168
| Parameter | Description |
| --------- | ----------- |
| `page`    | Page number (default: `1`). |
| `per_page`| Number of items to list per page (default: `20`, max: `100`). |
Nihad Abbasov's avatar
Nihad Abbasov committed
169

170 171 172 173 174 175
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
```

176
### Pagination Link header
177

178
[Link headers](http://www.w3.org/wiki/LinkHeader) are sent back with each
179 180
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.
181

182 183 184 185 186 187
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
curl -I -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/8/issues/8/notes?per_page=3&page=2
188 189
```

190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
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
209 210 211 212
```

### Other pagination headers

213 214 215 216 217 218 219 220 221 222
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 |
223

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
224 225
## id vs iid

226 227 228 229
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`.
230

231 232 233 234
| 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`. |
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
235

236 237 238 239 240
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
```
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
241

242
On the other hand, if you want to create a link to a web page you should use:
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
243

244 245 246
```bash
https://gitlab.example.com/api/v3/projects/42/issues/:iid.json
```
247 248 249

## Data validation and error reporting

250 251 252
When working with the API you may encounter validation errors. In such case,
the API will answer with an HTTP `400` status.

253 254
Such errors appear in two cases:

255 256 257
- 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
258 259 260

When an attribute is missing, you will get something like:

261 262 263 264 265 266 267
```
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
    "message":"400 (Bad request) \"title\" not given"
}
```
268

269 270
When a validation error occurs, error messages will be different. They will
hold all details of validation errors:
271

272 273 274 275 276 277 278 279
```
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
    "message": {
        "bio": [
            "is too long (maximum is 255 characters)"
        ]
280
    }
281 282
}
```
283

284 285
This makes error messages more machine-readable. The format can be described as
follows:
286

287 288 289 290 291 292 293 294 295
```json
{
    "message": {
        "<property-name>": [
            "<error-message>",
            "<error-message>",
            ...
        ],
        "<embed-entity>": {
296 297 298 299 300 301 302
            "<property-name>": [
                "<error-message>",
                "<error-message>",
                ...
            ],
        }
    }
303 304 305 306 307 308 309 310 311
}
```

## 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