# Collections

export const listCollectionsCurl = `curl https://api.afterlib.com/v1/collections \\
  -H "Authorization: Bearer $AFTERLIB_API_KEY"`;

export const listCollectionsJs = `const response = await fetch('https://api.afterlib.com/v1/collections', {
  headers: {Authorization: \`Bearer \${process.env.AFTERLIB_API_KEY}\`},
});

const collections = await response.json();`;

export const listCollectionsTs = `type ListCollectionsRequest = Record<string, never>;

const request: ListCollectionsRequest = {};

const response = await fetch('https://api.afterlib.com/v1/collections', {
  headers: {Authorization: 'Bearer ' + process.env.AFTERLIB_API_KEY},
});

const collections = await response.json();`;

export const listCollectionsPhp = `$response = file_get_contents('https://api.afterlib.com/v1/collections', false, stream_context_create([
  'http' => [
    'header' => 'Authorization: Bearer ' . getenv('AFTERLIB_API_KEY'),
  ],
]));

$collections = json_decode($response, true);`;

export const listCollectionsPython = `import json
import os
import urllib.request

request = urllib.request.Request(
    'https://api.afterlib.com/v1/collections',
    headers={'Authorization': f"Bearer {os.environ['AFTERLIB_API_KEY']}"},
)

with urllib.request.urlopen(request) as response:
    collections = json.loads(response.read().decode('utf-8'))`;

export const collectionItemsCurl = `curl "https://api.afterlib.com/v1/collections/019e6387-e2e9-7478-9d6d-170158c523b0/items?itemType=pages&limit=50" \\
  -H "Authorization: Bearer $AFTERLIB_API_KEY"`;

export const collectionItemsJs = `const response = await fetch(
  'https://api.afterlib.com/v1/collections/019e6387-e2e9-7478-9d6d-170158c523b0/items?itemType=pages&limit=50',
  {headers: {Authorization: \`Bearer \${process.env.AFTERLIB_API_KEY}\`}},
);

const items = await response.json();`;

export const collectionItemsTs = `type CollectionItemType = 'ads' | 'pages' | 'website_domains' | 'website_links';

type CollectionItemsRequest = {
  collectionId: string;
  itemType: CollectionItemType;
  limit?: number;
  cursor?: string;
};

const request: CollectionItemsRequest = {
  collectionId: '019e6387-e2e9-7478-9d6d-170158c523b0',
  itemType: 'pages',
  limit: 50,
};

const params = new URLSearchParams({
  itemType: request.itemType,
  limit: String(request.limit),
});

const response = await fetch(
  'https://api.afterlib.com/v1/collections/019e6387-e2e9-7478-9d6d-170158c523b0/items?' + params,
  {headers: {Authorization: 'Bearer ' + process.env.AFTERLIB_API_KEY}},
);

const items = await response.json();`;

export const collectionItemsPhp = `$response = file_get_contents('https://api.afterlib.com/v1/collections/019e6387-e2e9-7478-9d6d-170158c523b0/items?itemType=pages&limit=50', false, stream_context_create([
  'http' => [
    'header' => 'Authorization: Bearer ' . getenv('AFTERLIB_API_KEY'),
  ],
]));

$items = json_decode($response, true);`;

export const collectionItemsPython = `import json
import os
import urllib.request

request = urllib.request.Request(
    'https://api.afterlib.com/v1/collections/019e6387-e2e9-7478-9d6d-170158c523b0/items?itemType=pages&limit=50',
    headers={'Authorization': f"Bearer {os.environ['AFTERLIB_API_KEY']}"},
)

with urllib.request.urlopen(request) as response:
    items = json.loads(response.read().decode('utf-8'))`;

export const addCollectionItemCurl = `curl https://api.afterlib.com/v1/collections/019e6387-e2e9-7478-9d6d-170158c523b0/items \\
  -X POST \\
  -H "Authorization: Bearer $AFTERLIB_API_KEY" \\
  -H "Content-Type: application/json" \\
  -d '{
    "itemType": "pages",
    "itemId": "9000000000500"
  }'`;

export const addCollectionItemJs = `const response = await fetch(
  'https://api.afterlib.com/v1/collections/019e6387-e2e9-7478-9d6d-170158c523b0/items',
  {
    method: 'POST',
    headers: {
      Authorization: \`Bearer \${process.env.AFTERLIB_API_KEY}\`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      itemType: 'pages',
      itemId: '9000000000500',
    }),
  },
);

const result = await response.json();`;

export const addCollectionItemTs = `type CollectionItemType = 'ads' | 'pages' | 'website_domains' | 'website_links';

type AddCollectionItemRequest = {
  collectionId: string;
  body: {
    itemType: CollectionItemType;
    itemId: string;
  };
};

const request: AddCollectionItemRequest = {
  collectionId: '019e6387-e2e9-7478-9d6d-170158c523b0',
  body: {
    itemType: 'pages',
    itemId: '9000000000500',
  },
};

const response = await fetch(
  'https://api.afterlib.com/v1/collections/019e6387-e2e9-7478-9d6d-170158c523b0/items',
  {
    method: 'POST',
    headers: {
      Authorization: 'Bearer ' + process.env.AFTERLIB_API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(request.body),
  },
);

const result = await response.json();`;

export const addCollectionItemPhp = `$response = file_get_contents('https://api.afterlib.com/v1/collections/019e6387-e2e9-7478-9d6d-170158c523b0/items', false, stream_context_create([
  'http' => [
    'method' => 'POST',
    'header' => [
      'Authorization: Bearer ' . getenv('AFTERLIB_API_KEY'),
      'Content-Type: application/json',
    ],
    'content' => json_encode([
      'itemType' => 'pages',
      'itemId' => '9000000000500',
    ]),
  ],
]));

$result = json_decode($response, true);`;

export const addCollectionItemPython = `import json
import os
import urllib.request

request = urllib.request.Request(
    'https://api.afterlib.com/v1/collections/019e6387-e2e9-7478-9d6d-170158c523b0/items',
    data=json.dumps({
        'itemType': 'pages',
        'itemId': '9000000000500',
    }).encode('utf-8'),
    method='POST',
    headers={
        'Authorization': f"Bearer {os.environ['AFTERLIB_API_KEY']}",
        'Content-Type': 'application/json',
    },
)

with urllib.request.urlopen(request) as response:
    result = json.loads(response.read().decode('utf-8'))`;

Collections let members work with saved ad, page, website domain, and website link groups through the AfterLib API.

## List collections

<ApiExampleTabs curl={listCollectionsCurl} javascript={listCollectionsJs} typescript={listCollectionsTs} php={listCollectionsPhp} python={listCollectionsPython} />

Response:

```json
{
	"items": [
		{
			"id": "019e6387-e2e9-7478-9d6d-170158c523b0",
			"name": "Favorites",
			"appUrl": "https://app.afterlib.com/collections/019e6387-e2e9-7478-9d6d-170158c523b0",
			"type": "private",
			"isDefault": true,
			"defaultType": "favorites",
			"isOwner": true,
			"adCount": 1,
			"pageCount": 1,
			"websiteDomainCount": 1,
			"websiteLinkCount": 1
		}
	]
}
```

The response includes owned collections, accessible team collections, and visible default-style collections such as favorites when available. Hidden collections are not returned.

## Read collection items

| Parameter | Location | Type | Default | Allowed values | Description |
| --- | --- | --- | --- | --- | --- |
| `collectionId` | path | UUID string | required | collection UUID | The collection to read. |
| `itemType` | query | string | required | `ads`, `pages`, `website_domains`, `website_links` | The kind of item to return. |
| `limit` | query | number | `50` | `1` to `100` | Maximum items returned. |
| `cursor` | query | string | none | value from previous response | Fetch the next cursor page. |

<ApiExampleTabs curl={collectionItemsCurl} javascript={collectionItemsJs} typescript={collectionItemsTs} php={collectionItemsPhp} python={collectionItemsPython} />

Response:

```json
{
	"collection": {
		"id": "019e6387-e2e9-7478-9d6d-170158c523b0",
		"name": "Favorites",
		"appUrl": "https://app.afterlib.com/collections/019e6387-e2e9-7478-9d6d-170158c523b0",
		"type": "private",
		"isDefault": true,
		"defaultType": "favorites",
		"isOwner": true,
		"adCount": 1,
		"pageCount": 1,
		"websiteDomainCount": 1,
		"websiteLinkCount": 1
	},
	"itemType": "pages",
	"items": [
		{
			"pageId": "9000000000500",
			"appUrl": "https://app.afterlib.com/pages/9000000000500",
			"pageName": "Drift Wellness Company",
			"adsAmount": 4,
			"performance": 84
		}
	],
	"cursor": null,
	"hasMore": false
}
```

Website domain and website link collection reads are no-credit in this phase. Ad and page collection reads can charge viewing credits for returned unique records.

## Add a collection item

| Parameter | Location | Type | Default | Allowed values | Description |
| --- | --- | --- | --- | --- | --- |
| `collectionId` | path | UUID string | required | collection UUID | The collection to update. |
| `itemType` | JSON body | string | required | `ads`, `pages`, `website_domains`, `website_links` | The item kind. |
| `itemId` | JSON body | string | required | ad UUID, page ID, website domain UUID, or website link UUID | The item to save. |

<ApiExampleTabs curl={addCollectionItemCurl} javascript={addCollectionItemJs} typescript={addCollectionItemTs} php={addCollectionItemPhp} python={addCollectionItemPython} />

Response:

```json
{
	"collection": {
		"id": "019e6387-e2e9-7478-9d6d-170158c523b0",
		"name": "Favorites",
		"appUrl": "https://app.afterlib.com/collections/019e6387-e2e9-7478-9d6d-170158c523b0",
		"type": "private",
		"isDefault": true,
		"defaultType": "favorites",
		"isOwner": true,
		"adCount": 1,
		"pageCount": 1,
		"websiteDomainCount": 1,
		"websiteLinkCount": 1
	},
	"itemType": "pages",
	"itemId": "9000000000500",
	"added": true
}
```

The endpoint is idempotent. If the item already exists in the collection, the response returns `added: false`. Missing or inaccessible collections return `404` so collection existence is not leaked.