Skip to main content
When creating a customer portal, you can use the customer_resources_filters parameter to control which resources (property listings, reservations) are visible to the customer. Filters match against the custom_metadata you set on resources in customer_data.

How It Works

  1. Tag resources with custom_metadata — when passing property_listings or reservations in customer_data, include a custom_metadata object with key-value pairs on each resource.
  2. Set customer_resources_filters when creating the portal — provide an array of filter objects that specify which custom_metadata values a resource must have to be visible.
  3. Filtering is enforced server-side — the customer portal only returns resources whose custom_metadata matches all specified filters.

Filter Structure Reference

Each filter in the customer_resources_filters array is an object with the following fields:
FieldTypeDescription
fieldStringThe custom_metadata field name to filter on. Must start with a letter or underscore and contain only alphanumeric characters and underscores.
operationStringThe comparison operation. Currently only "=" (equals) is supported.
valueString or BooleanThe value to compare against.

Key Behaviors

  • AND logic — when multiple filters are provided, a resource must match all of them to be visible.
  • Exact match — the = operation performs an exact match against the custom_metadata value.
  • Server-side enforcement — filtering happens on the server. The customer portal API only returns matching resources.
  • Field name rules — field names must match the regex ^[a-zA-Z_]\w*$ (start with a letter or underscore, followed by alphanumeric characters or underscores).

Examples

Example 1: Filtering Property Listings by Region

Create property listings with a region field in custom_metadata, then filter to show only European properties.
const { customer_portal } = await seam.customers.createPortal({
  customer_data: {
    customer_key: 'customer_123',
    property_listings: [
      {
        name: 'Lisbon Apartment',
        property_listing_key: 'lisbon_apt',
        custom_metadata: { region: 'europe' },
      },
      {
        name: 'NYC Loft',
        property_listing_key: 'nyc_loft',
        custom_metadata: { region: 'north_america' },
      },
    ],
  },
  customer_resources_filters: [
    { field: 'region', operation: '=', value: 'europe' },
  ],
})

// The portal will only show "Lisbon Apartment"
console.log(customer_portal.url)

Example 2: Multiple Filters (AND Logic)

When you provide multiple filters, a resource must match all of them. Here, only property listings that are both premium and in Europe are shown.
const { customer_portal } = await seam.customers.createPortal({
  customer_data: {
    customer_key: 'customer_123',
    property_listings: [
      {
        name: 'Premium Villa',
        property_listing_key: 'premium_villa',
        custom_metadata: { is_premium: true, region: 'europe' },
      },
      {
        name: 'Standard Apartment',
        property_listing_key: 'standard_apt',
        custom_metadata: { is_premium: false, region: 'europe' },
      },
      {
        name: 'Premium Condo',
        property_listing_key: 'premium_condo',
        custom_metadata: { is_premium: true, region: 'north_america' },
      },
    ],
  },
  customer_resources_filters: [
    { field: 'is_premium', operation: '=', value: true },
    { field: 'region', operation: '=', value: 'europe' },
  ],
})

// Only "Premium Villa" is visible in the portal
console.log(customer_portal.url)

Example 3: Boolean Filters

Filter by a boolean custom_metadata value, such as showing only premium listings.
const { customer_portal } = await seam.customers.createPortal({
  customer_data: {
    customer_key: 'customer_123',
    property_listings: [
      {
        name: 'Premium Villa',
        property_listing_key: 'premium_villa',
        custom_metadata: { is_premium: true },
      },
      {
        name: 'Standard Apartment',
        property_listing_key: 'standard_apt',
        custom_metadata: { is_premium: false },
      },
    ],
  },
  customer_resources_filters: [
    { field: 'is_premium', operation: '=', value: true },
  ],
})

// Only "Premium Villa" is visible
console.log(customer_portal.url)

Example 4: Filtering Reservations

Filters also apply to reservations. Here, only reservations that are both premium and in Europe are shown.
const { customer_portal } = await seam.customers.createPortal({
  customer_data: {
    customer_key: 'customer_123',
    property_listings: [
      {
        name: 'Premium Villa',
        property_listing_key: 'premium_villa',
      },
    ],
    reservations: [
      {
        name: 'Premium EU Reservation',
        reservation_key: 'premium_eu_res',
        space_keys: ['premium_villa'],
        custom_metadata: { is_premium: true, region: 'europe' },
      },
      {
        name: 'Standard EU Reservation',
        reservation_key: 'standard_eu_res',
        space_keys: ['premium_villa'],
        custom_metadata: { is_premium: false, region: 'europe' },
      },
      {
        name: 'Premium US Reservation',
        reservation_key: 'premium_us_res',
        space_keys: ['premium_villa'],
        custom_metadata: { is_premium: true, region: 'north_america' },
      },
    ],
  },
  customer_resources_filters: [
    { field: 'is_premium', operation: '=', value: true },
    { field: 'region', operation: '=', value: 'europe' },
  ],
})

// Only "Premium EU Reservation" is visible in the portal
console.log(customer_portal.url)

Verifying Filters

After creating a portal, you can verify the configured filters by retrieving the portal via the customer API. The response includes customer_resources_filters in the portal configuration.
curl -X GET \
  'https://connect.getseam.com/seam/customer/v1/portals/get?customer_portal_id=PORTAL_ID' \
  -H 'Authorization: Bearer ${API_KEY}' \
  -H 'Content-Type: application/json'
The response will include the filters you configured:
{
  "customer_portal": {
    "customer_resources_filters": [
      { "field": "is_premium", "operation": "=", "value": true }
    ]
  }
}