Manages PubNub Illuminate resources with operations: list, get, create, update, delete, activate, deactivate, get-fields, execute-adhoc, publish-fake-data, verify-query, check-action-log, raw-snapshot, aggregate, field-health, and custom-query.
Supports full CRUD for: Business Objects, Metrics, Queries, Decisions, and Dashboards.
Operations:
- list: GET all resources of a given type
- get: GET one resource by id
- create: POST a new resource (Decisions use automatic 2-step POST→PUT workflow)
- update: PUT/replace a resource
- delete: DELETE a resource (Business Object delete cascades to all associated resources)
- activate / deactivate: toggle isActive (Business Object) or enabled (Decision)
- get-fields: fetch Query output field definitions (required before building a Query Decision)
- execute-adhoc: run a one-off Query pipeline without saving it
- publish-fake-data: generate type-aware fake PubNub messages and publish them to test Decisions. Fetches BO field schema and produces realistic values per field type. Payloads are NESTED to match each field's JSONPath (e.g.
$.message.body.application.user_id produces { application: { user_id: ... } }, not the flat key "application.user_id"), so JSONPath resolution works against nested BO schemas. Pass secret_key when the keyset has Access Manager enabled — initializing with the secret key grants root permissions and bypasses 403 errors. Alternatively pass auth_key with a token from grantToken(). Failures are reported per-message; partial publishes return success with a 'failures' array. NOTE: Illuminate ingests with a 20–30 second delay — wait before querying after publish. - verify-query: execute a saved Query by id and return results (confirms data is flowing)
- check-action-log: fetch recent Decision action log entries to verify a Decision fired
- raw-snapshot: return the most recent rows from a Business Object via ad-hoc query
- aggregate: group and count BO data by user/channel or custom group_by fields
- field-health: check which BO fields are populated vs empty (reveals JSONPath mismatches)
- custom-query: run a fully custom ad-hoc pipeline
ID Dependency Chain — always capture before proceeding: Business Object → id, fields[*].id Metric → id, measureId, dimensionIds Query → id, then call get-fields for output field IDs Decision → id, inputFields[*].id, outputFields[*].id, actions[*].id Dashboard → id, charts[*].id
Critical Decision rules: hitType ('SINGLE'|'MATCH_ALL') and executeOnce (boolean) are required — omitting causes HTTP 500. Handler auto-injects safe defaults (hitType=SINGLE, executeOnce=false, activeFrom=now, activeUntil=now+2yr). executionFrequency (NOT 'evaluationFrequency' — that name is invalid) is the decision evaluation cadence in seconds: it schedules evaluation for METRIC/QUERY decisions, and for BUSINESSOBJECT decisions must stay a plan-supported value (commonly 3600), never null (a null value passes the API but makes the portal reject saves). Per-action throttling goes on rules[].actionValues[].executionLimit*, not on executionFrequency. The 2-step create workflow resolves field/action names → UUIDs in: action templates (both output variable names AND input field names — input names are sentinel-substituted pre-POST and restored post-POST), inputValues.inputFieldId, outputValues.outputFieldId, outputValues.value (dollar-brace), actionValues.actionId, and actionValues.executionLimitInputFieldIds. Use names everywhere. If the PUT step fails the handler deletes the orphaned scaffold automatically.
CRITICAL — QUERY decision input field naming: For sourceType=QUERY decisions, each inputField.name MUST exactly match the source query's output field alias (case-sensitive, including underscores). Illuminate binds query result rows to decision inputs by NAME — not by sourceId. If names don't match, the decision will be created and activated successfully but will silently NEVER fire even with valid data. Always run get-fields on the source query first and copy the 'field' values verbatim into your decision's inputFields[].name.
Business Object limits (handler pre-flights and rejects on violation):
- name: 1-100 characters
- fields[].name: 1-50 characters
- max 100 fields per BO
- max 5 TEXT_LONG fields per BO (use TEXT, which holds 256 chars, for shorter strings)
- keep
description to ONE concise sentence (~under 200 chars). The API does NOT reject long descriptions, but an overly long one breaks the Admin portal Business Object detail page (it fails to render) — treat 'concise' as a hard rendering requirement, not a style preference.
Decision action types:
- PUBNUB_PUBLISH (portal label: Publish) — requires ALL four fields nested inside 'template': pubkey, subkey, channel, body.
- WEBHOOK_EXECUTION (Webhook)
- APPCONTEXT_SET_USER_METADATA (portal label: Update User)
- APPCONTEXT_SET_CHANNEL_METADATA (portal label: Update Channel)
- APPCONTEXT_SET_MEMBERSHIP_METADATA (portal label: Update Membership) All action config goes INSIDE the action's 'template' object — never as top-level action props. Putting PUBNUB_PUBLISH channel/body at the action top level does NOT error but stores template:null, which then breaks the portal Decisions page ('There was a problem loading your Decisions'). Metric/query filters can only reference dimensions (a filtered field must be in dimensionIds), else 400 'Filter fields must be dimensions'.
Decision action default: When the user doesn't specify what action to fire, default to actionType='PUBNUB_PUBLISH' with a message body that includes the relevant input/output values via dollar-brace template references. PUBNUB_PUBLISH requires no external infrastructure and is trivially verifiable via check-action-log or by subscribing to the target channel. Only use WEBHOOK when the user has provided a specific URL.
NEVER delete without explicit user confirmation.
TOOL SELECTION GUIDE — Illuminate Claude Behavior:
- Intent-first: Always start from the user's desired outcome. Ask what they want to achieve before suggesting Business Objects, Metrics, or Decisions.
- Preview-first: Before creating any resources, describe automation in 1-2 sentences and show a conditions → actions decision table. Ask for confirmation before building.
- Predefined templates: For spam (flooding/cross-posting) and ranking (Top N/Bottom N), use the Query Builder predefined templates. Never recreate these from scratch.
- Built-in BO fields: For chat/moderation/ranking, User/Channel/Message/Message Type are auto-created. Never ask users to define them.
- Start simple: Minimal decision for the core goal; add complexity only when requested.
- PubNub extension: For delayed checks, scheduling, or orchestration beyond Illuminate, suggest PubNub Functions or pub/sub as the first extension path.