← Artifacts / artifacts / api
REST API
Используйте REST API Artifacts для управления репозиториями, удаленными репозиториями, форками, импортом и токенами из внешних систем.
Проверьте Пространства имён сначала, затем выберите имя пространства имён, которое будете использовать в этих путях API.
Базовый URL-адрес и аутентификация
Маршруты REST API Artifacts используют следующий базовый путь:
https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/artifacts/namespaces/$ARTIFACTS_NAMESPACEЗапросы используют аутентификацию Bearer:
Authorization: Bearer $CLOUDFLARE_API_TOKENПути маршрутов ниже указаны относительно /accounts/$ACCOUNT_ID. В примерах с curl используется ARTIFACTS_BASE_URL или ARTIFACTS_ACCOUNT_BASE_URL чтобы сократить команды.
В следующих примерах предполагается:
export ACCOUNT_ID="<YOUR_ACCOUNT_ID>"
export ARTIFACTS_NAMESPACE="default"
export ARTIFACTS_REPO="starter-repo"
export CLOUDFLARE_API_TOKEN="<YOUR_API_TOKEN>"
export ARTIFACTS_BASE_URL="https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/artifacts/namespaces/$ARTIFACTS_NAMESPACE"
export ARTIFACTS_ACCOUNT_BASE_URL="https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/artifacts"Все ответы в формате JSON используют стандартную обёртку Cloudflare v4:
{
"result": {},
"success": true,
"errors": [],
"messages": []
}Успешные ответы типов blob, file и raw возвращают байты файла напрямую, а не в формате JSON. Например, GET /artifacts/namespaces/:namespace/repos/:name/file?ref=main&path=README.md возвращает содержимое README.md с Content-Type: application/octet-stream. Ответы с ошибками по прежнему используют стандартную обёртку:
{
"result": null,
"success": false,
"errors": [
{
"code": 10200,
"message": "File not found"
}
],
"messages": []
}Возвращённые токены репозитория являются секретами. Не записывайте их в журналы и не сохраняйте в долгоживущих удалённых репозиториях, если это не требуется для вашего рабочего процесса.
Общие типы
export type NamespaceName = string;
export type Jurisdiction = "eu" | "us";
export type RepoName = string;
export type BranchName = string;
export type Scope = "read" | "write";
export type TokenState = "active" | "expired" | "revoked";
export type ArtifactToken = string;
export type Cursor = string;
export type RepoSortField =
| "created_at"
| "updated_at"
| "last_push_at"
| "name";
export type SortDirection = "asc" | "desc";
export interface ApiError {
code: number;
message: string;
documentation_url?: string;
source?: {
pointer?: string;
};
}
export interface CursorResultInfo {
cursor: string;
per_page: number;
count: number;
}
export interface OffsetResultInfo {
page: number;
per_page: number;
total_pages: number;
count: number;
total_count: number;
}
export type ResultInfo = CursorResultInfo | OffsetResultInfo;
export interface ApiEnvelope<T> {
result: T | null;
success: boolean;
errors: ApiError[];
messages: ApiError[];
result_info?: ResultInfo;
}
export interface RepoInfo {
id: string;
name: RepoName;
description: string | null;
default_branch: string;
created_at: string;
updated_at: string;
last_push_at: string | null;
source: string | null;
read_only: boolean;
}
export interface RepoWithRemote extends RepoInfo {
remote: string;
}
export interface TokenInfo {
id: string;
scope: Scope;
state: TokenState;
created_at: string;
expires_at: string;
}Пространства имён
Создание пространства имён
Маршрут: POST /artifacts/namespaces
Используйте базовый URL уровня аккаунта.
Тело запроса:
namespaceNamespaceNameобязательноjurisdiction"eu" | "us"необязательно (по умолчанию: без ограничений)
curl --request POST "$ARTIFACTS_ACCOUNT_BASE_URL/namespaces" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"namespace": "my-eu-namespace",
"jurisdiction": "eu"
}'Юрисдикция применяется ко всем репозиториям в пространстве имён и не может быть изменена после создания. Если вы не укажете jurisdiction, Artifacts создаёт неограниченное пространство имён.
Подробнее см. в Локализация данных.
Список пространств имён
Маршрут: GET /artifacts/namespaces?limit=&cursor=
Используйте базовый URL уровня аккаунта.
curl "$ARTIFACTS_ACCOUNT_BASE_URL/namespaces?limit=20" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"Получить пространство имён
Маршрут: GET /artifacts/namespaces/:namespace
curl "$ARTIFACTS_ACCOUNT_BASE_URL/namespaces/$ARTIFACTS_NAMESPACE" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"Репозитории
Создание репозитория
Маршрут: POST /artifacts/namespaces/:namespace/repos
Тело запроса:
nameRepoNameобязательноdescriptionstringнеобязательноdefault_branchBranchNameнеобязательноread_onlybooleanнеобязательно
Тип ответа:
export interface CreateRepoRequest {
name: RepoName;
description?: string;
default_branch?: BranchName;
read_only?: boolean;
}
export interface CreateRepoResult {
id: string;
name: RepoName;
description: string | null;
default_branch: string;
remote: string;
token: ArtifactToken;
}
export type CreateRepoResponse = ApiEnvelope<CreateRepoResult>;curl --request POST "$ARTIFACTS_BASE_URL/repos" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"name": "starter-repo",
"description": "Repository for automation experiments",
"default_branch": "main",
"read_only": false
}'{
"result": {
"id": "repo_123",
"name": "starter-repo",
"description": "Repository for automation experiments",
"default_branch": "main",
"remote": "https://<ACCOUNT_ID>.artifacts.cloudflare.net/git/default/starter-repo.git",
"token": "art_v1_0123456789abcdef0123456789abcdef01234567?expires=1760000000"
},
"success": true,
"errors": [],
"messages": []
}Ответы на создание, форк и импорт возвращают только строку токена. Токен напрямую кодирует срок действия в ?expires= суффикс. Отдельный POST /tokens маршрут также возвращает expires_at вместе с токеном в открытом виде.
Список репозиториев
Маршрут: GET /artifacts/namespaces/:namespace/repos?limit=&cursor=&search=&sort=&direction=
Параметры запроса:
limitnumberнеобязательно (по умолчанию: 50, максимум: 200)cursorCursorнеобязательноsearchstringнеобязательноsort"created_at" | "updated_at" | "last_push_at" | "name"необязательно (по умолчанию: "created_at")direction"asc" | "desc"необязательно (по умолчанию: "desc")
Тип ответа:
export interface ListReposQuery {
limit?: number;
cursor?: Cursor;
search?: string;
sort?: RepoSortField;
direction?: SortDirection;
}
export type ListReposResponse = ApiEnvelope<RepoWithRemote[]>;curl "$ARTIFACTS_BASE_URL/repos?limit=20&sort=updated_at&direction=desc" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"{
"result": [
{
"id": "repo_123",
"name": "starter-repo",
"description": "Repository for automation experiments",
"default_branch": "main",
"created_at": "<ISO_TIMESTAMP>",
"updated_at": "<ISO_TIMESTAMP>",
"last_push_at": "<ISO_TIMESTAMP>",
"source": null,
"read_only": false,
"remote": "https://<ACCOUNT_ID>.artifacts.cloudflare.net/git/default/starter-repo.git"
}
],
"success": true,
"errors": [],
"messages": [],
"result_info": {
"cursor": "next-cursor",
"per_page": 20,
"count": 1
}
}Получить репозиторий
Маршрут: GET /artifacts/namespaces/:namespace/repos/:name
Тип ответа:
export type GetRepoResponse = ApiEnvelope<RepoWithRemote>;curl "$ARTIFACTS_BASE_URL/repos/$ARTIFACTS_REPO" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"{
"result": {
"id": "repo_123",
"name": "starter-repo",
"description": "Repository for automation experiments",
"default_branch": "main",
"created_at": "<ISO_TIMESTAMP>",
"updated_at": "<ISO_TIMESTAMP>",
"last_push_at": "<ISO_TIMESTAMP>",
"source": null,
"read_only": false,
"remote": "https://<ACCOUNT_ID>.artifacts.cloudflare.net/git/default/starter-repo.git"
},
"success": true,
"errors": [],
"messages": []
}Удаление репозитория
Маршрут: DELETE /artifacts/namespaces/:namespace/repos/:name
Этот маршрут возвращает 202 Accepted.
Тип ответа:
export interface DeleteRepoResult {
id: string;
}
export type DeleteRepoResponse = ApiEnvelope<DeleteRepoResult>;curl --request DELETE "$ARTIFACTS_BASE_URL/repos/$ARTIFACTS_REPO" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"{
"result": {
"id": "repo_123"
},
"success": true,
"errors": [],
"messages": []
}Создать форк репозитория
Маршрут: POST /artifacts/namespaces/:namespace/repos/:name/fork
Тело запроса:
nameRepoNameобязательноdescriptionstringнеобязательноread_onlybooleanнеобязательноdefault_branch_onlybooleanнеобязательно
Тип ответа:
export interface ForkRepoRequest {
name: RepoName;
description?: string;
read_only?: boolean;
default_branch_only?: boolean;
}
export interface ForkRepoResult extends CreateRepoResult {
objects: number;
}
export type ForkRepoResponse = ApiEnvelope<ForkRepoResult>;curl --request POST "$ARTIFACTS_BASE_URL/repos/$ARTIFACTS_REPO/fork" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"name": "starter-repo-copy",
"description": "Fork for testing",
"read_only": false,
"default_branch_only": true
}'{
"result": {
"id": "repo_456",
"name": "starter-repo-copy",
"description": "Repository for automation experiments",
"default_branch": "main",
"remote": "https://<ACCOUNT_ID>.artifacts.cloudflare.net/git/default/starter-repo-copy.git",
"token": "art_v1_89abcdef0123456789abcdef0123456789abcdef?expires=1760003600",
"objects": 128
},
"success": true,
"errors": [],
"messages": []
}Импортировать публичный удалённый репозиторий по HTTPS
Маршрут: POST /artifacts/namespaces/:namespace/repos/:name/import
Тело запроса:
urlstringобязательноbranchstringнеобязательноdepthnumberнеобязательноread_onlybooleanнеобязательно
Тип ответа:
export interface ImportRepoRequest {
url: string;
branch?: string;
depth?: number;
read_only?: boolean;
}
export type ImportRepoResponse = ApiEnvelope<CreateRepoResult>;Укажите полный удалённый URL-адрес Git по HTTPS, например https://github.com/facebook/react или https://gitlab.com/group/project.git.
curl --request POST "$ARTIFACTS_BASE_URL/repos/react-mirror/import" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"url": "https://github.com/facebook/react",
"branch": "main",
"depth": 100
}'{
"result": {
"id": "repo_789",
"name": "react-mirror",
"description": null,
"default_branch": "main",
"remote": "https://<ACCOUNT_ID>.artifacts.cloudflare.net/git/default/react-mirror.git",
"token": "art_v1_fedcba9876543210fedcba9876543210fedcba98?expires=1760007200"
},
"success": true,
"errors": [],
"messages": []
}Если репозиторий существует, но всё ещё импортируется или для него создаётся форк, этот маршрут может вернуть 409 Conflict с сообщением об ошибке, допускающей повтор.
Содержимое репозитория
Эти маршруты читают объекты Git и файлы из существующего репозитория. Маршруты для объектов используют неизменяемые хеши Git SHA-1. Маршруты для файлов определяют путь по ветке, тегу или хешу коммита.
Читайте историю коммитов
Маршрут: GET /artifacts/namespaces/:namespace/repos/:name/log?ref=&limit=&offset=
curl "$ARTIFACTS_BASE_URL/repos/$ARTIFACTS_REPO/log?ref=main&limit=10" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"Чтение коммита
Маршрут: GET /artifacts/namespaces/:namespace/repos/:name/commit/:hash
curl "$ARTIFACTS_BASE_URL/repos/$ARTIFACTS_REPO/commit/$COMMIT_HASH" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"Чтение дерева
Маршрут: GET /artifacts/namespaces/:namespace/repos/:name/tree/:hash
curl "$ARTIFACTS_BASE_URL/repos/$ARTIFACTS_REPO/tree/$TREE_HASH" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"Чтение blob-объекта
Маршрут: GET /artifacts/namespaces/:namespace/repos/:name/blob/:hash
Возвращает необработанные байты blob-объекта.
curl "$ARTIFACTS_BASE_URL/repos/$ARTIFACTS_REPO/blob/$BLOB_HASH" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"Чтение файла
Маршрут: GET /artifacts/namespaces/:namespace/repos/:name/file?ref=&path=
Возвращает необработанные байты файла в виде application/octet-stream.
curl "$ARTIFACTS_BASE_URL/repos/$ARTIFACTS_REPO/file?ref=main&path=README.md" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"Чтение необработанного файла
Маршрут: GET /artifacts/namespaces/:namespace/repos/:name/raw/:ref/:path
Возвращает байты файла с автоматически определённым Content-Type.
curl "$ARTIFACTS_BASE_URL/repos/$ARTIFACTS_REPO/raw/main/README.md" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"Токены
Эти токены предназначены для Git маршрутов. Они не аутентифицируют запросы REST API.
Список токенов репозитория
Маршрут: GET /artifacts/namespaces/:namespace/repos/:name/tokens?state=&per_page=&page=
Параметры запроса:
state"active" | "expired" | "revoked" | "all"необязательно (по умолчанию: "active")per_pagenumberнеобязательно (по умолчанию: 30, максимум: 100)pagenumberнеобязательно (по умолчанию: 1)
Тип ответа:
export interface ListTokensQuery {
state?: TokenState | "all";
per_page?: number;
page?: number;
}
export type ListTokensResponse = ApiEnvelope<TokenInfo[]>;curl "$ARTIFACTS_BASE_URL/repos/$ARTIFACTS_REPO/tokens?state=all&per_page=30&page=1" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"{
"result": [
{
"id": "0123456789abcdef",
"scope": "read",
"state": "active",
"created_at": "<ISO_TIMESTAMP>",
"expires_at": "<ISO_TIMESTAMP>"
}
],
"success": true,
"errors": [],
"messages": [],
"result_info": {
"page": 1,
"per_page": 30,
"total_pages": 1,
"count": 1,
"total_count": 1
}
}Создание токена
Маршрут: POST /artifacts/namespaces/:namespace/tokens
Тело запроса:
repoRepoNameобязательноscope"read" | "write"необязательно (по умолчанию: "write")ttlnumberнеобязательно : время жизни токена в секундах. Минимум 60 (1 минута), максимум 31,536,000 (1 год). По умолчанию 86,400 (24 часа).
Тип ответа:
export interface CreateTokenRequest {
repo: RepoName;
scope?: Scope;
ttl?: number;
}
export interface CreateTokenResult {
id: string;
plaintext: ArtifactToken;
scope: Scope;
expires_at: string;
}
export type CreateTokenResponse = ApiEnvelope<CreateTokenResult>;curl --request POST "$ARTIFACTS_BASE_URL/tokens" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"repo": "starter-repo",
"scope": "read",
"ttl": 3600
}'{
"result": {
"id": "0123456789abcdef",
"plaintext": "art_v1_0123456789abcdef0123456789abcdef01234567?expires=1760000000",
"scope": "read",
"expires_at": "<ISO_TIMESTAMP>"
},
"success": true,
"errors": [],
"messages": []
}Отзовите токен
Маршрут: DELETE /artifacts/namespaces/:namespace/tokens/:id
Тип ответа:
export interface DeleteTokenResult {
id: string;
}
export type DeleteTokenResponse = ApiEnvelope<DeleteTokenResult>;curl --request DELETE "$ARTIFACTS_BASE_URL/tokens/0123456789abcdef" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"{
"result": {
"id": "0123456789abcdef"
},
"success": true,
"errors": [],
"messages": []
}Ошибки
Ошибки приложения также используют обёртку v4:
export interface ApiError {
code: number;
message: string;
documentation_url?: string;
source?: {
pointer?: string;
};
}