# ARK SDK compatibility

If your stack already uses the official BytePlus ModelArk SDK for seedance, you can switch to XRToken by changing **two configuration values**:

1. **base URL**: `https://ark.ap-southeast.bytepluses.com/api/v3` → `https://api.xrtoken.ai/api/v3`. `/v1`, `/v3`, and `/api/v1` work the same.
2. **API key**: replace `ARK_API_KEY` with your XRToken `tr-` key

Request body, response body, and the SDK's URL composition all match the official spec. Keep the official `/api/v3` prefix — only the host has to change.

## What's covered

| Official ARK path | XRToken compatible endpoint | SDK drop-in |
|---|---|---|
| `POST /contents/generations/tasks` | `POST /api/v3/contents/generations/tasks` (same path under `/v1` `/v3` `/api/v1`) | ✅ |
| `GET /contents/generations/tasks/{id}` | `GET /api/v3/contents/generations/tasks/{id}` (same) | ✅ |
| `DELETE /contents/generations/tasks/{id}` | `DELETE /api/v3/contents/generations/tasks/{id}` (same) | ✅ |

The `id` returned by the create call is the upstream seedance task id (matches the official response), so subsequent polls and cancels with that id resolve the right row.

## Python SDK example

```python
from byteplussdkarkruntime import Ark

client = Ark(
    base_url="https://api.xrtoken.ai/api/v3",
    api_key="tr-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
)

resp = client.content_generation.tasks.create(
    model="doubao-seedance-2-0-260128",
    content=[
        {"type": "text", "text": "a kitten dashes across a meadow"}
    ],
)
print(resp.id)
```

## Asset library: official Open API format compatibility

The asset library uses the official Open API (`POST /?Action=...`), which normally requires AK/SK for SigV4 signing. Asset group / asset create, get, list, update, delete, and real-person verification all use the official `POST /?Action=...` path: point the base URL at us, swap the signing helper for a Bearer token, and keep the official request / response.

### What's covered

| Official Action | XRToken compatible endpoint | Auth | Notes |
|---|---|---|---|
| `Action=CreateAssetGroup` | `POST /?Action=CreateAssetGroup&Version=2024-01-01` | Bearer | request / response identical to official |
| `Action=CreateAsset` | `POST /?Action=CreateAsset&Version=2024-01-01` | Bearer | request / response identical to official |
| `Action=GetAssetGroup` | `POST /?Action=GetAssetGroup&Version=2024-01-01` | Bearer | request / response identical to official |
| `Action=GetAsset` | `POST /?Action=GetAsset&Version=2024-01-01` | Bearer | request / response identical to official |
| `Action=ListAssetGroups` | `POST /?Action=ListAssetGroups&Version=2024-01-01` | Bearer | request / response identical to official |
| `Action=ListAssets` | `POST /?Action=ListAssets&Version=2024-01-01` | Bearer | request / response identical to official |
| `Action=UpdateAssetGroup` | `POST /?Action=UpdateAssetGroup&Version=2024-01-01` | Bearer | request / response identical to official |
| `Action=UpdateAsset` | `POST /?Action=UpdateAsset&Version=2024-01-01` | Bearer | request / response identical to official |
| `Action=DeleteAssetGroup` | `POST /?Action=DeleteAssetGroup&Version=2024-01-01` | Bearer | request / response identical to official |
| `Action=DeleteAsset` | `POST /?Action=DeleteAsset&Version=2024-01-01` | Bearer | request / response identical to official |
| `Action=CreateVisualValidateSession` | `POST /?Action=CreateVisualValidateSession&Version=2024-01-01` | Bearer | request / response identical to official |
| `Action=GetVisualValidateResult` | `POST /?Action=GetVisualValidateResult&Version=2024-01-01` | Bearer | request / response identical to official |

Authentication:

- `Authorization: Bearer tr-xxx` (recommended)
- or `x-api-key: tr-xxx`

Example (create asset group):

```bash
curl -X POST "https://api.xrtoken.ai/?Action=CreateAssetGroup&Version=2024-01-01" \
  -H "Authorization: Bearer $XRT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "Name": "my asset group",
    "ProjectName": "default"
  }'
```

Example (create asset):

```bash
curl -X POST "https://api.xrtoken.ai/?Action=CreateAsset&Version=2024-01-01" \
  -H "Authorization: Bearer $XRT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "GroupId": "group-2026**********-*****",
    "URL": "https://example.com/image.jpg",
    "Name": "test",
    "AssetType": "Image",
    "ProjectName": "default"
  }'
```

`ProjectName` is optional: when omitted, the gateway project (currently `xrtoken`) is used automatically; when explicitly provided (including `default`), the value is passed through as-is. `Name` is optional on `CreateAsset`. Get asset group / asset:

```bash
curl -X POST "https://api.xrtoken.ai/?Action=GetAssetGroup&Version=2024-01-01" \
  -H "Authorization: Bearer $XRT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "Id": "group-2026**********-*****" }'
```

```bash
curl -X POST "https://api.xrtoken.ai/?Action=GetAsset&Version=2024-01-01" \
  -H "Authorization: Bearer $XRT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "Id": "asset-20260423183015-xk4m2" }'
```

List, delete, and real-person validation use the same `POST /?Action=...` path:

```bash
curl -X POST "https://api.xrtoken.ai/?Action=ListAssets&Version=2024-01-01" \
  -H "Authorization: Bearer $XRT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "Filter": { "GroupIds": ["group-2026**********-*****"] },
    "PageNumber": 1,
    "PageSize": 10
  }'
```

```bash
curl -X POST "https://api.xrtoken.ai/?Action=DeleteAsset&Version=2024-01-01" \
  -H "Authorization: Bearer $XRT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "Id": "asset-20260423183015-xk4m2" }'
```

```bash
curl -X POST "https://api.xrtoken.ai/?Action=CreateVisualValidateSession&Version=2024-01-01" \
  -H "Authorization: Bearer $XRT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```

Responses match the official envelope (`ResponseMetadata` / `Result`) and keep the asset library's tenant isolation: you can only operate on assets under groups you own.

Switch the signing helper to `Authorization: Bearer tr-xxx`; the request / response bodies require no changes.
