# Pages

export const searchPagesCurl = `curl https://api.afterlib.com/v1/pages/search \\
  -H "Authorization: Bearer $AFTERLIB_API_KEY" \\
  -H "Content-Type: application/json" \\
  -d '{
    "search": "running",
    "limit": 10,
    "sortBy": "performance",
    "sortDirection": "desc"
  }'`;

export const searchPagesJs = `const response = await fetch('https://api.afterlib.com/v1/pages/search', {
  method: 'POST',
  headers: {
    Authorization: \`Bearer \${process.env.AFTERLIB_API_KEY}\`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    search: 'running',
    limit: 10,
    sortBy: 'performance',
    sortDirection: 'desc',
  }),
});

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

export const searchPagesTs = `type PagesSearchRequest = {
  search?: string;
  limit?: number;
  cursor?: string;
  sortBy?: 'performance' | 'trend' | 'audienceReach' | 'pageLikes' | 'pageIgFollowers';
  sortDirection?: 'asc' | 'desc';
};

const body: PagesSearchRequest = {
  search: 'running',
  limit: 10,
  sortBy: 'performance',
  sortDirection: 'desc',
};

const response = await fetch('https://api.afterlib.com/v1/pages/search', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer ' + process.env.AFTERLIB_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(body),
});

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

export const searchPagesPhp = `$response = file_get_contents('https://api.afterlib.com/v1/pages/search', false, stream_context_create([
  'http' => [
    'method' => 'POST',
    'header' => [
      'Authorization: Bearer ' . getenv('AFTERLIB_API_KEY'),
      'Content-Type: application/json',
    ],
    'content' => json_encode([
      'search' => 'running',
      'limit' => 10,
      'sortBy' => 'performance',
      'sortDirection' => 'desc',
    ]),
  ],
]));

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

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

request = urllib.request.Request(
    'https://api.afterlib.com/v1/pages/search',
    data=json.dumps({
        'search': 'running',
        'limit': 10,
        'sortBy': 'performance',
        'sortDirection': 'desc',
    }).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'))`;

export const filteredPagesCurl = `curl https://api.afterlib.com/v1/pages/search \\
  -H "Authorization: Bearer $AFTERLIB_API_KEY" \\
  -H "Content-Type: application/json" \\
  -d '{
    "search": "running",
    "countries": {"include": ["US"], "operator": "or"},
    "technologies": {"include": ["shopify"], "operator": "or"},
    "audienceReach": {"gte": 1000000},
    "creationDate": {"gte": "2021-01-01"},
    "limit": 25
  }'`;

export const filteredPagesJs = `const response = await fetch('https://api.afterlib.com/v1/pages/search', {
  method: 'POST',
  headers: {
    Authorization: \`Bearer \${process.env.AFTERLIB_API_KEY}\`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    search: 'running',
    countries: {include: ['US'], operator: 'or'},
    technologies: {include: ['shopify'], operator: 'or'},
    audienceReach: {gte: 1000000},
    creationDate: {gte: '2021-01-01'},
    limit: 25,
  }),
});`;

export const filteredPagesTs = `type RangeFilter = {gte?: number; lte?: number};
type DateRangeFilter = {gte?: string; lte?: string};
type IncludeExcludeFilter = {
  include?: string[];
  exclude?: string[];
  operator?: 'or' | 'and' | 'exact';
};

type PagesSearchRequest = {
  search?: string;
  limit?: number;
  countries?: IncludeExcludeFilter;
  technologies?: IncludeExcludeFilter;
  audienceReach?: RangeFilter;
  creationDate?: DateRangeFilter;
};

const body: PagesSearchRequest = {
  search: 'running',
  countries: {include: ['US'], operator: 'or'},
  technologies: {include: ['shopify'], operator: 'or'},
  audienceReach: {gte: 1000000},
  creationDate: {gte: '2021-01-01'},
  limit: 25,
};

const response = await fetch('https://api.afterlib.com/v1/pages/search', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer ' + process.env.AFTERLIB_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(body),
});`;

export const filteredPagesPhp = `$response = file_get_contents('https://api.afterlib.com/v1/pages/search', false, stream_context_create([
  'http' => [
    'method' => 'POST',
    'header' => [
      'Authorization: Bearer ' . getenv('AFTERLIB_API_KEY'),
      'Content-Type: application/json',
    ],
    'content' => json_encode([
      'search' => 'running',
      'countries' => ['include' => ['US'], 'operator' => 'or'],
      'technologies' => ['include' => ['shopify'], 'operator' => 'or'],
      'audienceReach' => ['gte' => 1000000],
      'creationDate' => ['gte' => '2021-01-01'],
      'limit' => 25,
    ]),
  ],
]));`;

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

request = urllib.request.Request(
    'https://api.afterlib.com/v1/pages/search',
    data=json.dumps({
        'search': 'running',
        'countries': {'include': ['US'], 'operator': 'or'},
        'technologies': {'include': ['shopify'], 'operator': 'or'},
        'audienceReach': {'gte': 1000000},
        'creationDate': {'gte': '2021-01-01'},
        'limit': 25,
    }).encode('utf-8'),
    method='POST',
    headers={
        'Authorization': f"Bearer {os.environ['AFTERLIB_API_KEY']}",
        'Content-Type': 'application/json',
    },
)`;

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

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

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

export const getPageTs = `type GetPageRequest = {
  pageId: string;
};

const request: GetPageRequest = {
  pageId: '9000000000500',
};

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

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

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

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

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

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

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

## Search pages

Search pages with optional keyword, range, country, language, technology, and sorting filters. Returned page records include `appUrl`, a direct link to open that page in the AfterLib web app.

| Parameter | Location | Type | Default | Allowed values | Description |
| --- | --- | --- | --- | --- | --- |
| `search` | JSON body | string | none | up to 200 chars | Keyword search across public page fields. |
| `limit` | JSON body | number | `20` | `1` to `100` | Maximum pages returned. |
| `cursor` | JSON body | string | none | value from previous response | Fetch the next cursor page. |
| `sortBy` | JSON body | string | `performance` | `performance`, `trend`, `audienceReach`, `pageLikes`, `pageIgFollowers`, `adsTotalDuplicates`, `adsAmount`, `averageDuplicates`, `pageCreatedAt`, `audienceReachChangeP14`, `totalAdsChangeP14`, `uniqueAdsChangeP14` | Sort field. |
| `sortDirection` | JSON body | string | `desc` | `asc`, `desc` | Sort direction. |
| `textSearch` | JSON body | string or object | none | text string or field include/exclude object | Match text in specific public fields. |
| `performance`, `audienceReach`, `pageLikes`, `ads` | JSON body | object | none | `{ "gte": number, "lte": number }` | Numeric range filters. |
| `creationDate` | JSON body | object | none | `{ "gte": "YYYY-MM-DD", "lte": "YYYY-MM-DD" }` | Page creation date range. |
| `countries`, `languages`, `technologies` | JSON body | object | none | `{ "include": [], "exclude": [], "operator": "or" }` | Include/exclude filters. |

<ApiExampleTabs curl={searchPagesCurl} javascript={searchPagesJs} typescript={searchPagesTs} php={searchPagesPhp} python={searchPagesPython} />

Response:

```json
{
	"items": [
		{
			"pageId": "9000000000500",
			"metaPageExternalId": "9000000000500",
			"appUrl": "https://app.afterlib.com/pages/9000000000500",
			"pageName": "Drift Wellness Company",
			"pageLikes": 2778360,
			"pageIgFollowers": 992229,
			"pageCreatedAt": "2021-01-13T09:04:49.640Z",
			"adsAmount": 4,
			"adsTotalDuplicates": 1538,
			"audienceReach": 15436615,
			"averageDuplicates": 385,
			"performance": 84,
			"trend": 1,
			"countries": ["US", "CA"],
			"languages": ["eng"],
			"technologySlugs": ["shopify", "klaviyo"]
		}
	],
	"cursor": null,
	"hasMore": false,
	"totalHits": 1
}
```

## Search recipe: high-reach pages

Use page-level filters when you want accounts with enough audience scale and a specific commerce stack.

<ApiExampleTabs curl={filteredPagesCurl} javascript={filteredPagesJs} typescript={filteredPagesTs} php={filteredPagesPhp} python={filteredPagesPython} />

## Fetch one page

Fetch one page by Meta page ID.

| Parameter | Location | Type | Default | Allowed values | Description |
| --- | --- | --- | --- | --- | --- |
| `pageId` | path | string | required | positive page ID string | The page to fetch. |

<ApiExampleTabs curl={getPageCurl} javascript={getPageJs} typescript={getPageTs} php={getPagePhp} python={getPagePython} />

Response:

```json
{
	"pageId": "9000000000500",
	"appUrl": "https://app.afterlib.com/pages/9000000000500",
	"pageName": "Drift Wellness Company",
	"pageLikes": 2778360,
	"pageIgFollowers": 992229,
	"adsAmount": 4,
	"performance": 84,
	"countries": ["US", "CA"],
	"technologySlugs": ["shopify", "klaviyo"]
}
```

`POST /v1/pages/search` and `GET /v1/pages/{pageId}` can charge credits for returned unique pages. Save `X-Afterlib-Request-Id` when debugging unexpected results or credit charges.