Skip to main content

Visibility rules

A visibility rule is a server-evaluated condition that controls whether a given deal is shown. Rules attach to a deal and combine partner-level dimensions (partner and partner type) with per-member dimensions (the user's type(s) and region(s)). Where each dimension applies depends on the endpoint: the partner-scoped catalogue listing (GET /v1/deals) evaluates only the partner-level dimensions — it has no end user in scope — while the per-member dimensions are enforced where a member is in scope, namely the hosted end-user listing and GET /v1/deals/{id}/instructions.

:::info Portal-API endpoint Visibility-rule management lives under /v1/portal/*. The endpoint accepts either a Firebase ID token (used by the partner-portal UI) or your Partner API JWT — so partners can manage rules programmatically alongside the dashboard. :::

Request shape

Every create call uses the same body:

{
"deal_id": "018e4b2a-0000-7def-abcd-000000000010",
"rule_type": "include_region",
"rule_value": ["Europe", "North America"],
"priority": 0
}
FieldTypeRequiredNotes
deal_iduuidYesThe deal the rule applies to
rule_typeenumYesOne of the include/exclude variants below
rule_valuearray of stringYesOperand values — semantics depend on rule_type
priorityintegerNoEvaluation order (default 0)

Common patterns

Region-locked deal

Only show this deal to users in Europe or North America:

curl -X POST https://perks.founderpass.com/v1/portal/deals/{deal_id}/visibility-rules \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"deal_id": "{deal_id}",
"rule_type": "include_region",
"rule_value": ["Europe", "North America"],
"priority": 0
}'

Hide a deal from a specific user type

Block the deal for users tagged "Idea stage":

{
"deal_id": "{deal_id}",
"rule_type": "exclude_user_type",
"rule_value": ["Idea stage"],
"priority": 0
}

Allow only certain partner types

Useful when configuring a global deal that should only reach accelerators and incubators:

{
"deal_id": "{deal_id}",
"rule_type": "include_partner_type",
"rule_value": ["Accelerator", "Incubator"],
"priority": 0
}

Updating and deleting rules

# Update — body is partial; only send the fields you want to change
curl -X PATCH {API_BASE}/v1/portal/visibility-rules/{rule_id} \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "rule_value": ["Europe"], "priority": 1 }'

# Delete
curl -X DELETE {API_BASE}/v1/portal/visibility-rules/{rule_id} \
-H "Authorization: Bearer $TOKEN"

Rule types

All rule types follow the same include_* / exclude_* pattern. Include means "only these"; exclude means "everyone except these".

rule_typerule_value containsBehaviour
include_partnerPartner UUIDsShow only to listed partners
exclude_partnerPartner UUIDsHide from listed partners
include_partner_typePartnerType valuesShow only to these partner types
exclude_partner_typePartnerType valuesHide from these partner types
include_regionAudienceRegion valuesShow only in listed regions
exclude_regionAudienceRegion valuesHide from listed regions
include_user_typeUserType valuesShow only to these user types
exclude_user_typeUserType valuesHide from these user types

:::warning Regions are named, not ISO codes AudienceRegion values are named regions (Europe, North America, Asia, ...) — not ISO 3166-1 country codes. See Enumerations for the full list. :::

How rules combine

Multiple rules on the same deal AND together — the user must satisfy every rule to see the deal. To express OR within one dimension (e.g. "Europe or North America"), put both values in a single rule's rule_value array.

Toggling a global deal on or off

If you just want to hide a global FounderPass deal from your portal without writing a rule, use the per-deal visibility toggle:

curl -X PATCH https://perks.founderpass.com/v1/portal/deals/{deal_id}/visibility \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "visible": false }'

See the API Reference for the full response schemas.

api_excluded vs other controls

Three different mechanisms can keep a deal out of a listing. They operate at different scopes — don't confuse them:

ControlWho sets itScopeEffect
Visibility rulesPartner (this guide)Per-deal, per-segmentGate a deal by partner, partner type, region, or user type
Visibility toggle (partner_deal_visibility)PartnerPer-deal, per-partnerHide a single global deal from your portal — affects both the hosted app and the Partner API
api_excludedFounderPass super_adminPer-deal, channel-scopedRemoves the deal from the Partner API only (GET /v1/deals, detail, instructions, attributed tracking), while it stays live in the hosted app
hidden_globallyFounderPass super_adminPer-deal, everywherePulls the deal from every channel for every partner

The key distinction: api_excluded is channel-scoped, not partner-scoped. A deal marked api_excluded never appears on any Partner API path for any partner, yet end users still see and claim it in the hosted storefront. You can't change api_excluded yourself — it's an admin-side flag — but you'll see it reflected as the deal simply being absent from your API responses. The api_excluded boolean is surfaced on the Deal model for reference.