Skip to content
Dashboard

Entity scopes

Guest-portal content in SuiteOp is written once and switched on where it applies. An entity’s scopes are the properties it reaches, through four routes: individual properties, property groups, tags and guest portals. The four entity-scope operations read and change those routes for one entity at a time. Every field is listed on the operation’s page in the API Reference.

OperationRequestPermission
listEntityScopesGET /entity-scopesview_properties
addEntityScopesPOST /entity-scopes/addmodify_properties
removeEntityScopesPOST /entity-scopes/removemodify_properties
updateEntityScopesPOST /entity-scopesmodify_properties

Paths are relative to your region’s base URL, for example https://api-us.suiteop.com/api/v1. See Authentication for permissions. Writing the scopes of a manual or guide_list also needs modify_guides; without it the write returns 403 authorization_error.

Every call names the entity with entityId and entityType. There is no autodetection, so the type must match the ID.

entityTypeWhat it isWhere the ID comes from
upsellA paid add-on in the guest storelistUpsells, createUpsell
manualA house manual articlelistPortalManuals
precheck_stepA pre-check-in steplistPrecheckSteps
portal_settingsA guest portallistPortals
guide_listA guide list, managed in the appNo public operation returns these IDs
eventAn event, managed in the appNo public operation returns these IDs

manual and portal_settings can’t be scoped to guest portals: a non-empty portalSettingsIds for either is rejected with 400 validation_error (message validation.unsupported_scope_type_for_entity). For a guest portal, the property route is the portal assignment itself: scoping a portal to a property makes it that property’s portal, the same as assignPortalToProperty. A replace that leaves a property out of a portal’s propertyIds takes that portal off the property.

GET /entity-scopes takes entityId and entityType as query parameters and returns all four routes. It isn’t paginated.

Terminal window
curl "https://api-us.suiteop.com/api/v1/entity-scopes?entityType=upsell&entityId=3f2b1d9e-7a4c-4b2e-8f61-0c9d2e5a7b18" \
-H "Authorization: Bearer sk_live_your_key_here"
{
"data": {
"propertyIds": ["9a3d7e40-2c1b-4f8e-a6d5-3b7c9e0f1a24"],
"propertyGroupIds": [],
"tagIds": ["5e8a1c3d-7b2f-4a9e-8d6c-1f0e3b5a7c92"],
"portalSettingsIds": []
},
"meta": { "requestId": "…" }
}

addEntityScopes and removeEntityScopes change only the IDs you send and keep everything else. Prefer them over updateEntityScopes: you don’t need to read or resend the current set.

Terminal window
curl -X POST https://api-us.suiteop.com/api/v1/entity-scopes/add \
-H "Authorization: Bearer sk_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"entityType": "upsell",
"entityId": "3f2b1d9e-7a4c-4b2e-8f61-0c9d2e5a7b18",
"propertyGroupIds": ["2e6d0f5b-8a1c-4d3e-9b7f-6c0a2e4d8f13"]
}'

Both answer with the entity’s resulting scopes, in the same four-array shape listEntityScopes returns:

{
"data": {
"propertyIds": ["9a3d7e40-2c1b-4f8e-a6d5-3b7c9e0f1a24"],
"propertyGroupIds": ["2e6d0f5b-8a1c-4d3e-9b7f-6c0a2e4d8f13"],
"tagIds": ["5e8a1c3d-7b2f-4a9e-8d6c-1f0e3b5a7c92"],
"portalSettingsIds": []
},
"meta": { "requestId": "…" }
}
  • Send at least one ID. Omit the arrays you aren’t changing. A request whose arrays are all empty or missing returns 400 validation_error with validation.entity_scope_delta_empty in details.issues (the top-level message is the generic input-validation one).
  • Safe to retry. Adding an ID the entity already has, or removing one it doesn’t have, succeeds without change.
  • IDs must be yours. On add, a property, group, tag or portal from another organization returns 400 validation_error with the message validation.scope_ids_not_in_org; details names the kind and the IDs. Remove doesn’t check: an ID the entity doesn’t hold is ignored.

updateEntityScopes (POST /entity-scopes) replaces the entity’s whole scope set with what you send, across all four routes, and answers { "success": true }.

Terminal window
curl -X POST https://api-us.suiteop.com/api/v1/entity-scopes \
-H "Authorization: Bearer sk_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"entityType": "precheck_step",
"entityId": "8d2e4f60-1b3a-4c7d-9e25-0f6a8b1c3d47",
"propertyIds": [],
"propertyGroupIds": ["2e6d0f5b-8a1c-4d3e-9b7f-6c0a2e4d8f13"],
"tagIds": [],
"portalSettingsIds": []
}'
  • Unknown keys are rejected with 400 validation_error, so a misspelled propertyIDs fails instead of silently clearing the property route.
  • IDs from another organization return 400 validation_error (validation.scope_ids_not_in_org), as on add.
  • An entityId that doesn’t exist in your organization, or doesn’t match entityType, returns 404 not_found_error on every write.

An sk_ API key acts across the whole organization. An OAuth token carries the property access of the member who authorized it (see Members), and for such a token:

  • The entity itself must be visible to the member, or the write returns 404.
  • On add and replace, a property ID outside their access, or a group, tag or portal that covers any property outside it, returns 404, the same answer as an ID that doesn’t exist.
  • On remove, a scope ID outside their access is ignored: the request succeeds and that assignment stays in place. Removing it needs a credential that can reach it, such as an sk_ key.
  • updateEntityScopes replaces only the scopes within their access. Scopes they can’t reach are kept.
  • listEntityScopes, add and remove return only the scopes the member can see, so the response can be smaller than the stored set.
  • Scopes are separate from the entity. createUpsell, createPrecheckStep and updatePortalManual don’t set scopes; add them after creating the entity. createPortalManual can seed one property scope with propertyId.
  • Retries on replace aren’t harmless. Resending a stale updateEntityScopes body after someone else changed the scopes overwrites their change. Add and remove don’t have this problem.
  • Send an Idempotency-Key on these POSTs when you retry automatically, so a replayed request returns the original response (see Idempotency).
  • Workflow scopes are different. Which properties an automation runs on is set with set_workflow_scopes, not with these operations.