# Using the CardSight AI API - Collection Binders API

## Overview
Organize collection cards into virtual binders. Create themed binders to group cards by player, team, set, or any custom organization.

## Endpoint Details
- **Base URL**: `https://api.cardsight.ai/v1/collection/{collectionId}/binders`
- **Authentication**: API Key required (X-Api-Key header)

## Endpoints

| Method | URL | Description |
|--------|-----|-------------|
| GET | /v1/collection/{collectionId}/binders | List all binders in collection |
| POST | /v1/collection/{collectionId}/binders | Create a new binder |
| GET | /v1/collection/{collectionId}/binders/{binderId} | Get binder details |
| PUT | /v1/collection/{collectionId}/binders/{binderId} | Update binder |
| DELETE | /v1/collection/{collectionId}/binders/{binderId} | Delete binder |
| GET | /v1/collection/{collectionId}/binders/{binderId}/cards | List cards in binder |
| POST | /v1/collection/{collectionId}/binders/{binderId}/cards | Add card to binder |
| DELETE | /v1/collection/{collectionId}/binders/{binderId}/cards/{cardId} | Remove card from binder |

## List Binders Parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| collectionId | UUID | Yes | - | Collection UUID (path) |
| take | integer | No | 20 | Results per page (1-100) |
| skip | integer | No | 0 | Number of results to skip |
| name | string | No | - | Search by binder name (partial match) |
| sort | string | No | - | Field to sort by ("name") |
| order | string | No | "asc" | Sort order ("asc" or "desc") |

## Using the CardSight AI SDK (Recommended)

### Node.js / TypeScript
```typescript
import { CardSightAI } from 'cardsightai'

const client = new CardSightAI({ apiKey: 'your-api-key' })

const collectionId = '550e8400-e29b-41d4-a716-446655440000'

// List binders
const response = await client.collections.binders.list(collectionId, {
  take: 20,
  name: 'Rookies'
})

if (response.error) {
  console.error('Error:', response.error)
} else {
  console.log(`Total binders: ${response.data.total_count}`)
  for (const binder of response.data.binders) {
    console.log(`${binder.name}: ${binder.description || 'No description'}`)
  }
}

// Create a binder
const newBinder = await client.collections.binders.create(collectionId, {
  name: 'Rookie Stars',
  description: 'Top rookie cards from my collection'
})

if (!newBinder.error) {
  console.log(`Created binder: ${newBinder.data.id}`)
}

// Add card to binder
const binderId = newBinder.data.id
const addResult = await client.collections.binders.addCard(collectionId, binderId, {
  collectionCardId: '550e8400-e29b-41d4-a716-446655440001'
})

if (!addResult.error) {
  console.log(`Added card, link ID: ${addResult.data.id}`)
}

// List cards in binder
const binderCards = await client.collections.binders.cards(collectionId, binderId)

if (!binderCards.error) {
  for (const card of binderCards.data.cards) {
    console.log(`Card link: ${card.id}, Collection card: ${card.collectionCardId}`)
  }
}

// Remove card from binder (uses the binder-card link ID, not the collection card ID)
const binderCardId = addResult.data.id
await client.collections.binders.removeCard(collectionId, binderId, binderCardId)
```

### Python
```python
from cardsightai import CardSightAI

client = CardSightAI(api_key='your-api-key')

collection_id = '550e8400-e29b-41d4-a716-446655440000'

# List binders
response = client.collections.binders.list(collection_id)

for binder in response.binders:
    print(f"{binder.name}: {binder.id}")

# Create a binder
new_binder = client.collections.binders.create(collection_id,
    name='Rookie Stars',
    description='Top rookie cards'
)

# Add card to binder
client.collections.binders.add_card(
    collection_id,
    new_binder.id,
    collection_card_id='550e8400-e29b-41d4-a716-446655440001'
)
```

## Direct API Calls (cURL)

```bash
# List binders
curl -X GET "https://api.cardsight.ai/v1/collection/550e8400-e29b-41d4-a716-446655440000/binders" \
  -H "X-Api-Key: your-api-key"

# Create binder
curl -X POST "https://api.cardsight.ai/v1/collection/550e8400-e29b-41d4-a716-446655440000/binders" \
  -H "X-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{"name": "Rookie Stars", "description": "Top rookie cards"}'

# Add card to binder
curl -X POST "https://api.cardsight.ai/v1/collection/550e8400-e29b-41d4-a716-446655440000/binders/BINDER_ID/cards" \
  -H "X-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{"collectionCardId": "550e8400-e29b-41d4-a716-446655440001"}'

# Remove card from binder (uses the binder-card link ID)
curl -X DELETE "https://api.cardsight.ai/v1/collection/550e8400-e29b-41d4-a716-446655440000/binders/BINDER_ID/cards/BINDER_CARD_ID" \
  -H "X-Api-Key: your-api-key"
```

## Example Response (List Binders)
```json
{
  "binders": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440010",
      "collectionId": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Rookie Stars",
      "description": "Top rookie cards from my collection"
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440011",
      "collectionId": "550e8400-e29b-41d4-a716-446655440000",
      "name": "For Trade",
      "description": null
    }
  ],
  "total_count": 2,
  "skip": 0,
  "take": 20
}
```

## Example Response (Add Card to Binder)
```json
{
  "id": "550e8400-e29b-41d4-a716-446655440020",
  "binderId": "550e8400-e29b-41d4-a716-446655440010",
  "collectionCardId": "550e8400-e29b-41d4-a716-446655440001"
}
```

## Response Fields

### Paginated Binders Response

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| binders | array | Yes | Array of Binder objects |
| total_count | number | Yes | Total number of binders |
| skip | number | Yes | Number of results skipped |
| take | number | Yes | Number of results returned |

### Binder Object

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| id | UUID | Yes | Unique binder identifier |
| collectionId | UUID | Yes | ID of the collection this binder belongs to |
| name | string | No | Binder name |
| description | string | No | Binder description |

### BinderCard Object (returned when adding/listing cards)

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| id | UUID | Yes | Unique binder-card link identifier |
| binderId | UUID | Yes | ID of the binder |
| collectionCardId | UUID | Yes | ID of the collection card |

### Create/Update Binder Request

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| name | string | No | Binder name |
| description | string | No | Binder description |

### Add Card to Binder Request

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| collectionCardId | UUID | Yes | UUID of the collection card to add |

## Common Use Cases
- Organize cards by player or team
- Group cards for trading
- Create themed sub-collections
- Prepare cards for display or sale

## Tips for AI Assistants
- The SDK returns `{ data, error }` - always check for errors first
- URL uses singular "collection" not "collections": `/v1/collection/{collectionId}/binders`
- Binders reference cards in the parent collection via `collectionCardId`
- A card can be in multiple binders
- Deleting a binder doesn't delete the cards from the collection
- When removing a card from a binder, use the binder-card link `id` (from BinderCard), not the `collectionCardId`
- The `name` and `description` fields on Binder are optional
