> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.partnerpage.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.partnerpage.io/_mcp/server.

# Build your own directory site

Use PartnerPage's public reads to show a partner directory on your own website. They provide the listings, filter options and partner profiles used by the hosted directory. These three reads require no API key. Keep private API keys out of browser code.

For authenticated reads, [create a read-only API key under Settings → Developers](https://directory.partnerpage.io/developers). Keep it on your server.

Replace `DIRECTORY_ID` with your directory's UUID. The API origin is `https://v1.api.partnerpage.io`.

## Load partner cards

```sh
curl --get 'https://v1.api.partnerpage.io/api/search/v1alpha/directories/DIRECTORY_ID/entries/' \
  --data-urlencode 'entry_type=partner' \
  --data-urlencode 'page_size=120' \
  --data-urlencode 'include=filter_options' \
  --data-urlencode 'ordering=title'
```

The response has `count`, `next`, `previous`, `facets` and `results`. `facets` is currently an empty object. Read cards from `results`: each includes `id`, `title`, `slug`, `icon` (logo), `image` (cover image), `headline`, `tier`, `featured` and other listing fields. Images may be null and an unassigned tier is an empty object.

`include=filter_options` adds `status` and `assignedFilterOptions` to each card. Each option has `id`, `name`, `slug`, `image`, `order` and its parent filter ID in `filter`. These include options from filters shown in the public filter bar or on profiles. Internal-only, deleted and fully hidden filters are excluded. Omit `include` when you do not need these extra fields.

One request returns up to 120 matching listings. If `next` is not null, follow that URL until it is null. Do not assume the first page contains the whole directory. The default page size is 5; sizes above 120 are capped. An empty, non-integer or non-positive `page_size` returns 400 with a `pageSize` error.

## Build filters and search

Fetch the filter bar's filters and their options:

```sh
curl 'https://v1.api.partnerpage.io/api/directory/public/v1alpha/directories/DIRECTORY_ID/filters/'
```

Use each filter's `filterOptions` to build your controls. `hasResults` indicates whether an option has a public listing. Match option IDs with a card's `assignedFilterOptions` for filtering a fully loaded public list on your own site, or request matching listings from the API:

```sh
curl --get 'https://v1.api.partnerpage.io/api/search/v1alpha/directories/DIRECTORY_ID/entries/' \
  --data-urlencode 'entry_type=partner' \
  --data-urlencode 'search=implementation' \
  --data-urlencode 'filters=(education,retail)(europe)' \
  --data-urlencode 'include=filter_options' \
  --data-urlencode 'page_size=120'
```

Replace the example option slugs with slugs from your filters response. A listing must match every parenthesized group and any option within a group. The example means education **or** retail, and Europe. Search checks names, headlines, descriptions, keywords, tiers and filter options. Malformed filter syntax returns 400.

Without a search or filter, the list returns `public` listings only. Applying either also includes `searchable` listings. A locally filtered public list therefore differs from a server search that may include searchable partners. Hidden and inactive listings are never returned.

Use `ordering=title` or `ordering=-title` for alphabetical order. Other supported values are `random`, `tier`, `-tier`, `tier_review`, `-tier_review`, `tier_review_average`, `-tier_review_average`, `recommended` and `relevance`; see the endpoint reference for their behavior. Empty or unknown ordering values return 400. For random order, follow `next` links to retain the same shuffle, or supply the same `seed` for each page.

Optional `featured=true` or `featured=false` selects featured or non-featured listings. `availability=true` selects available partners. Omit filters you do not need; blank featured/availability values are ignored for compatibility. Invalid boolean values return 400.

## Open a partner profile

Use the listing's current `slug`, including any custom slug:

```sh
curl 'https://v1.api.partnerpage.io/api/directory/public/v1alpha/directories/DIRECTORY_ID/entries/partners/slugs/PARTNER_SLUG/'
```

This returns the public profile, including its logo, cover image, tier, callouts, media and filter options. Use it when a visitor opens a partner, rather than making one details request for every card. Public and searchable partners are available; hidden, inactive or unknown slugs return 404. Where profile approval is enabled, partner edits wait in a draft until approved: visitors receive the last approved profile. Approving profile changes updates the approved profile; it does not publish a hidden partner or change its visibility.

Listing results may trail an edit by a few seconds. The profile read returns the latest approved data. A missing directory gives an empty listing; the filters read gives 404. Handle these outcomes and request errors explicitly in your interface.

Cache public GET responses for a short time and revalidate after publishing changes. Key caches by the complete request URL, including the directory, profile slug and query parameters, so one search, filter selection or page cannot return another's data. Do not mix authenticated or private API responses into a public browser, server or CDN cache.

## Before publishing your integration

Verify pagination with a directory larger than one page; missing logos and tiers; a custom partner slug; combined search and filters; and hidden/inactive partners. Read the endpoint references under **Public directory** in the API reference for complete schemas. These public reads do not grant write access or access to internal-directory data.