BigW Consortium Gitlab

README.md 16.1 KB
Newer Older
1
# GitLab API
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)
Shinya Maeda committed
14 15
- [Project-level Variables](project_level_variables.md)
- [Group-level Variables](group_level_variables.md)
16
- [Commits](commits.md)
17
- [Custom Attributes](custom_attributes.md)
18
- [Deployments](deployments.md)
19
- [Deploy Keys](deploy_keys.md)
20
- [Environments](environments.md)
21
- [Events](events.md)
22
- [Feature flags](features.md)
23 24
- [Gitignores templates](templates/gitignores.md)
- [GitLab CI Config templates](templates/gitlab_ci_ymls.md)
25
- [Groups](groups.md)
26 27
- [Group Access Requests](access_requests.md)
- [Group Members](members.md)
28
- [Issues](issues.md)
29
- [Issue Boards](boards.md)
30
- [Jobs](jobs.md)
31
- [Keys](keys.md)
32
- [Labels](labels.md)
33
- [Merge Requests](merge_requests.md)
34 35
- [Project milestones](milestones.md)
- [Group milestones](group_milestones.md)
36
- [Namespaces](namespaces.md)
37
- [Notes](notes.md) (comments)
38
- [Notification settings](notification_settings.md)
39
- [Open source license templates](templates/licenses.md)
40
- [Pages Domains](pages_domains.md)
41
- [Pipelines](pipelines.md)
42
- [Pipeline Triggers](pipeline_triggers.md)
Shinya Maeda committed
43
- [Pipeline Schedules](pipeline_schedules.md)
44
- [Projects](projects.md) including setting Webhooks
45 46
- [Project Access Requests](access_requests.md)
- [Project Members](members.md)
47
- [Project Snippets](project_snippets.md)
48
- [Protected Branches](protected_branches.md)
49 50
- [Repositories](repositories.md)
- [Repository Files](repository_files.md)
51
- [Runners](runners.md)
52 53
- [Services](services.md)
- [Settings](settings.md)
54
- [Sidekiq metrics](sidekiq_metrics.md)
55 56
- [System Hooks](system_hooks.md)
- [Tags](tags.md)
57
- [Todos](todos.md)
58
- [Users](users.md)
59
- [Validate CI configuration](lint.md)
60
- [V3 to V4](v3_to_v4.md)
61
- [Version](version.md)
62
- [Wikis](wikis.md)
63

64 65
## Road to GraphQL

66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
Going forward, we will start on moving to
[GraphQL](http://graphql.org/learn/best-practices/) 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.
3. It is versioned by default.

It will co-exist with the current v4 REST API. If we have a v5 API, this should
be a compatibility layer on top of GraphQL.

Although there were some patenting and licensing concerns with GraphQL, these
have been resolved to our satisfaction by the relicensing of the reference
implementations under MIT, and the use of the OWF license for the GraphQL
specification.
81

82 83 84
## Basic usage

API requests should be prefixed with `api` and the API version. The API version
85 86
is defined in [`lib/api.rb`][lib-api-url]. For example, the root of the v4 API
is at `/api/v4`.
87

Douwe Maan committed
88
Example of a valid API request using cURL:
89 90

```shell
Douwe Maan committed
91
curl "https://gitlab.example.com/api/v4/projects"
92 93 94 95 96
```

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

97
## Authentication
98

Douwe Maan committed
99 100
Most API requests require authentication, or will only return public data when
authentication is not provided. For
101 102
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).
103

Douwe Maan committed
104
There are three ways to authenticate with the GitLab API:
105

106 107
1. [OAuth2 tokens](#oauth2-tokens)
1. [Personal access tokens](#personal-access-tokens)
Douwe Maan committed
108 109 110 111 112
1. [Session cookie](#session-cookie)

For admins who want to authenticate with the API as a specific user, or who want to build applications or scripts that do so, two options are available:
1. [Impersonation tokens](#impersonation-tokens)
2. [Sudo](#sudo)
113

114 115
If authentication information is invalid or omitted, an error message will be
returned with status code `401`:
116 117 118 119 120 121 122

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

Douwe Maan committed
123
### OAuth2 tokens
124

Douwe Maan committed
125 126
You can use an [OAuth2 token](oauth2.md) to authenticate with the API by passing it in either the
`access_token` parameter or the `Authorization` header.
127

Douwe Maan committed
128
Example of using the OAuth2 token in a parameter:
129

Douwe Maan committed
130 131 132
```shell
curl https://gitlab.example.com/api/v4/projects?access_token=OAUTH-TOKEN
```
133

Douwe Maan committed
134
Example of using the OAuth2 token in a header:
135

136
```shell
137
curl --header "Authorization: Bearer OAUTH-TOKEN" https://gitlab.example.com/api/v4/projects
138 139
```

Douwe Maan committed
140
Read more about [GitLab as an OAuth2 provider](oauth2.md).
141

Douwe Maan committed
142
### Personal access tokens
143

Douwe Maan committed
144 145
You can use a [personal access token][pat] to authenticate with the API by passing it in either the
`private_token` parameter or the `Private-Token` header.
146

Douwe Maan committed
147
Example of using the personal access token in a parameter:
148

Douwe Maan committed
149 150 151 152 153
```shell
curl https://gitlab.example.com/api/v4/projects?private_token=9koXpg98eAheJpvBs5tK
```

Example of using the personal access token in a header:
154

Douwe Maan committed
155 156 157
```shell
curl --header "Private-Token: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects
```
158

Douwe Maan committed
159 160 161 162 163 164 165
Read more about [personal access tokens][pat].

### Session cookie

When signing in to the main GitLab application, 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.
166

Douwe Maan committed
167 168 169
The primary user of this authentication method is the web frontend of GitLab itself,
which can use the API as the authenticated user to get a list of their projects,
for example, without needing to explicitly pass an access token.
170

171
### Impersonation tokens
172

173
> [Introduced][ce-9099] in GitLab 9.0. Needs admin permissions.
174

175
Impersonation tokens are a type of [personal access token][pat]
Douwe Maan committed
176 177
that can only be created by an admin for a specific user. They are a great fit
if you want to build applications or scripts that authenticate with the API as a specific user.
178

Douwe Maan committed
179 180 181
They are an alternative to directly using the user's password or one of their
personal access tokens, and to using the [Sudo](#sudo) feature, since the user's (or admin's, in the case of Sudo)
password/token may not be known or may change over time.
182

183
For more information, refer to the
184
[users API](users.md#retrieve-user-impersonation-tokens) docs.
185

Douwe Maan committed
186 187
Impersonation tokens are used exactly like regular personal access tokens, and can be passed in either the
`private_token` parameter or the `Private-Token` header.
188

189
### Sudo
190

191
> Needs admin permissions.
192

193
All API requests support performing an API call as if you were another user,
Douwe Maan committed
194 195 196
provided you are authenticated as an administrator with an OAuth or Personal Access Token that has the `sudo` scope.

You need to pass the `sudo` parameter either via query string or a header with an ID/username of
197
the user you want to perform the operation as. If passed as a header, the
Douwe Maan committed
198
header name must be `Sudo`.
199

Douwe Maan committed
200
If a non administrative access token is provided, an error message will
201
be returned with status code `403`:
202 203 204

```json
{
205
  "message": "403 Forbidden - Must be admin to use sudo"
206 207 208
}
```

Douwe Maan committed
209 210 211 212 213 214 215 216 217 218 219
If an access token without the `sudo` scope is provided, an error message will
be returned with status code `403`:

```json
{
  "error": "insufficient_scope",
  "error_description": "The request requires higher privileges than provided by the access token.",
  "scope": "sudo"
}
```

220
If the sudo user ID or username cannot be found, an error message will be
221
returned with status code `404`:
222 223 224

```json
{
Douwe Maan committed
225
  "message": "404 User with ID or username '123' Not Found"
226 227 228
}
```

229 230 231 232
---

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

234
```
235
GET /projects?private_token=9koXpg98eAheJpvBs5tK&sudo=username
236
```
237

238
```shell
Douwe Maan committed
239
curl --header "Private-Token: 9koXpg98eAheJpvBs5tK" --header "Sudo: username" "https://gitlab.example.com/api/v4/projects"
240 241
```

242 243
Example of a valid API call and a request using cURL with sudo request,
providing an ID:
244

245
```
246
GET /projects?private_token=9koXpg98eAheJpvBs5tK&sudo=23
247
```
248

249
```shell
Douwe Maan committed
250
curl --header "Private-Token: 9koXpg98eAheJpvBs5tK" --header "Sudo: 23" "https://gitlab.example.com/api/v4/projects"
251
```
252

253 254 255 256 257 258 259 260 261 262 263 264
## 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. |
265 266
| `GET` / `PUT` | Return `200 OK` if the resource is accessed or modified successfully. The (modified) result is returned as JSON. |
| `DELETE` | Returns `204 No Content` if the resuource was deleted successfully. |
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281

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. |
282
| `412` | Indicates the request was denied. May happen if the `If-Unmodified-Since` header is provided when trying to delete a resource, which was modified in between. |
283 284
| `422 Unprocessable` | The entity could not be processed. |
| `500 Server Error` | While handling the request something went wrong server-side. |
285

Dmitriy Zaporozhets committed
286
## Pagination
Nihad Abbasov committed
287

288 289
Sometimes the returned result will span across many pages. When listing
resources you can pass the following parameters:
Nihad Abbasov committed
290

291 292
| Parameter | Description |
| --------- | ----------- |
293 294
| `page`    | Page number (default: `1`) |
| `per_page`| Number of items to list per page (default: `20`, max: `100`) |
Nihad Abbasov committed
295

296 297 298
In the example below, we list 50 [namespaces](namespaces.md) per page.

```bash
299
curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/namespaces?per_page=50
300 301
```

302
### Pagination Link header
303

304
[Link headers](http://www.w3.org/wiki/LinkHeader) are sent back with each
305 306
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.
307

308 309 310 311 312
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
313
curl --head --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/8/issues/8/notes?per_page=3&page=2
314 315
```

316 317 318 319 320 321 322 323
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
324
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"
325 326 327 328 329 330 331 332 333 334
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
335 336 337 338
```

### Other pagination headers

339 340 341 342 343 344 345 346 347 348
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 |
349

350 351
## Namespaced path encoding

352
If using namespaced API calls, make sure that the `NAMESPACE/PROJECT_NAME` is
353 354
URL-encoded.

355
For example, `/` is represented by `%2F`:
356 357

```
358 359 360 361 362 363 364 365 366 367 368 369
GET /api/v4/projects/diaspora%2Fdiaspora
```

## Branches & tags name encoding

If your branch or tag contains a `/`, make sure the branch/tag name is
URL-encoded.

For example, `/` is represented by `%2F`:

```
GET /api/v4/projects/1/branches/my%2Fbranch/commits
370 371
```

372
## `id` vs `iid`
Dmitriy Zaporozhets committed
373

374 375 376 377
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`.
378

379 380
| Parameter | Description |
| --------- | ----------- |
381 382
| `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` |
Dmitriy Zaporozhets committed
383

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

386
```
387
GET /projects/42/issues/:id
388
```
Dmitriy Zaporozhets committed
389

390 391
On the other hand, if you want to create a link to a web page you should use
the `iid`:
Dmitriy Zaporozhets committed
392

393
```
394
GET /projects/42/issues/:iid
395
```
396 397 398

## Data validation and error reporting

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

402 403
Such errors appear in two cases:

404
- A required attribute of the API request is missing, e.g., the title of an
405
  issue is not given
406
- An attribute did not pass the validation, e.g., user bio is too long
407 408 409

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

410
```
411 412 413 414 415 416
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
    "message":"400 (Bad request) \"title\" not given"
}
```
417

418 419
When a validation error occurs, error messages will be different. They will
hold all details of validation errors:
420

421
```
422 423 424 425 426 427 428
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
    "message": {
        "bio": [
            "is too long (maximum is 255 characters)"
        ]
429
    }
430 431
}
```
432

433 434
This makes error messages more machine-readable. The format can be described as
follows:
435

436 437 438 439 440 441 442 443 444
```json
{
    "message": {
        "<property-name>": [
            "<error-message>",
            "<error-message>",
            ...
        ],
        "<embed-entity>": {
445 446 447 448 449 450 451
            "<property-name>": [
                "<error-message>",
                "<error-message>",
                ...
            ],
        }
    }
452 453 454
}
```

455
## Unknown route
456

457
When you try to access an API URL that does not exist you will receive 404 Not Found.
458 459

```
460
HTTP/1.1 404 Not Found
461 462
Content-Type: application/json
{
463
    "error": "404 Not Found"
464 465 466
}
```

467 468 469
## Encoding `+` in ISO 8601 dates

If you need to include a `+` in a query parameter, you may need to use `%2B` instead due
Connor Shea committed
470
a [W3 recommendation](http://www.w3.org/Addressing/URL/4_URI_Recommentations.html) that
471 472 473 474 475 476 477 478 479 480 481 482 483
causes a `+` to be interpreted as a space. For example, in an ISO 8601 date, you may want to pass
a time in Mountain Standard Time, such as:

```
2017-10-17T23:11:13.000+05:30
```

The correct encoding for the query parameter would be:

```
2017-10-17T23:11:13.000%2B05:30
```

484 485 486
## Clients

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

489 490
[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
491
[ce-3749]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/3749
492
[ce-5951]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/5951
493
[ce-9099]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9099
494
[pat]: ../user/profile/personal_access_tokens.md