# pai-image

Part of **PAI**

<!-- intent-backlink:auto -->

> 💡 **Path Selection**: This skill is one implementation path for [Train a machine learning model](../../intent/pai-train-model/SKILL.md). If you're unsure which path to take, check the routing skill first.

# Platform for AI (PAI) Image Management

## Capabilities Overview

| Sub-capability | Calling Mode | Description |
|----------------|--------------|-------------|
| AddImage | Synchronous | Adds a custom image to a workspace with metadata such as name, URI, labels, and accessibility. |
| GetImage | Synchronous | Retrieves detailed metadata of a specific image, optionally including non-essential fields like labels. |
| ListImages | Synchronous | Queries a paginated list of images with filtering by name, labels, workspace, or visibility. |
| PublishImage | Synchronous | Changes an image's visibility from PRIVATE to PUBLIC, making it accessible to all workspace members. |
| RemoveImage | Synchronous | Deletes an image from the workspace using its image ID. |

## API Calling Patterns

### Authentication
Use **Bearer Token** authentication as the primary method:
- Include the header: `Authorization: Bearer <your_api_key>`
- Store your API key in the environment variable: `DASHSCOPE_API_KEY`
- Example: `export DASHSCOPE_API_KEY=sk-xxxxxx`

While other Alibaba Cloud authentication methods exist (e.g., AccessKey), Bearer token is recommended for PAI Image Management APIs based on documentation examples.

### Service Endpoint
APIs use region-specific endpoints with the pattern:
```text
https://api.aliyun.com/api/AIWorkSpace/2021-02-04/{Action}
```
For international regions, use:
```text
https://api.alibabacloud.com/api/AIWorkSpace/2021-02-04/{Action}
```
Common regions include `cn-hangzhou`, `cn-shanghai`, and `cn-beijing`.

### Synchronous Request Pattern
All image management operations follow a synchronous REST pattern:
1. Send an HTTP request (POST, GET, PUT, or DELETE) to the appropriate endpoint
2. Include required parameters in the URL (GET/DELETE) or request body (POST)
3. Receive a JSON response immediately with results or error details
4. No polling or async handling is needed—responses are returned in a single round trip

## Parameter Reference

### AddImage

| Parameter | Type | Required | Default | Constraints | Description |
|-----------|------|----------|---------|-------------|-------------|
| Name | string | Yes | — | 1-50 chars, starts with letter, lowercase/digits/hyphens only | The image name, unique within the workspace |
| Description | string | No | — | — | The description of the image |
| ImageUri | string | Yes | — | — | The URI of the image (e.g., from Alibaba Cloud Container Registry) |
| Labels | array<object> | No | — | — | Array of key-value label objects; supports system-defined keys like `system.chipType` |
| WorkspaceId | string | No | — | — | The ID of the target workspace |
| Accessibility | string | No | — | one of: PUBLIC, PRIVATE | Visibility setting for the image |
| Size | integer | No | — | — | Image size in GB |
| ImageId | string | No | — | format: `image-` + 18 alphanumeric chars | Custom image ID; auto-generated if omitted |
| SourceType | string | No | — | — | — |
| SourceId | string | No | — | — | — |

### GetImage

| Parameter | Type | Required | Default | Constraints | Description |
|-----------|------|----------|---------|-------------|-------------|
| ImageId | string | Yes | — | — | The ID of the image to retrieve |
| Verbose | boolean | No | false | one of: false, true | Whether to include non-essential info like labels |

### ListImages

| Parameter | Type | Required | Default | Constraints | Description |
|-----------|------|----------|---------|-------------|-------------|
| Name | string | No | — | — | Fuzzy search by image name |
| PageNumber | integer | No | 1 | value starts from 1 | Page number for pagination |
| PageSize | integer | No | 20 | — | Number of entries per page (default 20) |
| SortBy | string | No | — | only GmtCreateTime supported | Field to sort by |
| Order | string | No | ASC | one of: ASC, DESC | Sort order |
| Labels | string | No | — | format: Key=Value, comma-separated | Label filter conditions |
| Verbose | boolean | No | — | one of: true, false | Include non-essential info like labels |
| WorkspaceId | string | No | — | — | Filter by workspace ID |
| Query | string | No | — | — | Fuzzy search by name and description |
| Accessibility | string | No | — | one of: PUBLIC, PRIVATE | Filter by visibility |
| ImageUri | string | No | — | — | — |

### PublishImage

| Parameter | Type | Required | Default | Constraints | Description |
|-----------|------|----------|---------|-------------|-------------|
| ImageId | string | Yes | — | — | The ID of the image to publish |

### RemoveImage

| Parameter | Type | Required | Default | Constraints | Description |
|-----------|------|----------|---------|-------------|-------------|
| ImageId | string | Yes | — | — | The ID of the image to delete |

## Code Examples

### Add a Custom Image - curl - all regions

```bash
curl -X POST https://api.aliyun.com/api/AIWorkSpace/2021-02-04/AddImage \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
  "Name": "nlp-compression",
  "Description": "NLP model compression training image",
  "ImageUri": "registry.cn-hangzhou.aliyuncs.com/pai-compression/nlp:gpu",
  "Labels": [
    {
      "Key": "system.chipType",
      "Value": "GPU"
    }
  ],
  "WorkspaceId": "15******45",
  "Accessibility": "PUBLIC",
  "Size": 2
}'
```

### Retrieve Image Details - curl - all regions

```bash
curl -X GET 'https://api.aliyun.com/api/AIWorkSpace/2021-02-04/GetImage?ImageId=image-4c62******53uor&Verbose=false' \
-H 'Authorization: Bearer $DASHSCOPE_API_KEY'
```

### List Images with Pagination - bash - all regions

```bash
curl -X GET 'https://api.aliyun.com/api/AIWorkSpace/2021-02-04/ListImages?WorkspaceId=20******55&PageNumber=1&PageSize=20' \
-H 'Authorization: Bearer $DASHSCOPE_API_KEY' \
-H 'Content-Type: application/json'
```

### Publish an Image - curl - all regions

```bash
curl -X PUT 'https://api.aliyun.com/api/AIWorkSpace/2021-02-04/images/image-dk******fa/publish' \
-H 'Authorization: Bearer $DASHSCOPE_API_KEY' \
-H 'Content-Type: application/json'
```

### Delete an Image - curl - all regions

```bash
curl -X DELETE https://api.aliyun.com/api/AIWorkSpace/2021-02-04/images/image-rbv******c9ks92 \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json"
```

## Response Format

```json
{
  "RequestId": "5A14FA81-DD4E-******-6343FE44B941",
  "ImageId": "image-4c62******53uor"
}
```

**Key Fields**:
- `RequestId` — Unique identifier for the API request, useful for troubleshooting
- `ImageId` — The ID of the created or published image
- `TotalCount` — Total number of images matching the query (in ListImages)
- `Images[]` — Array of image objects with metadata (in ListImages)
- `GmtCreateTime` — ISO 8601 timestamp of image creation

## Error Handling

| Error Code | Description | Recommended Action |
|------------|-------------|-------------------|
| 400 | Bad Request. The request parameters are invalid or missing. | Validate required parameters and constraints (e.g., Name format) |
| 401 | Unauthorized. The API key or credentials are invalid or not authorized to access this resource. | Check that `DASHSCOPE_API_KEY` is valid and has proper permissions |
| 403 | Forbidden. The user does not have sufficient permissions to perform this operation. | Verify RAM policy grants `pai:UpdateImage` or `pai:DeleteImage` as needed |
| 404 | Not Found. The specified workspace or image does not exist. | Confirm ImageId and WorkspaceId exist via ListImages or ListWorkspaces |
| 429 | Too Many Requests. Rate limit exceeded. Wait before retrying. | Implement exponential backoff; check quota limits |
| 500 | Internal Server Error. An unexpected error occurred on the server side. | Retry with jitter; contact support if persistent |
| 503 | Service Unavailable. The service is temporarily unavailable. | Retry after a short delay |
| InvalidParameter.WorkspaceId | The specified WorkspaceId is invalid or does not exist. | Use a valid WorkspaceId from ListWorkspaces |
| InvalidParameter.PageSize | The PageSize parameter must be between 1 and 100. | Set PageSize to a value in [1, 100] |
| InvalidImageId.NotFound | The specified image ID does not exist. | Verify ImageId using ListImages |
| UnauthorizedOperation | The user does not have sufficient permissions to delete the image. | Ensure your account has delete permissions for the image |

### Rate Limits & Retry
- AddImage, PublishImage, RemoveImage: 100 QPS per account
- GetImage, ListImages: up to 10 requests per second
- On 429 errors, use exponential backoff with jitter (e.g., wait 1s, 2s, 4s...) and respect any `Retry-After` header if present

## Environment Requirements

- Set your API key: `export DASHSCOPE_API_KEY=your_api_key_here`
- Use standard HTTP clients (curl, requests, etc.)—no special SDK required
- Ensure your environment can reach `api.aliyun.com` or `api.alibabacloud.com`

## FAQ

Q: How do I find my WorkspaceId?
A: Call the ListWorkspaces API or check the AI Workspace console under Workspace Settings.

Q: Can I reuse an ImageUri across multiple images?
A: Yes, the same ImageUri (e.g., from Container Registry) can be registered multiple times with different metadata.

Q: What labels are supported for filtering?
A: Supported label keys include `system.chipType`, `system.dsw.cudaVersion`, `system.framework`, `system.pythonVersion`, and others listed in the Labels parameter description.

Q: Why am I getting a 403 error when publishing an image?
A: Only the image creator can publish a PRIVATE image. Ensure you are the owner or have been granted explicit permissions.

Q: Is there a size limit for images?
A: The Size parameter is informational (in GB); actual storage limits depend on your Alibaba Cloud Container Registry quota.

## Pricing & Billing

### Billing Model
All image management APIs are billed **per request**, regardless of payload size or complexity.

### Price Reference

| Tier | Input Price | Output Price |
|------|-------------|--------------|
| AddImage | 0.001 / | — |
| GetImage | 0.001 / | 0.001 / |
| ListImages | 0.0001 / | 0.0001 / |
| PublishImage | 0.001 / | 0.001 / |
| RemoveImage | 0.001 / | — |

### Free Tier
- AddImage, PublishImage, RemoveImage: 100 free calls per month
- GetImage, ListImages: 1000 free requests per month
- Free tier resets monthly

### Usage Limits
- AddImage/PublishImage/RemoveImage: 100 QPS
- GetImage/ListImages: 10 requests per second
- ListImages PageSize: 1–100 entries per page

### Billing Notes
Each API call counts as one request. Free tier usage is tracked separately per operation type and resets at the beginning of each calendar month.