Curated Skills
by lstudlo

cloudflare

references/argo-smart-routing/api.md

.md 240 lines
Content
## API Reference

**Note on Smart Shield:** Argo Smart Routing is being integrated into Cloudflare's Smart Shield product. API endpoints remain stable; existing integrations continue to work without changes.

### Base Endpoint
```
https://api.cloudflare.com/client/v4
```

### Authentication
Use API tokens with Zone:Argo Smart Routing:Edit permissions:

```bash
# Headers required
X-Auth-Email: user@example.com
Authorization: Bearer YOUR_API_TOKEN
```

### Get Argo Smart Routing Status

**Endpoint:** `GET /zones/{zone_id}/argo/smart_routing`

**Description:** Retrieves current Argo Smart Routing enablement status.

**cURL Example:**
```bash
curl -X GET "https://api.cloudflare.com/client/v4/zones/{zone_id}/argo/smart_routing" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json"
```

**Response:**
```json
{
  "result": {
    "id": "smart_routing",
    "value": "on",
    "editable": true,
    "modified_on": "2024-01-11T12:00:00Z"
  },
  "success": true,
  "errors": [],
  "messages": []
}
```

**TypeScript SDK Example:**
```typescript
import Cloudflare from 'cloudflare';

const client = new Cloudflare({
  apiToken: process.env.CLOUDFLARE_API_TOKEN
});

const status = await client.argo.smartRouting.get({ zone_id: 'your-zone-id' });
console.log(`Argo status: ${status.value}, editable: ${status.editable}`);
```

**Python SDK Example:**
```python
from cloudflare import Cloudflare

client = Cloudflare(api_token=os.environ.get('CLOUDFLARE_API_TOKEN'))

status = client.argo.smart_routing.get(zone_id='your-zone-id')
print(f"Argo status: {status.value}, editable: {status.editable}")
```

### Update Argo Smart Routing Status

**Endpoint:** `PATCH /zones/{zone_id}/argo/smart_routing`

**Description:** Enable or disable Argo Smart Routing for a zone.

**Request Body:**
```json
{
  "value": "on"  // or "off"
}
```

**cURL Example:**
```bash
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/{zone_id}/argo/smart_routing" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"value": "on"}'
```

**TypeScript SDK Example:**
```typescript
const result = await client.argo.smartRouting.edit({
  zone_id: 'your-zone-id',
  value: 'on',
});
console.log(`Updated: ${result.value} at ${result.modified_on}`);
```

**Python SDK Example:**
```python
result = client.argo.smart_routing.edit(
    zone_id='your-zone-id',
    value='on'
)
print(f"Updated: {result.value} at {result.modified_on}")
```

## Checking Editability Before Updates

**Critical:** Always check the `editable` field before attempting to enable/disable Argo. When `editable: false`, the zone has restrictions (billing not configured, insufficient permissions, or plan limitations).

**Pattern:**
```typescript
async function safelyEnableArgo(client: Cloudflare, zoneId: string): Promise<boolean> {
  const status = await client.argo.smartRouting.get({ zone_id: zoneId });
  
  if (!status.editable) {
    console.error('Cannot modify Argo: editable=false (check billing/permissions)');
    return false;
  }
  
  if (status.value === 'on') {
    console.log('Argo already enabled');
    return true;
  }
  
  await client.argo.smartRouting.edit({ zone_id: zoneId, value: 'on' });
  console.log('Argo enabled successfully');
  return true;
}
```

**Python Pattern:**
```python
def safely_enable_argo(client: Cloudflare, zone_id: str) -> bool:
    status = client.argo.smart_routing.get(zone_id=zone_id)
    
    if not status.editable:
        print('Cannot modify Argo: editable=false (check billing/permissions)')
        return False
    
    if status.value == 'on':
        print('Argo already enabled')
        return True
    
    client.argo.smart_routing.edit(zone_id=zone_id, value='on')
    print('Argo enabled successfully')
    return True
```

## Error Handling

The TypeScript SDK provides typed error classes for robust error handling:

```typescript
import Cloudflare from 'cloudflare';
import { APIError, APIConnectionError, RateLimitError } from 'cloudflare';

async function enableArgoWithErrorHandling(client: Cloudflare, zoneId: string) {
  try {
    const result = await client.argo.smartRouting.edit({
      zone_id: zoneId,
      value: 'on',
    });
    return result;
  } catch (error) {
    if (error instanceof RateLimitError) {
      console.error('Rate limited. Retry after:', error.response?.headers.get('retry-after'));
      // Implement exponential backoff
    } else if (error instanceof APIError) {
      console.error('API error:', error.status, error.message);
      if (error.status === 403) {
        console.error('Permission denied - check API token scopes');
      } else if (error.status === 400) {
        console.error('Bad request - verify zone_id and payload');
      }
    } else if (error instanceof APIConnectionError) {
      console.error('Connection failed:', error.message);
      // Retry with exponential backoff
    } else {
      console.error('Unexpected error:', error);
    }
    throw error;
  }
}
```

**Python Error Handling:**
```python
from cloudflare import Cloudflare, APIError, RateLimitError

def enable_argo_with_error_handling(client: Cloudflare, zone_id: str):
    try:
        result = client.argo.smart_routing.edit(zone_id=zone_id, value='on')
        return result
    except RateLimitError as e:
        print(f"Rate limited. Retry after: {e.response.headers.get('retry-after')}")
        raise
    except APIError as e:
        print(f"API error: {e.status} - {e.message}")
        if e.status == 403:
            print('Permission denied - check API token scopes')
        elif e.status == 400:
            print('Bad request - verify zone_id and payload')
        raise
    except Exception as e:
        print(f"Unexpected error: {e}")
        raise
```

## Response Schema

All Argo Smart Routing API responses follow this structure:

```typescript
interface ArgoSmartRoutingResponse {
  result: {
    id: 'smart_routing';
    value: 'on' | 'off';
    editable: boolean;
    modified_on: string; // ISO 8601 timestamp
  };
  success: boolean;
  errors: Array<{
    code: number;
    message: string;
  }>;
  messages: Array<string>;
}
```

## Key Response Fields

| Field | Type | Description |
|-------|------|-------------|
| `value` | `"on" \| "off"` | Current enablement status |
| `editable` | `boolean` | Whether changes are allowed (check before PATCH) |
| `modified_on` | `string` | ISO timestamp of last modification |
| `success` | `boolean` | Whether request succeeded |
| `errors` | `Array` | Error details if `success: false`