README.md 24.5 KB
Newer Older
E
Evan Read 已提交
1
# API Docs
N
Nihad Abbasov 已提交
2

E
Evan Read 已提交
3
Automate GitLab via a simple and powerful API.
4

5 6
The main GitLab API is a [REST](https://en.wikipedia.org/wiki/Representational_state_transfer) API. Therefore, documentation in this section assumes knowledge of REST concepts.

7 8
There is also a partial [OpenAPI definition](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/api/openapi/openapi.yaml), which allows you to test the API directly from the GitLab user interface. Contributions are welcome.

9
## Available API resources
E
Evan Read 已提交
10

E
Evan Read 已提交
11
For a list of the available resources and their endpoints, see
12
[API resources](api_resources.md).
E
Evan Read 已提交
13

14
## SCIM **(SILVER ONLY)**
15 16 17 18

[GitLab.com Silver and above](https://about.gitlab.com/pricing/) provides an [SCIM API](scim.md) that implements [the RFC7644 protocol](https://tools.ietf.org/html/rfc7644) and provides
the `/Users` endpoint. The base URL is: `/api/scim/v2/groups/:group_path/Users/`.

19 20
## Road to GraphQL

21 22 23 24
[GraphQL](graphql/index.md) is available in GitLab, which will
allow deprecation of controller-specific endpoints.

GraphQL has a number of benefits:
25 26

1. We avoid having to maintain two different APIs.
27 28
1. Callers of the API can request only what they need.
1. It is versioned by default.
29 30 31 32 33 34 35 36

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.
37

E
Evan Read 已提交
38
## Compatibility guidelines
39 40

The HTTP API is versioned using a single number, the current one being 4. This
E
Evan Read 已提交
41
number symbolizes the same as the major version number as described by
42 43
[SemVer](https://semver.org/). This mean that backward incompatible changes
will require this version number to change. However, the minor version is
44
not explicit. This allows for a stable API endpoint, but also means new
45 46 47
features can be added to the API in the same version number.

New features and bug fixes are released in tandem with a new GitLab, and apart
B
Bruce Szalwinski 已提交
48
from incidental patch and security releases, are released on the 22nd of each
49 50 51 52
month. Backward incompatible changes (e.g. endpoints removal, parameters
removal etc.), as well as removal of entire API versions are done in tandem
with a major point release of GitLab itself. All deprecations and changes
between two versions should be listed in the documentation. For the changes
53 54
between v3 and v4; please read the [v3 to v4 documentation](v3_to_v4.md)

55
### Current status
56

57
Currently only API version v4 is available. Version v3 was removed in
58
[GitLab 11.0](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/36819).
59

60 61 62
## Basic usage

API requests should be prefixed with `api` and the API version. The API version
63
is defined in [`lib/api.rb`](https://gitlab.com/gitlab-org/gitlab/tree/master/lib/api/api.rb). For example, the root of the v4 API
64
is at `/api/v4`.
65

D
Douwe Maan 已提交
66
Example of a valid API request using cURL:
67 68

```shell
D
Douwe Maan 已提交
69
curl "https://gitlab.example.com/api/v4/projects"
70 71 72 73 74
```

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

75
## Authentication
A
Achilleas Pipinellis 已提交
76

D
Douwe Maan 已提交
77 78
Most API requests require authentication, or will only return public data when
authentication is not provided. For
79
those cases where it is not required, this will be mentioned in the documentation
80
for each individual endpoint. For example, the [`/projects/:id` endpoint](projects.md#get-single-project).
81

82
There are several ways to authenticate with the GitLab API:
83

84
1. [OAuth2 tokens](#oauth2-tokens)
85 86
1. [Personal access tokens](../user/profile/personal_access_tokens.md)
1. [Project access tokens](../user/project/settings/project_access_tokens.md) **(CORE ONLY)**
D
Douwe Maan 已提交
87
1. [Session cookie](#session-cookie)
88
1. [GitLab CI/CD job token](#gitlab-ci-job-token) **(Specific endpoints only)**
D
Douwe Maan 已提交
89 90

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:
91

D
Douwe Maan 已提交
92
1. [Impersonation tokens](#impersonation-tokens)
93
1. [Sudo](#sudo)
N
Nihad Abbasov 已提交
94

95 96
If authentication information is invalid or omitted, an error message will be
returned with status code `401`:
N
Nihad Abbasov 已提交
97 98 99 100 101 102 103

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

D
Douwe Maan 已提交
104
### OAuth2 tokens
105

D
Douwe Maan 已提交
106 107
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.
108

D
Douwe Maan 已提交
109
Example of using the OAuth2 token in a parameter:
N
Nihad Abbasov 已提交
110

D
Douwe Maan 已提交
111
```shell
112
curl "https://gitlab.example.com/api/v4/projects?access_token=OAUTH-TOKEN"
D
Douwe Maan 已提交
113
```
114

D
Douwe Maan 已提交
115
Example of using the OAuth2 token in a header:
116

117
```shell
118
curl --header "Authorization: Bearer OAUTH-TOKEN" "https://gitlab.example.com/api/v4/projects"
119 120
```

D
Douwe Maan 已提交
121
Read more about [GitLab as an OAuth2 provider](oauth2.md).
122

123
### Personal/project access tokens
N
Nihad Abbasov 已提交
124

125
Access tokens can be used to authenticate with the API by passing it in either the `private_token` parameter
126
or the `PRIVATE-TOKEN` header.
V
Valery Sizov 已提交
127

128
Example of using the personal/project access token in a parameter:
V
Valery Sizov 已提交
129

D
Douwe Maan 已提交
130
```shell
131
curl "https://gitlab.example.com/api/v4/projects?private_token=<your_access_token>"
D
Douwe Maan 已提交
132 133
```

134
Example of using the personal/project access token in a header:
135

D
Douwe Maan 已提交
136
```shell
137
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects"
D
Douwe Maan 已提交
138
```
139

140
You can also use personal/project access tokens with OAuth-compliant headers:
141 142

```shell
143
curl --header "Authorization: Bearer <your_access_token>" "https://gitlab.example.com/api/v4/projects"
144 145
```

D
Douwe Maan 已提交
146 147 148 149 150
### 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.
151

D
Douwe Maan 已提交
152 153 154
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.
155

156
### GitLab CI job token
157

158
With a few API endpoints you can use a [GitLab CI/CD job token](../user/project/new_ci_build_permissions_model.md#job-token)
159 160
to authenticate with the API:

161
- [Get job artifacts](job_artifacts.md#get-job-artifacts)
162
- [Pipeline triggers](pipeline_triggers.md)
163
- [Release creation](releases/index.md#create-a-release)
164

165
### Impersonation tokens
V
Valery Sizov 已提交
166

167
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/9099) in GitLab 9.0. Needs admin permissions.
V
Valery Sizov 已提交
168

169
Impersonation tokens are a type of [personal access token](../user/profile/personal_access_tokens.md)
D
Douwe Maan 已提交
170 171
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.
172

D
Douwe Maan 已提交
173 174 175
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.
176

177
For more information, refer to the
178
[users API](users.md#create-an-impersonation-token) docs.
179

D
Douwe Maan 已提交
180
Impersonation tokens are used exactly like regular personal access tokens, and can be passed in either the
181
`private_token` parameter or the `PRIVATE-TOKEN` header.
182

I
Imre Farkas 已提交
183 184
#### Disable impersonation

185
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/40385) in GitLab 11.6.
I
Imre Farkas 已提交
186

187
By default, impersonation is enabled. To disable impersonation:
I
Imre Farkas 已提交
188 189 190 191 192

**For Omnibus installations**

1. Edit `/etc/gitlab/gitlab.rb`:

M
Marcel Amirault 已提交
193 194 195
   ```ruby
   gitlab_rails['impersonation_enabled'] = false
   ```
I
Imre Farkas 已提交
196 197 198 199 200 201 202 203 204 205

1. Save the file and [reconfigure](../administration/restart_gitlab.md#omnibus-gitlab-reconfigure)
   GitLab for the changes to take effect.

To re-enable impersonation, remove this configuration and reconfigure GitLab.

**For installations from source**

1. Edit `config/gitlab.yml`:

M
Marcel Amirault 已提交
206 207 208 209
   ```yaml
   gitlab:
     impersonation_enabled: false
   ```
I
Imre Farkas 已提交
210 211 212 213 214 215

1. Save the file and [restart](../administration/restart_gitlab.md#installations-from-source)
   GitLab for the changes to take effect.

To re-enable impersonation, remove this configuration and restart GitLab.

216
### Sudo
217

218
NOTE: **Note:**
E
Evan Read 已提交
219
Only available to [administrators](../user/permissions.md).
220

221
All API requests support performing an API call as if you were another user,
D
Douwe Maan 已提交
222
provided you are authenticated as an administrator with an OAuth or Personal Access Token that has the `sudo` scope.
223
The API requests are executed with the permissions of the impersonated user.
D
Douwe Maan 已提交
224 225

You need to pass the `sudo` parameter either via query string or a header with an ID/username of
226
the user you want to perform the operation as. If passed as a header, the
227
header name must be `Sudo`.
228 229 230

NOTE: **Note:**
Usernames are case insensitive.
231

D
Douwe Maan 已提交
232
If a non administrative access token is provided, an error message will
233
be returned with status code `403`:
234 235 236

```json
{
237
  "message": "403 Forbidden - Must be admin to use sudo"
238 239 240
}
```

D
Douwe Maan 已提交
241 242 243 244 245 246 247 248 249 250 251
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"
}
```

252
If the sudo user ID or username cannot be found, an error message will be
253
returned with status code `404`:
254 255 256

```json
{
D
Douwe Maan 已提交
257
  "message": "404 User with ID or username '123' Not Found"
258 259 260
}
```

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

264
```plaintext
265
GET /projects?private_token=<your_access_token>&sudo=username
266
```
267

268
```shell
269
curl --header "PRIVATE-TOKEN: <your_access_token>" --header "Sudo: username" "https://gitlab.example.com/api/v4/projects"
270 271
```

272 273
Example of a valid API call and a request using cURL with sudo request,
providing an ID:
274

275
```plaintext
276
GET /projects?private_token=<your_access_token>&sudo=23
277
```
278

279
```shell
280
curl --header "PRIVATE-TOKEN: <your_access_token>" --header "Sudo: 23" "https://gitlab.example.com/api/v4/projects"
281
```
282

283 284 285 286 287 288 289 290 291 292 293 294
## 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. |
R
Robert Schilling 已提交
295
| `GET` / `PUT` | Return `200 OK` if the resource is accessed or modified successfully. The (modified) result is returned as JSON. |
P
Pascal Borreli 已提交
296
| `DELETE` | Returns `204 No Content` if the resource was deleted successfully. |
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311

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. |
R
Robert Schilling 已提交
312
| `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. |
313 314
| `422 Unprocessable` | The entity could not be processed. |
| `500 Server Error` | While handling the request something went wrong server-side. |
315

D
Dmitriy Zaporozhets 已提交
316
## Pagination
N
Nihad Abbasov 已提交
317

318 319 320 321 322 323 324 325 326 327 328
We support two kinds of pagination methods:

- Offset-based pagination. This is the default method and available on all endpoints.
- Keyset-based pagination. Added to selected endpoints but being
  [progressively rolled out](https://gitlab.com/groups/gitlab-org/-/epics/2039).

For large collections, we recommend keyset pagination (when available) over offset
pagination for performance reasons.

### Offset-based pagination

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

332 333
| Parameter | Description |
| --------- | ----------- |
334 335
| `page`    | Page number (default: `1`) |
| `per_page`| Number of items to list per page (default: `20`, max: `100`) |
N
Nihad Abbasov 已提交
336

337 338
In the example below, we list 50 [namespaces](namespaces.md) per page.

339
```shell
340
curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/namespaces?per_page=50"
341 342
```

343
#### Pagination `Link` header
344

345 346
[`Link` headers](https://www.w3.org/wiki/LinkHeader) are sent back with each
response. They have `rel` set to `prev`/`next`/`first`/`last` and contain the relevant
347
URL. Please use these links instead of generating your own URLs.
348

349 350 351 352
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`:

353
```shell
354
curl --head --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/8/issues/8/notes?per_page=3&page=2"
355 356
```

357 358
The response will then be:

359
```http
360 361 362 363 364
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 已提交
365
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"
366 367 368 369 370 371 372 373 374 375
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
376 377
```

378
#### Other pagination headers
379

380 381 382 383 384 385 386 387 388 389
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 |
390

391 392
CAUTION: **Caution:**
For performance reasons since
393
[GitLab 11.8](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/23931)
394
and **behind the `api_kaminari_count_with_limit`
395
[feature flag](../development/feature_flags/index.md)**, if the number of resources is
396 397 398
more than 10,000, the `X-Total` and `X-Total-Pages` headers as well as the
`rel="last"` `Link` are not present in the response headers.

399 400 401 402 403 404 405 406 407 408 409 410 411 412
### Keyset-based pagination

Keyset-pagination allows for more efficient retrieval of pages and - in contrast to offset-based pagination - runtime
is independent of the size of the collection.

This method is controlled by the following parameters:

| Parameter    | Description                            |
| ------------ | -------------------------------------- |
| `pagination` | `keyset` (to enable keyset pagination) |
| `per_page`   | Number of items to list per page (default: `20`, max: `100`) |

In the example below, we list 50 [projects](projects.md) per page, ordered by `id` ascending.

413
```shell
414
curl --request GET --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects?pagination=keyset&per_page=50&order_by=id&sort=asc"
415 416 417 418
```

The response header includes a link to the next page. For example:

419
```http
420 421
HTTP/1.1 200 OK
...
422
Links: <https://gitlab.example.com/api/v4/projects?pagination=keyset&per_page=50&order_by=id&sort=asc&id_after=42>; rel="next"
423
Link: <https://gitlab.example.com/api/v4/projects?pagination=keyset&per_page=50&order_by=id&sort=asc&id_after=42>; rel="next"
424 425 426 427
Status: 200 OK
...
```

428
CAUTION: **Deprecation:**
429 430 431
The `Links` header will be removed in GitLab 14.0 to be aligned with the [W3C `Link` specification](https://www.w3.org/wiki/LinkHeader).
The `Link` header was [added in GitLab 13.1](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33714)
and should be used instead.
432

433 434 435
The link to the next page contains an additional filter `id_after=42` which excludes records we have retrieved already.
Note the type of filter depends on the `order_by` option used and we may have more than one additional filter.

436
When the end of the collection has been reached and there are no additional records to retrieve, the `Link` header is absent and the resulting array is empty.
437 438 439 440 441 442 443 444 445 446

We recommend using only the given link to retrieve the next page instead of building your own URL. Apart from the headers shown,
we don't expose additional pagination headers.

Keyset-based pagination is only supported for selected resources and ordering options:

| Resource                  | Order                      |
| ------------------------- | -------------------------- |
| [Projects](projects.md)   | `order_by=id` only         |

447 448 449 450 451 452 453 454 455 456
## Path parameters

If an endpoint has path parameters, the documentation shows them with a preceding colon.

For example:

```plaintext
DELETE /projects/:id/share/:group_id
```

457
The `:id` path parameter needs to be replaced with the project ID, and the `:group_id` needs to be replaced with the ID of the group. The colons `:` should not be included.
458

459
The resulting cURL call for a project with ID `5` and a group ID of `17` is then:
460 461

```shell
462
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/share/17"
463 464
```

465 466 467 468 469 470
NOTE: **Note:**
Path parameters that are required to be URL-encoded must be followed. If not,
it will not match an API endpoint and respond with a 404. If there's something
in front of the API (for example, Apache), ensure that it won't decode the URL-encoded
path parameters.

471 472
## Namespaced path encoding

N
Nathan Friend 已提交
473
If using namespaced API calls, make sure that the `NAMESPACE/PROJECT_PATH` is
474 475
URL-encoded.

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

478
```plaintext
479 480 481
GET /api/v4/projects/diaspora%2Fdiaspora
```

N
Nathan Friend 已提交
482
NOTE: **Note:**
483
A project's **path** is not necessarily the same as its **name**. A
484
project's path can be found in the project's URL or in the project's settings
N
Nathan Friend 已提交
485 486
under **General > Advanced > Change path**.

487
## File path, branches, and tags name encoding
488

489
If a file path, branch or tag contains a `/`, make sure it is URL-encoded.
490 491 492

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

493
```plaintext
494
GET /api/v4/projects/1/repository/files/src%2FREADME.md?ref=master
495
GET /api/v4/projects/1/branches/my%2Fbranch/commits
496
GET /api/v4/projects/1/repository/tags/my%2Ftag
497 498
```

499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
## Request Payload

API Requests can use parameters sent as [query strings](https://en.wikipedia.org/wiki/Query_string)
or as a [payload body](https://tools.ietf.org/html/draft-ietf-httpbis-p3-payload-14#section-3.2).
GET requests usually send a query string, while PUT/POST requests usually send the payload body:

- Query string:

  ```shell
  curl --request POST "https://gitlab/api/v4/projects?name=<example-name>&description=<example-description>"
  ```

- Request payload (JSON):

  ```shell
  curl --request POST --header "Content-Type: application/json" --data '{"name":"<example-name>", "description":"<example-description"}' "https://gitlab/api/v4/projects"
  ```

URL encoded query strings have a length limitation. Requests that are too large will
result in a `414 Request-URI Too Large` error message. This can be resolved by using
a payload body instead.

521 522
## Encoding API parameters of `array` and `hash` types

523
We can call the API with `array` and `hash` types parameters as shown below:
524 525 526 527 528

### `array`

`import_sources` is a parameter of type `array`:

529
```shell
530
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
531 532
-d "import_sources[]=github" \
-d "import_sources[]=bitbucket" \
533
https://gitlab.example.com/api/v4/some_endpoint
534 535 536 537 538 539
```

### `hash`

`override_params` is a parameter of type `hash`:

540
```shell
541
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
542 543 544 545 546 547 548 549
--form "namespace=email" \
--form "path=impapi" \
--form "file=@/path/to/somefile.txt"
--form "override_params[visibility]=private" \
--form "override_params[some_other_param]=some_value" \
https://gitlab.example.com/api/v4/projects/import
```

550 551
### Array of hashes

552
`variables` is a parameter of type `array` containing hash key/value pairs `[{ 'key': 'UPLOAD_TO_S3', 'value': 'true' }]`:
553

554
```shell
555
curl --globoff --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
556 557
"https://gitlab.example.com/api/v4/projects/169/pipeline?ref=master&variables[][key]=VAR1&variables[][value]=hello&variables[][key]=VAR2&variables[][value]=world"

558
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
559 560 561 562 563
--header "Content-Type: application/json" \
--data '{ "ref": "master", "variables": [ {"key": "VAR1", "value": "hello"}, {"key": "VAR2", "value": "world"} ] }' \
"https://gitlab.example.com/api/v4/projects/169/pipeline"
```

564
## `id` vs `iid`
D
Dmitriy Zaporozhets 已提交
565

E
Evan Read 已提交
566
 Some resources have two similarly-named fields. For example, [issues](issues.md), [merge requests](merge_requests.md), and [project milestones](merge_requests.md). The fields are:
567

568 569
- `id`: ID that is unique across all projects.
- `iid`: additional, internal ID that is unique in the scope of a single project.
570

571 572
NOTE: **Note:**
The `iid` is displayed in the web UI.
D
Dmitriy Zaporozhets 已提交
573

574
If a resource has the `iid` field and the `id` field, the `iid` field is usually used instead of `id` to fetch the resource.
575

576
For example, suppose a project with `id: 42` has an issue with `id: 46` and `iid: 5`. In this case:
D
Dmitriy Zaporozhets 已提交
577

578 579
- A valid API call to retrieve the issue is  `GET /projects/42/issues/5`
- An invalid API call to retrieve the issue is `GET /projects/42/issues/46`.
D
Dmitriy Zaporozhets 已提交
580

581
NOTE: **Note:**
582
Not all resources with the `iid` field are fetched by `iid`. For guidance on which field to use, see the documentation for the specific resource.
J
jubianchi 已提交
583 584 585

## Data validation and error reporting

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

J
jubianchi 已提交
589 590
Such errors appear in two cases:

591
- A required attribute of the API request is missing, e.g., the title of an
592
  issue is not given
593
- An attribute did not pass the validation, e.g., user bio is too long
J
jubianchi 已提交
594 595 596

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

597
```http
598 599 600 601 602 603
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
    "message":"400 (Bad request) \"title\" not given"
}
```
J
jubianchi 已提交
604

605 606
When a validation error occurs, error messages will be different. They will
hold all details of validation errors:
607

608
```http
609 610 611 612 613 614 615
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
    "message": {
        "bio": [
            "is too long (maximum is 255 characters)"
        ]
J
jubianchi 已提交
616
    }
617 618
}
```
J
jubianchi 已提交
619

620 621
This makes error messages more machine-readable. The format can be described as
follows:
J
jubianchi 已提交
622

623 624 625 626 627 628 629 630 631
```json
{
    "message": {
        "<property-name>": [
            "<error-message>",
            "<error-message>",
            ...
        ],
        "<embed-entity>": {
J
jubianchi 已提交
632 633 634 635 636 637 638
            "<property-name>": [
                "<error-message>",
                "<error-message>",
                ...
            ],
        }
    }
639 640 641
}
```

D
Dmitriy Zaporozhets 已提交
642
## Unknown route
643

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

646
```http
647
HTTP/1.1 404 Not Found
648
Content-Type: application/json
649
{
650
    "error": "404 Not Found"
651 652 653
}
```

654 655 656
## Encoding `+` in ISO 8601 dates

If you need to include a `+` in a query parameter, you may need to use `%2B` instead due
C
Cynthia Ng 已提交
657
to a [W3 recommendation](http://www.w3.org/Addressing/URL/4_URI_Recommentations.html) that
658 659 660
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:

661
```plaintext
662 663 664 665 666
2017-10-17T23:11:13.000+05:30
```

The correct encoding for the query parameter would be:

667
```plaintext
668 669 670
2017-10-17T23:11:13.000%2B05:30
```

671 672 673
## Clients

There are many unofficial GitLab API Clients for most of the popular
674
programming languages. Visit the [GitLab website](https://about.gitlab.com/partners/#api-clients) for a complete list.
675

M
Michael Kozono 已提交
676 677
## Rate limits

678
For administrator documentation on rate limit settings, see
M
Michael Kozono 已提交
679 680
[Rate limits](../security/rate_limits.md). To find the settings that are
specifically used by GitLab.com, see
681
[GitLab.com-specific rate limits](../user/gitlab_com/index.md#gitlabcom-specific-rate-limits).