README.md 14.3 KB
Newer Older
1
# GitLab API
N
Nihad Abbasov 已提交
2

3
Automate GitLab via a simple and powerful API. All definitions can be found
4
under [`/lib/api`](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/api).
5

6
## Resources
7

8 9 10
Documentation for various API resources can be found separately in the
following locations:

11
- [Award Emoji](award_emoji.md)
12
- [Branches](branches.md)
13
- [Broadcast Messages](broadcast_messages.md)
A
Achilleas Pipinellis 已提交
14 15
- [Build Variables](build_variables.md)
- [Commits](commits.md)
16
- [Deployments](deployments.md)
A
Achilleas Pipinellis 已提交
17
- [Deploy Keys](deploy_keys.md)
18
- [Environments](environments.md)
M
Mark Fletcher 已提交
19
- [Events](events.md)
20 21
- [Gitignores templates](templates/gitignores.md)
- [GitLab CI Config templates](templates/gitlab_ci_ymls.md)
A
Achilleas Pipinellis 已提交
22
- [Groups](groups.md)
23 24
- [Group Access Requests](access_requests.md)
- [Group Members](members.md)
25
- [Issues](issues.md)
26
- [Issue Boards](boards.md)
27
- [Jobs](jobs.md)
A
Achilleas Pipinellis 已提交
28
- [Keys](keys.md)
R
Robert Schilling 已提交
29
- [Labels](labels.md)
A
Achilleas Pipinellis 已提交
30
- [Merge Requests](merge_requests.md)
31
- [Milestones](milestones.md)
32
- [Open source license templates](templates/licenses.md)
33
- [Namespaces](namespaces.md)
A
Achilleas Pipinellis 已提交
34
- [Notes](notes.md) (comments)
35
- [Notification settings](notification_settings.md)
36
- [Pipelines](pipelines.md)
37
- [Pipeline Triggers](pipeline_triggers.md)
S
Add doc  
Shinya Maeda 已提交
38
- [Pipeline Schedules](pipeline_schedules.md)
A
Achilleas Pipinellis 已提交
39
- [Projects](projects.md) including setting Webhooks
40 41
- [Project Access Requests](access_requests.md)
- [Project Members](members.md)
A
Achilleas Pipinellis 已提交
42 43 44
- [Project Snippets](project_snippets.md)
- [Repositories](repositories.md)
- [Repository Files](repository_files.md)
45
- [Runners](runners.md)
A
Achilleas Pipinellis 已提交
46 47 48
- [Services](services.md)
- [Session](session.md)
- [Settings](settings.md)
49
- [Sidekiq metrics](sidekiq_metrics.md)
A
Achilleas Pipinellis 已提交
50 51
- [System Hooks](system_hooks.md)
- [Tags](tags.md)
52
- [Todos](todos.md)
53
- [Users](users.md)
54
- [Validate CI configuration](ci/lint.md)
O
Oswaldo Ferreira 已提交
55
- [V3 to V4](v3_to_v4.md)
R
Robert Schilling 已提交
56
- [Version](version.md)
A
Achilleas Pipinellis 已提交
57

58 59 60 61 62 63 64 65 66
## Road to GraphQL

API v4 will be the last REST API that we support. Going forward, we will start
on moving to GraphQL and deprecate the use of controller-specific
endpoints. GraphQL has a number of benefits:

1. We avoid having to maintain two different APIs.
2. Callers of the API can request only what they need.

A
Achilleas Pipinellis 已提交
67 68 69 70 71 72
### Internal CI API

The following documentation is for the [internal CI API](ci/README.md):

- [Builds](ci/builds.md)
- [Runners](ci/runners.md)
73

74
## Authentication
75

T
Toni 已提交
76 77 78
Most API requests require authentication via a session cookie or token. For those cases where it is not required, this will be mentioned in the documentation 
for each individual endpoint. For example, the [`/projects/:id` endpoint](projects.md). 
There are three types of tokens available: private tokens, OAuth 2 tokens, and personal
79
access tokens.
N
Nihad Abbasov 已提交
80

81 82
If authentication information is invalid or omitted, an error message will be
returned with status code `401`:
N
Nihad Abbasov 已提交
83 84 85 86 87 88 89

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

90 91 92 93 94 95
### Session Cookie

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.

96
### Private Tokens
N
Nihad Abbasov 已提交
97

98 99
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
100 101
an underscore). You can find or reset your private token in your account page
(`/profile/account`).
N
Nihad Abbasov 已提交
102

103
### OAuth 2 Tokens
N
Nihad Abbasov 已提交
104

105 106 107 108
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:
109

110
```shell
R
Robert Schilling 已提交
111
curl --header "Authorization: Bearer OAUTH-TOKEN" https://gitlab.example.com/api/v4/projects
112 113
```

114 115 116
Read more about [GitLab as an OAuth2 client](oauth2.md).

### Personal Access Tokens
N
Nihad Abbasov 已提交
117

118
> [Introduced][ce-3749] in GitLab 8.8.
V
Valery Sizov 已提交
119

120
You can create as many personal access tokens as you like from your GitLab
121 122
profile (`/profile/personal_access_tokens`); perhaps one for each application
that needs access to the GitLab API.
V
Valery Sizov 已提交
123

124 125
Once you have your token, pass it to the API using either the `private_token`
parameter or the `PRIVATE-TOKEN` header.
126

127 128 129 130 131 132 133
> [Introduced][ce-5951] in GitLab 8.15.

Personal Access Tokens can be created with one or more scopes that allow various actions
that a given token can perform. Although there are only two scopes available at the
moment – `read_user` and `api` – the groundwork has been laid to add more scopes easily.

At any time you can revoke any personal access token by just clicking **Revoke**.
134

135
### Impersonation tokens
V
Valery Sizov 已提交
136

137
> [Introduced][ce-9099] in GitLab 9.0. Needs admin permissions.
V
Valery Sizov 已提交
138

139 140
Impersonation tokens are a type of [Personal Access Token](#personal-access-tokens)
that can only be created by an admin for a specific user.
141

142 143 144 145 146
They are a better alternative to using the user's password/private token
or using the [Sudo](#sudo) feature which also requires the admin's password
or private token, since the password/token can change over time. Impersonation
tokens are a great fit if you want to build applications or tools which
authenticate with the API as a specific user.
147

148 149
For more information about the usage please refer to the
[users API](users.md#retrieve-user-impersonation-tokens) docs.
150

151
### Sudo
152

153
> Needs admin permissions.
154

155
All API requests support performing an API call as if you were another user,
156
provided your private token is from an administrator account. You need to pass
157 158 159
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).
160

161 162
If a non administrative `private_token` is provided, then an error message will
be returned with status code `403`:
163 164 165

```json
{
166
  "message": "403 Forbidden - Must be admin to use sudo"
167 168 169
}
```

170
If the sudo user ID or username cannot be found, an error message will be
171
returned with status code `404`:
172 173 174 175 176 177 178

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

179 180 181 182
---

Example of a valid API call and a request using cURL with sudo request,
providing a username:
183

184
```
185
GET /projects?private_token=9koXpg98eAheJpvBs5tK&sudo=username
186
```
187

188
```shell
R
Robert Schilling 已提交
189
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --header "SUDO: username" "https://gitlab.example.com/api/v4/projects"
190 191
```

192 193
Example of a valid API call and a request using cURL with sudo request,
providing an ID:
194

195
```
196
GET /projects?private_token=9koXpg98eAheJpvBs5tK&sudo=23
197
```
198

199
```shell
R
Robert Schilling 已提交
200
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --header "SUDO: 23" "https://gitlab.example.com/api/v4/projects"
201
```
202

203 204 205 206 207 208
## 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:
209

210 211
```
GET /projects?private_token=9koXpg98eAheJpvBs5tK
212
```
213

214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
Example of a valid API request using cURL and authentication via header:

```shell
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects"
```

The API uses JSON to serialize data. You don't need to specify `.json` at the
end of an API URL.

## 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 | Description |
| ------------ | ----------- |
| `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 this, is that 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 | Description |
| ------------- | ----------- |
| `200 OK` | The `GET`, `PUT` or `DELETE` request was successful, the resource(s) itself is returned as JSON. |
| `204 No Content` | The server has successfully fulfilled the request and that there is no additional content to send in the response payload body. |
| `201 Created` | The `POST` request was successful and the resource is returned as JSON. |
| `304 Not Modified` | Indicates that the resource has not been modified since the last request. |
| `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 server-side. |
254

D
Dmitriy Zaporozhets 已提交
255
## Pagination
N
Nihad Abbasov 已提交
256

257 258
Sometimes the returned result will span across many pages. When listing
resources you can pass the following parameters:
N
Nihad Abbasov 已提交
259

260 261
| Parameter | Description |
| --------- | ----------- |
262 263
| `page`    | Page number (default: `1`) |
| `per_page`| Number of items to list per page (default: `20`, max: `100`) |
N
Nihad Abbasov 已提交
264

265 266 267
In the example below, we list 50 [namespaces](namespaces.md) per page.

```bash
R
Robert Schilling 已提交
268
curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/namespaces?per_page=50
269 270
```

271
### Pagination Link header
272

273
[Link headers](http://www.w3.org/wiki/LinkHeader) are sent back with each
274 275
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.
276

277 278 279 280 281
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
R
Robert Schilling 已提交
282
curl --head --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/8/issues/8/notes?per_page=3&page=2
283 284
```

285 286 287 288 289 290 291 292
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
R
Robert Schilling 已提交
293
Link: <https://gitlab.example.com/api/v4/projects/8/issues/8/notes?page=1&per_page=3>; rel="prev", <https://gitlab.example.com/api/v4/projects/8/issues/8/notes?page=3&per_page=3>; rel="next", <https://gitlab.example.com/api/v4/projects/8/issues/8/notes?page=1&per_page=3>; rel="first", <https://gitlab.example.com/api/v4/projects/8/issues/8/notes?page=3&per_page=3>; rel="last"
294 295 296 297 298 299 300 301 302 303
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
304 305 306 307
```

### Other pagination headers

308 309 310 311 312 313 314 315 316 317
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 |
318

319 320
## Namespaced path encoding

321
If using namespaced API calls, make sure that the `NAMESPACE/PROJECT_NAME` is
322 323
URL-encoded.

324
For example, `/` is represented by `%2F`:
325 326 327 328 329

```
/api/v4/projects/diaspora%2Fdiaspora
```

330
## `id` vs `iid`
D
Dmitriy Zaporozhets 已提交
331

332 333 334 335
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`.
336

337 338
| Parameter | Description |
| --------- | ----------- |
339 340
| `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` |
D
Dmitriy Zaporozhets 已提交
341

342
That means that if you want to get an issue via the API you should use the `id`:
343

344
```
345
GET /projects/42/issues/:id
346
```
D
Dmitriy Zaporozhets 已提交
347

348 349
On the other hand, if you want to create a link to a web page you should use
the `iid`:
D
Dmitriy Zaporozhets 已提交
350

351
```
352
GET /projects/42/issues/:iid
353
```
J
jubianchi 已提交
354 355 356

## Data validation and error reporting

357
When working with the API you may encounter validation errors, in which case
358 359
the API will answer with an HTTP `400` status.

J
jubianchi 已提交
360 361
Such errors appear in two cases:

362
- A required attribute of the API request is missing, e.g., the title of an
363
  issue is not given
364
- An attribute did not pass the validation, e.g., user bio is too long
J
jubianchi 已提交
365 366 367

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

368
```
369 370 371 372 373 374
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
    "message":"400 (Bad request) \"title\" not given"
}
```
J
jubianchi 已提交
375

376 377
When a validation error occurs, error messages will be different. They will
hold all details of validation errors:
378

379
```
380 381 382 383 384 385 386
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
    "message": {
        "bio": [
            "is too long (maximum is 255 characters)"
        ]
J
jubianchi 已提交
387
    }
388 389
}
```
J
jubianchi 已提交
390

391 392
This makes error messages more machine-readable. The format can be described as
follows:
J
jubianchi 已提交
393

394 395 396 397 398 399 400 401 402
```json
{
    "message": {
        "<property-name>": [
            "<error-message>",
            "<error-message>",
            ...
        ],
        "<embed-entity>": {
J
jubianchi 已提交
403 404 405 406 407 408 409
            "<property-name>": [
                "<error-message>",
                "<error-message>",
                ...
            ],
        }
    }
410 411 412
}
```

D
Dmitriy Zaporozhets 已提交
413
## Unknown route
414

D
Dmitriy Zaporozhets 已提交
415
When you try to access an API URL that does not exist you will receive 404 Not Found.
416 417

```
418
HTTP/1.1 404 Not Found
419 420
Content-Type: application/json
{
421
    "error": "404 Not Found"
422 423 424
}
```

425 426 427
## Clients

There are many unofficial GitLab API Clients for most of the popular
428
programming languages. Visit the [GitLab website] for a complete list.
429

430 431
[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
432
[ce-3749]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/3749
433
[ce-5951]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/5951
434
[ce-9099]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9099