2020-10-24 23:57:45 +05:30
---
stage: Create
group: Source Code
2022-11-25 23:54:43 +05:30
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
2020-10-24 23:57:45 +05:30
---
2023-05-27 22:25:52 +05:30
# Project import and export API **(FREE)**
2018-03-27 19:54:05 +05:30
2023-05-27 22:25:52 +05:30
Use the project import and export API to import and export projects using file transfers.
2020-03-13 15:44:24 +05:30
2023-05-27 22:25:52 +05:30
Before using the project import and export API, you might want to use the
[group import and export API ](group_import_export.md ).
2018-03-27 19:54:05 +05:30
2023-06-20 00:43:36 +05:30
## Prerequisites
For information on prerequisites for project import and export API, see:
- Prerequisites for [project export ](../user/project/settings/import_export.md#export-a-project-and-its-data ).
- Prerequisites for [project import ](../user/project/settings/import_export.md#import-a-project-and-its-data ).
2018-03-27 19:54:05 +05:30
## Schedule an export
Start a new export.
2022-08-27 11:52:29 +05:30
The endpoint also accepts an `upload` hash parameter. It contains all the necessary information to upload the exported
project to a web server or to any S3-compatible platform. For exports, GitLab:
- Only supports binary data file uploads to the final server.
- Sends the `Content-Type: application/gzip` header with upload requests. Ensure that your pre-signed URL includes this
as part of the signature.
- Can take some time to complete the project export process. Make sure the upload URL doesn't have a short expiration
time and is available throughout the export process.
- Administrators can modify the maximum export file size. By default, the maximum is unlimited (`0`). To change this,
edit `max_export_size` using either:
- [Application settings API ](settings.md#change-application-settings )
- [GitLab UI ](../user/admin_area/settings/account_and_limit_settings.md ).
2018-05-09 12:01:36 +05:30
2022-03-02 08:16:31 +05:30
The `upload[url]` parameter is required if the `upload` parameter is present.
2018-05-09 12:01:36 +05:30
2023-03-04 22:38:38 +05:30
For uploads to Amazon S3, refer to [Generating a pre-signed URL for uploading objects ](https://docs.aws.amazon.com/AmazonS3/latest/userguide/PresignedUrlUploadObject.html )
documentation scripts to generate the `upload[url]` .
2020-05-24 23:13:21 +05:30
```plaintext
2018-03-27 19:54:05 +05:30
POST /projects/:id/export
```
| Attribute | Type | Required | Description |
| --------- | -------------- | -------- | ---------------------------------------- |
2023-06-20 00:43:36 +05:30
| `id` | integer or string | yes | The ID or [URL-encoded path of the project ](rest/index.md#namespaced-path-encoding ) owned by the authenticated user.
| `upload[url]` | string | yes | The URL to upload the project.
| `description` | string | no | Overrides the project description.
| `upload` | hash | no | Hash that contains the information to upload the exported project to a web server.
| `upload[http_method]` | string | no | The HTTP method to upload the exported project. Only `PUT` and `POST` methods allowed. Default is `PUT` .
2018-03-27 19:54:05 +05:30
2020-03-13 15:44:24 +05:30
```shell
2023-06-20 00:43:36 +05:30
curl --request POST --header "PRIVATE-TOKEN: < your_access_token > " \
"https://gitlab.example.com/api/v4/projects/1/export" \
2018-11-18 11:00:15 +05:30
--data "upload[http_method]=PUT" \
--data-urlencode "upload[url]=https://example-bucket.s3.eu-west-3.amazonaws.com/backup?X-Amz-Algorithm=AWS4-HMAC-SHA256& X-Amz-Credential=AKIAIMBJHN2O62W8IELQ%2F20180312%2Feu-west-3%2Fs3%2Faws4_request& X-Amz-Date=20180312T110328Z& X-Amz-Expires=900& X-Amz-SignedHeaders=host& X-Amz-Signature=8413facb20ff33a49a147a0b4abcff4c8487cc33ee1f7e450c46e8f695569dbd"
2018-03-27 19:54:05 +05:30
```
```json
{
"message": "202 Accepted"
}
```
## Export status
Get the status of export.
2020-05-24 23:13:21 +05:30
```plaintext
2018-03-27 19:54:05 +05:30
GET /projects/:id/export
```
| Attribute | Type | Required | Description |
| --------- | -------------- | -------- | ---------------------------------------- |
2023-06-20 00:43:36 +05:30
| `id` | integer or string | yes | The ID or [URL-encoded path of the project ](rest/index.md#namespaced-path-encoding ) owned by the authenticated user.
2018-03-27 19:54:05 +05:30
2020-03-13 15:44:24 +05:30
```shell
2023-06-20 00:43:36 +05:30
curl --header "PRIVATE-TOKEN: < your_access_token > " \
"https://gitlab.example.com/api/v4/projects/1/export"
2018-03-27 19:54:05 +05:30
```
2020-03-13 15:44:24 +05:30
Status can be one of:
2021-09-04 01:27:46 +05:30
- `none` : No exports _queued_ , _started_ , _finished_ , or _being regenerated_ .
- `queued` : The request for export is received, and is in the queue to be processed.
- `started` : The export process has started and is in progress. It includes:
- The process of exporting.
- Actions performed on the resulting file, such as sending an email notifying
the user to download the file, or uploading the exported file to a web server.
- `finished` : After the export process has completed and the user has been notified.
- `regeneration_in_progress` : An export file is available to download, and a request to generate a new export is in process.
2020-11-24 15:15:51 +05:30
2018-03-27 19:54:05 +05:30
`_links` are only present when export has finished.
2020-11-24 15:15:51 +05:30
`created_at` is the project create timestamp, not the export start time.
2018-03-27 19:54:05 +05:30
```json
{
"id": 1,
"description": "Itaque perspiciatis minima aspernatur corporis consequatur.",
"name": "Gitlab Test",
"name_with_namespace": "Gitlab Org / Gitlab Test",
"path": "gitlab-test",
"path_with_namespace": "gitlab-org/gitlab-test",
"created_at": "2017-08-29T04:36:44.383Z",
"export_status": "finished",
"_links": {
"api_url": "https://gitlab.example.com/api/v4/projects/1/export/download",
2021-06-08 01:23:25 +05:30
"web_url": "https://gitlab.example.com/gitlab-org/gitlab-test/download_export"
2018-03-27 19:54:05 +05:30
}
}
```
## Export download
Download the finished export.
2020-05-24 23:13:21 +05:30
```plaintext
2018-03-27 19:54:05 +05:30
GET /projects/:id/export/download
```
2023-06-20 00:43:36 +05:30
| Attribute | Type | Required | Description |
| --------- | ----------------- | -------- | ---------------------------------------- |
| `id` | integer or string | yes | The ID or [URL-encoded path of the project ](rest/index.md#namespaced-path-encoding ) owned by the authenticated user.
2018-03-27 19:54:05 +05:30
2020-03-13 15:44:24 +05:30
```shell
2021-09-04 01:27:46 +05:30
curl --header "PRIVATE-TOKEN: < your_access_token > " --remote-header-name \
--remote-name "https://gitlab.example.com/api/v4/projects/5/export/download"
2018-03-27 19:54:05 +05:30
```
2020-03-13 15:44:24 +05:30
```shell
2018-03-27 19:54:05 +05:30
ls *export.tar.gz
2017-12-05_22-11-148_namespace_project_export.tar.gz
```
## Import a file
2020-05-24 23:13:21 +05:30
```plaintext
2018-03-27 19:54:05 +05:30
POST /projects/import
```
2023-06-20 00:43:36 +05:30
| Attribute | Type | Required | Description |
| ----------- | -------------- | -------- | ---------------------------------------- |
| `file` | string | yes | The file to be uploaded.
| `path` | string | yes | Name and path for new project.
| `name` | string | no | The name of the project to be imported. Defaults to the path of the project if not provided.
| `namespace` | integer or string | no | The ID or path of the namespace to import the project to. Defaults to the current user's namespace.< br />< br /> Requires at least the Maintainer role on the destination group to import to. Using the Developer role for this purpose was [deprecated ](https://gitlab.com/gitlab-org/gitlab/-/issues/387891 ) in GitLab 15.8 and is scheduled for removal in GitLab 16.0.
| `override_params` | Hash | no | Supports all fields defined in the [Project API ](projects.md ).
| `overwrite` | boolean | no | If there is a project with the same path the import overwrites it. Defaults to `false` .
2018-05-09 12:01:36 +05:30
2021-04-17 20:07:23 +05:30
The override parameters passed take precedence over all values defined inside the export file.
2018-03-27 19:54:05 +05:30
2018-10-15 14:42:47 +05:30
To upload a file from your file system, use the `--form` argument. This causes
2018-03-27 19:54:05 +05:30
cURL to post data using the header `Content-Type: multipart/form-data` .
2018-10-15 14:42:47 +05:30
The `file=` parameter must point to a file on your file system and be preceded
2018-03-27 19:54:05 +05:30
by `@` . For example:
2020-03-13 15:44:24 +05:30
```shell
2021-09-04 01:27:46 +05:30
curl --request POST --header "PRIVATE-TOKEN: < your_access_token > " --form "path=api-project" \
--form "file=@/path/to/file" "https://gitlab.example.com/api/v4/projects/import"
2018-03-27 19:54:05 +05:30
```
2022-07-23 23:45:48 +05:30
cURL doesn't support posting a file from a remote server. This example imports a project
using Python's `open` method:
2018-11-18 11:00:15 +05:30
```python
import requests
url = 'https://gitlab.example.com/api/v4/projects/import'
2022-07-23 23:45:48 +05:30
files = { "file": open("project_export.tar.gz", "rb") }
2018-11-18 11:00:15 +05:30
data = {
"path": "example-project",
"namespace": "example-group"
}
headers = {
2019-02-15 15:39:39 +05:30
'Private-Token': "< your_access_token > "
2018-11-18 11:00:15 +05:30
}
requests.post(url, headers=headers, data=data, files=files)
```
2018-03-27 19:54:05 +05:30
```json
{
"id": 1,
"description": null,
"name": "api-project",
"name_with_namespace": "Administrator / api-project",
"path": "api-project",
"path_with_namespace": "root/api-project",
"created_at": "2018-02-13T09:05:58.023Z",
2020-04-22 19:07:51 +05:30
"import_status": "scheduled",
"correlation_id": "mezklWso3Za",
"failed_relations": []
2018-03-27 19:54:05 +05:30
}
```
2021-02-22 17:27:13 +05:30
NOTE:
2023-06-20 00:43:36 +05:30
The maximum import file size can be set by the Administrator. It defaults to `0` (unlimited).
2023-03-04 22:38:38 +05:30
As an administrator, you can modify the maximum import file size. To do so, use the `max_import_size` option in the [Application settings API ](settings.md#change-application-settings ) or the [Admin Area ](../user/admin_area/settings/account_and_limit_settings.md ). Default [modified ](https://gitlab.com/gitlab-org/gitlab/-/issues/251106 ) from 50 MB to 0 in GitLab 13.8.
2020-06-23 00:09:42 +05:30
2023-06-20 00:43:36 +05:30
## Import a file from a remote object storage (Beta)
2021-06-08 01:23:25 +05:30
2023-06-20 00:43:36 +05:30
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/282503) in GitLab 13.12 in [Beta](../policy/alpha-beta-support.md#beta) [with a flag](../administration/feature_flags.md) named `import_project_from_remote_file`. Enabled by default.
2021-06-08 01:23:25 +05:30
2023-06-20 00:43:36 +05:30
FLAG:
On self-managed GitLab, by default this feature is available. To hide the feature, ask an administrator to [disable the feature flag ](../administration/feature_flags.md ) named `import_project_from_remote_file` .
On GitLab.com, this feature is available.
2021-06-08 01:23:25 +05:30
```plaintext
POST /projects/remote-import
```
2023-06-20 00:43:36 +05:30
| Attribute | Type | Required | Description |
| ----------------- | ----------------- | -------- | ---------------------------------------- |
| `path` | string | yes | Name and path for the new project.
| `url` | string | yes | URL for the file to import.
| `name` | string | no | The name of the project to import. If not provided, defaults to the path of the project.
| `namespace` | integer or string | no | The ID or path of the namespace to import the project to. Defaults to the current user's namespace.
| `overwrite` | boolean | no | Whether to overwrite a project with the same path when importing. Defaults to `false` .
| `override_params` | Hash | no | Supports all fields defined in the [Project API ](projects.md ).
2021-06-08 01:23:25 +05:30
The passed override parameters take precedence over all values defined in the export file.
```shell
curl --request POST \
--header "PRIVATE-TOKEN: < your_access_token > " \
2022-01-26 12:08:38 +05:30
--header "Content-Type: application/json" \
2021-06-08 01:23:25 +05:30
--url "https://gitlab.example.com/api/v4/projects/remote-import" \
--data '{"url":"https://remoteobject/file?token=123123","path":"remote-project"}'
```
```json
{
"id": 1,
"description": null,
"name": "remote-project",
"name_with_namespace": "Administrator / remote-project",
"path": "remote-project",
"path_with_namespace": "root/remote-project",
"created_at": "2018-02-13T09:05:58.023Z",
"import_status": "scheduled",
"correlation_id": "mezklWso3Za",
"failed_relations": [],
"import_error": null
}
```
2023-06-20 00:43:36 +05:30
The `Content-Length` header must return a valid number. The maximum file size is 10 GB.
2022-04-04 11:22:00 +05:30
The `Content-Type` header must be `application/gzip` .
2021-06-08 01:23:25 +05:30
2022-05-07 20:08:51 +05:30
## Import a file from AWS S3
2022-06-21 17:19:12 +05:30
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/348874) in GitLab 14.9 in [Beta](https://about.gitlab.com/handbook/product/gitlab-the-product/#beta), [with a flag](../administration/feature_flags.md) named `import_project_from_remote_file_s3`. Disabled by default.
> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/348874) in GitLab 14.10.
2023-06-20 00:43:36 +05:30
> - [Enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/350571) in GitLab 15.11. Feature flag `import_project_from_remote_file_s3` removed.
2022-05-07 20:08:51 +05:30
```plaintext
POST /projects/remote-import-s3
```
| Attribute | Type | Required | Description |
| ------------------- | -------------- | -------- | ---------------------------------------- |
2023-06-20 00:43:36 +05:30
| `access_key_id` | string | yes | [AWS S3 access key ID ](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys ).
| `bucket_name` | string | yes | [AWS S3 bucket name ](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html ) where the file is stored.
| `file_key` | string | yes | [AWS S3 file key ](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingObjects.html ) to identify the file.
| `path` | string | yes | The full path of the new project.
| `region` | string | yes | [AWS S3 region name ](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html#Regions ) where the file is stored.
| `secret_access_key` | string | yes | [AWS S3 secret access key ](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys ).
| `name` | string | no | The name of the project to import. If not provided, defaults to the path of the project.
| `namespace` | integer or string | no | The ID or path of the namespace to import the project to. Defaults to the current user's namespace.
2022-05-07 20:08:51 +05:30
The passed override parameters take precedence over all values defined in the export file.
```shell
curl --request POST \
2022-06-21 17:19:12 +05:30
--url "https://gitlab.example.com/api/v4/projects/remote-import-s3" \
2022-05-07 20:08:51 +05:30
--header "PRIVATE-TOKEN: < your gitlab access key > " \
--header 'Content-Type: application/json' \
--data '{
"name": "Sample Project",
"path": "sample-project",
"region": "< Your S3 region name > ",
"bucket_name": "< Your S3 bucket name > ",
"file_key": "< Your S3 file key > ",
"access_key_id": "< Your AWS access key id > ",
"secret_access_key": "< Your AWS secret access key > "
}'
```
2022-07-23 23:45:48 +05:30
This example imports from an Amazon S3 bucket, using a module that connects to Amazon S3:
```python
import requests
from io import BytesIO
s3_file = requests.get(presigned_url)
url = 'https://gitlab.example.com/api/v4/projects/import'
files = {'file': ('file.tar.gz', BytesIO(s3_file.content))}
data = {
"path": "example-project",
"namespace": "example-group"
}
headers = {
'Private-Token': "< your_access_token > "
}
requests.post(url, headers=headers, data=data, files=files)
```
2022-05-07 20:08:51 +05:30
```json
{
"id": 1,
"description": null,
"name": "Sample project",
"name_with_namespace": "Administrator / sample-project",
"path": "sample-project",
"path_with_namespace": "root/sample-project",
"created_at": "2018-02-13T09:05:58.023Z",
"import_status": "scheduled",
"correlation_id": "mezklWso3Za",
"failed_relations": [],
"import_error": null
}
```
2018-03-27 19:54:05 +05:30
## Import status
Get the status of an import.
2020-05-24 23:13:21 +05:30
```plaintext
2018-03-27 19:54:05 +05:30
GET /projects/:id/import
```
| Attribute | Type | Required | Description |
| --------- | -------------- | -------- | ---------------------------------------- |
2023-06-20 00:43:36 +05:30
| `id` | integer or string | yes | The ID or [URL-encoded path of the project ](rest/index.md#namespaced-path-encoding ) owned by the authenticated user.
2018-03-27 19:54:05 +05:30
2020-03-13 15:44:24 +05:30
```shell
2023-06-20 00:43:36 +05:30
curl --header "PRIVATE-TOKEN: < your_access_token > " \
"https://gitlab.example.com/api/v4/projects/1/import"
2018-03-27 19:54:05 +05:30
```
2020-03-13 15:44:24 +05:30
Status can be one of:
- `none`
- `scheduled`
- `failed`
- `started`
- `finished`
2018-03-27 19:54:05 +05:30
2021-04-17 20:07:23 +05:30
If the status is `failed` , it includes the import error message under `import_error` .
2020-04-22 19:07:51 +05:30
If the status is `failed` , `started` or `finished` , the `failed_relations` array might
2023-06-20 00:43:36 +05:30
be populated with any occurrences of relations that failed to import due to either:
- Unrecoverable errors.
- Retries were exhausted. A typical example: query timeouts.
2020-04-22 19:07:51 +05:30
2021-02-22 17:27:13 +05:30
NOTE:
2020-04-22 19:07:51 +05:30
An element's `id` field in `failed_relations` references the failure record, not the relation.
2021-02-22 17:27:13 +05:30
NOTE:
2021-09-04 01:27:46 +05:30
The `failed_relations` array is capped to 100 items.
2018-03-27 19:54:05 +05:30
```json
{
"id": 1,
"description": "Itaque perspiciatis minima aspernatur corporis consequatur.",
"name": "Gitlab Test",
"name_with_namespace": "Gitlab Org / Gitlab Test",
"path": "gitlab-test",
"path_with_namespace": "gitlab-org/gitlab-test",
"created_at": "2017-08-29T04:36:44.383Z",
2020-04-22 19:07:51 +05:30
"import_status": "started",
2022-01-26 12:08:38 +05:30
"import_type": "github",
2020-04-22 19:07:51 +05:30
"correlation_id": "mezklWso3Za",
"failed_relations": [
{
"id": 42,
"created_at": "2020-04-02T14:48:59.526Z",
"exception_class": "RuntimeError",
"exception_message": "A failure occurred",
"source": "custom error context",
2022-01-26 12:08:38 +05:30
"relation_name": "merge_requests",
"line_number": 0
2020-04-22 19:07:51 +05:30
}
]
2018-03-27 19:54:05 +05:30
}
```
2022-01-26 12:08:38 +05:30
When importing from GitHub, the a `stats` field lists how many objects were already fetched from
GitHub and how many were already imported:
```json
{
"id": 1,
"description": "Itaque perspiciatis minima aspernatur corporis consequatur.",
"name": "Gitlab Test",
"name_with_namespace": "Gitlab Org / Gitlab Test",
"path": "gitlab-test",
"path_with_namespace": "gitlab-org/gitlab-test",
"created_at": "2017-08-29T04:36:44.383Z",
"import_status": "started",
"import_type": "github",
"correlation_id": "mezklWso3Za",
"failed_relations": [
{
"id": 42,
"created_at": "2020-04-02T14:48:59.526Z",
"exception_class": "RuntimeError",
"exception_message": "A failure occurred",
"source": "custom error context",
"relation_name": "merge_requests",
"line_number": 0
}
],
"stats": {
"fetched": {
"diff_note": 19,
"issue": 3,
"label": 1,
"note": 3,
"pull_request": 2,
"pull_request_merged_by": 1,
"pull_request_review": 16
},
"imported": {
"diff_note": 19,
"issue": 3,
"label": 1,
"note": 3,
"pull_request": 2,
"pull_request_merged_by": 1,
"pull_request_review": 16
}
}
}
```
2023-06-20 00:43:36 +05:30
## Related topics
- [Migrating projects using file exports ](../user/project/settings/import_export.md ).
- [Project import and export Rake tasks ](../administration/raketasks/project_import_export.md ).