> ## Documentation Index
> Fetch the complete documentation index at: https://docs.scrip.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Get rule configuration as of a timestamp

> Return the last immutable configuration revision at or before the RFC3339 timestamp. The revision field is omitted and explicit caveats are returned when the time predates tracked history.

Returns the latest tracked immutable revision at or before the RFC 3339 `at` timestamp.

When the timestamp predates tracked history, the response omits `revision` and returns an explicit `caveats` entry.


## OpenAPI

````yaml GET /v1/programs/{programId}/rule-configuration/revisions/as-of
openapi: 3.0.3
info:
  contact:
    email: support@scrip.dev
    name: Scrip Support
  description: >-
    Scrip is the operating system for rewards programs. Use this REST API to
    define earn and redemption rules, issue and redeem assets, and track every
    movement in a double-entry ledger. Full guides and reference:
    https://docs.scrip.dev


    Core concepts:

    - **Programs**: Containers for incentive logic (e.g., "Q1 Sales Bonus",
    "Customer Loyalty")

    - **Assets**: The currency or points being tracked (e.g., "Bonus Points",
    "Cash Rewards")

    - **Participants**: Users who earn and spend assets (identified by
    external_id)

    - **Groups**: Collections of participants for team-based incentives

    - **Rules**: Automated reward logic triggered by events

    - **Events**: Actions that trigger rule evaluation (e.g., "purchase",
    "referral")


    Response formats:

    - **Collection endpoints** return: {"data": [...], "pagination":
    {"has_more": true, "next_cursor": "..."}}

    - **Single-resource endpoints** return the resource directly

    - **Errors** return: {"code": "...", "message": "...", "details": {...}} —
    `details` is an optional object, present on input errors only
  license:
    name: Proprietary
  termsOfService: https://scrip.dev/terms
  title: Scrip API
  version: '1.0'
servers:
  - url: https://api.scrip.dev
security: []
tags:
  - description: >-
      Manage incentive programs. Programs are the top-level container for all
      incentive logic.
    name: Programs
  - description: >-
      Manage asset types (currencies, points). Assets define what participants
      can earn and spend.
    name: Assets
  - description: >-
      Manage participants and their balances. Participants are identified by
      external_id from your system.
    name: Participants
  - description: Manage participant groups for team-based incentives.
    name: Groups
  - description: >-
      Manage automated reward rules. Rules define conditions and actions
      triggered by events.
    name: Rules
  - description: Ingest events that trigger rule evaluation and reward distribution.
    name: Events
  - description: Transfer assets between participants.
    name: Transfers
  - description: Access ledger summaries and program activity reports.
    name: Reporting
  - description: >-
      Redeem participant balances for rewards. Supports raw amount redemptions
      and catalog item redemptions.
    name: Redemptions
  - description: >-
      Manage the reward catalog. Create and manage redeemable items with
      inventory tracking.
    name: Rewards
  - description: >-
      Schedule and manage automated event dispatching. Automations generate
      events on cron schedules, at specific times, or by evaluating participant
      state.
    name: Automations
  - description: >-
      Manage tier types and levels within programs. Tiers define status
      hierarchies that participants progress through based on qualification
      rules.
    name: Tiers
  - description: Inspect double-entry ledger records for auditing and reconciliation.
    name: Journal Entries
  - description: >-
      Manage webhook endpoints and delivery logs. Webhooks notify your
      application of real-time events via HTTP POST with HMAC-SHA256 signatures.
    name: Webhooks
paths:
  /v1/programs/{programId}/rule-configuration/revisions/as-of:
    get:
      tags:
        - Rules
      summary: Reconstruct rule configuration as of a timestamp
      description: >-
        Return the last immutable configuration revision at or before the
        RFC3339 timestamp. The revision field is omitted and explicit caveats
        are returned when the time predates tracked history.
      operationId: getRuleConfigurationAsOf
      parameters:
        - description: Program ID
          in: path
          name: programId
          required: true
          schema:
            format: uuid
            type: string
        - description: RFC3339 as-of timestamp
          in: query
          name: at
          required: true
          schema:
            format: date-time
            type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/handlers.GetRuleConfigurationAsOfResponse'
          description: OK
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/handlers.ErrBadRequestResponse'
          description: Bad Request
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/handlers.ErrUnauthorizedResponse'
          description: Unauthorized
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/handlers.ErrForbiddenResponse'
          description: Forbidden
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/handlers.ErrNotFoundResponse'
          description: Not Found
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/handlers.ErrInternalResponse'
          description: Internal Server Error
      security:
        - ApiKeyAuth: []
        - BearerAuth: []
components:
  schemas:
    handlers.GetRuleConfigurationAsOfResponse:
      properties:
        caveats:
          description: Explicit limitations on historical coverage.
          items:
            $ref: '#/components/schemas/service.RuleConfigurationHistoryCaveat'
          type: array
        revision:
          allOf:
            - $ref: '#/components/schemas/handlers.RuleConfigurationRevisionResponse'
          description: >-
            Latest tracked revision at or before the requested time. Omitted
            when the time predates tracked history.
      type: object
    handlers.ErrBadRequestResponse:
      additionalProperties: false
      properties:
        code:
          description: Code is the machine-readable error code
          example: bad_request
          type: string
        details:
          allOf:
            - $ref: '#/components/schemas/handlers.ErrorDetails'
          description: >-
            Details provides optional structured error context (field errors,
            etc.)
        message:
          description: Message is the human-readable error description
          example: Invalid request parameters
          type: string
      type: object
    handlers.ErrUnauthorizedResponse:
      properties:
        code:
          description: Code is the machine-readable error code
          example: unauthorized
          type: string
        details:
          allOf:
            - $ref: '#/components/schemas/handlers.ErrorDetails'
          description: Details provides optional structured error context
        message:
          description: Message is the human-readable error description
          example: Missing or invalid credentials
          type: string
      type: object
    handlers.ErrForbiddenResponse:
      properties:
        code:
          description: Code is the machine-readable error code
          example: forbidden
          type: string
        details:
          allOf:
            - $ref: '#/components/schemas/handlers.ErrorDetails'
          description: Details provides optional structured error context
        message:
          description: Message is the human-readable error description
          example: Insufficient permissions for this action
          type: string
      type: object
    handlers.ErrNotFoundResponse:
      properties:
        code:
          description: Code is the machine-readable error code
          example: not_found
          type: string
        details:
          allOf:
            - $ref: '#/components/schemas/handlers.ErrorDetails'
          description: Details provides optional structured error context
        message:
          description: Message is the human-readable error description
          example: Resource not found
          type: string
      type: object
    handlers.ErrInternalResponse:
      properties:
        code:
          description: Code is the machine-readable error code
          example: internal_error
          type: string
        message:
          description: Message is the human-readable error description
          example: An internal error occurred
          type: string
      type: object
    service.RuleConfigurationHistoryCaveat:
      properties:
        code:
          description: Machine-readable limitation code.
          enum:
            - history_not_yet_tracked
            - pre_history_legacy_data
          type: string
        message:
          description: Human-readable explanation of the limitation.
          type: string
      type: object
    handlers.RuleConfigurationRevisionResponse:
      properties:
        actor:
          allOf:
            - $ref: '#/components/schemas/audit.Actor'
          description: Authenticated actor that made the change.
        affected_rule_ids:
          description: Rule IDs changed by this revision.
          items:
            type: string
          type: array
        affected_rule_set_ids:
          description: Rule-set IDs changed by this revision.
          items:
            type: string
          type: array
        changed_at:
          description: Commit time of this revision.
          format: date-time
          type: string
        configuration:
          allOf:
            - $ref: '#/components/schemas/service.RuleConfigurationRevisionSnapshot'
          description: Complete effective configuration at this revision.
        configuration_change_id:
          description: >-
            Atomic preview/apply change ID, when this revision came from a
            change set.
          format: uuid
          type: string
        diff:
          allOf:
            - $ref: '#/components/schemas/service.RuleConfigurationDiff'
          description: Exact resource-level changes made by this revision.
        id:
          description: Stable revision record ID.
          format: uuid
          type: string
        program_id:
          description: Program whose configuration changed.
          format: uuid
          type: string
        rule_configuration_version:
          description: >-
            Program rule-configuration version; increases by one on every
            change.
          type: integer
        rule_history_ids:
          description: Per-rule history rows written by this revision.
          items:
            type: string
          type: array
        rule_set_history_ids:
          description: Per-rule-set history rows written by this revision.
          items:
            type: string
          type: array
        source:
          allOf:
            - $ref: '#/components/schemas/service.RuleConfigurationSource'
          description: Caller category and optional correlation metadata.
        source_revision:
          description: Historical revision restored by a forward rollback, when applicable.
          type: integer
      type: object
    handlers.ErrorDetails:
      description: >-
        Optional structured details about the error. Always a JSON object: a
        `fields` array for validation errors, or flat
        field/reason/expected/received properties for other input errors.
      properties:
        expected:
          description: Expected value or format (non-validation input errors)
          example: uuid
          type: string
        field:
          description: Field name that caused the error (non-validation input errors)
          example: asset_id
          type: string
        fields:
          description: >-
            Fields lists each offending input field on validation_error
            responses.
          items:
            $ref: '#/components/schemas/handlers.ErrorFieldDetail'
          type: array
        reason:
          description: Machine-readable reason code (non-validation input errors)
          example: invalid
          type: string
        received:
          description: Value that was received (non-validation input errors)
          example: not-a-uuid
          type: string
      type: object
    audit.Actor:
      properties:
        actor_source:
          $ref: '#/components/schemas/audit.ActorSource'
        api_key_id:
          type: string
        external_subject:
          type: string
        external_subject_type:
          type: string
        rule_id:
          type: string
        user_id:
          type: string
        via_api_key_id:
          type: string
      type: object
    service.RuleConfigurationRevisionSnapshot:
      properties:
        program_id:
          description: Program whose historical configuration is represented.
          type: string
        rule_configuration_version:
          description: Historical program rule-configuration revision.
          type: integer
        rule_sets:
          description: Complete effective rule sets and rules at this revision.
          items:
            $ref: '#/components/schemas/service.RuleSetConfigurationRevisionSnapshot'
          type: array
      type: object
    service.RuleConfigurationDiff:
      properties:
        rule_sets:
          description: Created, updated, moved, or otherwise changed rule sets.
          items:
            $ref: '#/components/schemas/service.RuleConfigurationResourceDiff'
          type: array
        rules:
          description: Created, updated, moved, archived, or otherwise changed rules.
          items:
            $ref: '#/components/schemas/service.RuleConfigurationResourceDiff'
          type: array
      type: object
    service.RuleConfigurationSource:
      properties:
        reference:
          description: Optional caller-supplied correlation reference.
          type: string
        source_revision:
          description: Historical target revision when this change is a forward rollback.
          type: integer
        type:
          description: >-
            Caller category such as api, dashboard, mcp, sdk, config_as_code, or
            scenario_promotion.
          type: string
      type: object
    handlers.ErrorFieldDetail:
      description: >-
        A single field-level error: which input field failed, why, and (where
        known) the expected and received values.
      properties:
        expected:
          description: >-
            Expected value or format. Usually a string; for "one of" constraints
            it

            is an array of the allowed values.
        field:
          description: Field name that caused the error
          example: amount
          type: string
        message:
          description: Human-readable explanation (validation errors only)
          example: This field is required
          type: string
        reason:
          description: Machine-readable reason code
          example: required
          type: string
        received:
          description: Value that was received
          example: '-10.00'
          type: string
      type: object
    audit.ActorSource:
      enum:
        - direct_user
        - direct_api_key
        - rule
        - system
        - asserted
      type: string
      x-enum-varnames:
        - ActorSourceDirectUser
        - ActorSourceDirectAPIKey
        - ActorSourceRule
        - ActorSourceSystem
        - ActorSourceAsserted
    service.RuleSetConfigurationRevisionSnapshot:
      properties:
        id:
          type: string
        key:
          type: string
        name:
          type: string
        order:
          type: integer
        rules:
          items:
            $ref: '#/components/schemas/service.RuleConfigurationSnapshot'
          type: array
      type: object
    service.RuleConfigurationResourceDiff:
      properties:
        after:
          description: Normalized resource state after the change.
        before:
          description: Normalized resource state before the change.
        change_type:
          description: Resource transition type.
          enum:
            - create
            - update
            - move
            - status
            - archive
            - remove
          type: string
        client_ref:
          description: >-
            Request-local identity when the resource is created by this change
            set.
          type: string
        fields:
          description: Fields whose values changed.
          items:
            type: string
          type: array
        id:
          description: Stable resource ID.
          type: string
      type: object
    service.RuleConfigurationSnapshot:
      properties:
        actions:
          items:
            $ref: '#/components/schemas/models.RuleAction'
          type: array
        active_from:
          format: date-time
          type: string
        active_to:
          format: date-time
          type: string
        budgets:
          items:
            $ref: '#/components/schemas/models.BudgetSpec'
          type: array
        client_ref:
          type: string
        condition:
          type: string
        description:
          type: string
        id:
          type: string
        name:
          type: string
        order:
          type: integer
        rule_set_id:
          type: string
        status:
          type: string
        stop_after_match:
          type: boolean
      type: object
    models.RuleAction:
      description: >-
        A single action to execute when a rule matches. Actions are flat
        objects: every field sits at the top level alongside `type`, and `type`
        selects which fields are allowed. Fields that do not appear in the
        selected branch are rejected.
      discriminator:
        mapping:
          BROADCAST:
            $ref: '#/components/schemas/models.RuleActionBroadcast'
          COUNTER:
            $ref: '#/components/schemas/models.RuleActionCounter'
          CREDIT:
            $ref: '#/components/schemas/models.RuleActionCredit'
          DEBIT:
            $ref: '#/components/schemas/models.RuleActionDebit'
          FORFEIT:
            $ref: '#/components/schemas/models.RuleActionForfeit'
          HOLD:
            $ref: '#/components/schemas/models.RuleActionHold'
          RELEASE:
            $ref: '#/components/schemas/models.RuleActionRelease'
          SCHEDULE_EVENT:
            $ref: '#/components/schemas/models.RuleActionScheduleEvent'
          SET_ATTRIBUTE:
            $ref: '#/components/schemas/models.RuleActionSetAttribute'
          SET_TIER:
            $ref: '#/components/schemas/models.RuleActionSetTier'
          TAG:
            $ref: '#/components/schemas/models.RuleActionTag'
          UNTAG:
            $ref: '#/components/schemas/models.RuleActionUntag'
          VOID_HOLD:
            $ref: '#/components/schemas/models.RuleActionVoidHold'
        propertyName: type
      oneOf:
        - $ref: '#/components/schemas/models.RuleActionCredit'
        - $ref: '#/components/schemas/models.RuleActionDebit'
        - $ref: '#/components/schemas/models.RuleActionHold'
        - $ref: '#/components/schemas/models.RuleActionRelease'
        - $ref: '#/components/schemas/models.RuleActionForfeit'
        - $ref: '#/components/schemas/models.RuleActionVoidHold'
        - $ref: '#/components/schemas/models.RuleActionTag'
        - $ref: '#/components/schemas/models.RuleActionUntag'
        - $ref: '#/components/schemas/models.RuleActionCounter'
        - $ref: '#/components/schemas/models.RuleActionSetAttribute'
        - $ref: '#/components/schemas/models.RuleActionSetTier'
        - $ref: '#/components/schemas/models.RuleActionScheduleEvent'
        - $ref: '#/components/schemas/models.RuleActionBroadcast'
      title: Rule action
    models.BudgetSpec:
      description: >-
        Spend cap for one asset on this rule. Omit schedule_type for a lifetime
        cap; otherwise the schedule_type selects which reset field is required.
      oneOf:
        - additionalProperties: false
          description: >-
            Never resets. schedule_type, cron_expression, and interval are all
            rejected.
          properties:
            asset_id:
              description: Asset this budget constrains
              example: 550e8400-e29b-41d4-a716-446655440000
              format: uuid
              type: string
            limit:
              description: >-
                Maximum allowed spend per budget period, as a positive decimal
                string (e.g. "10000.00"). Budgets are static: ${{ }} expressions
                are not supported here.
              example: '10000.00'
              pattern: >-
                ^\+?(?:0*[1-9][0-9]*(?:\.[0-9]*)?|0*\.[0-9]*[1-9][0-9]*)(?:[eE][-+]?[0-9]+)?$
              type: string
          required:
            - asset_id
            - limit
          title: Lifetime budget
          type: object
        - additionalProperties: false
          description: >-
            Resets on a cron schedule. cron_expression is required and must not
            carry an inline timezone; interval is rejected.
          properties:
            asset_id:
              description: Asset this budget constrains
              example: 550e8400-e29b-41d4-a716-446655440000
              format: uuid
              type: string
            cron_expression:
              description: >-
                Cron expression for CRON-based resets (e.g. "0 0 1 * *" for
                first of every month)
              example: 0 0 1 * *
              type: string
            limit:
              description: >-
                Maximum allowed spend per budget period, as a positive decimal
                string (e.g. "10000.00"). Budgets are static: ${{ }} expressions
                are not supported here.
              example: '10000.00'
              pattern: >-
                ^\+?(?:0*[1-9][0-9]*(?:\.[0-9]*)?|0*\.[0-9]*[1-9][0-9]*)(?:[eE][-+]?[0-9]+)?$
              type: string
            schedule_type:
              description: >-
                Reset schedule type: CRON or INTERVAL. Omit for lifetime
                (no-reset) budgets.
              enum:
                - CRON
              example: CRON
              type: string
          required:
            - asset_id
            - limit
            - schedule_type
            - cron_expression
          title: Cron budget
          type: object
        - additionalProperties: false
          description: >-
            Resets every interval. interval is required; cron_expression is
            rejected.
          properties:
            asset_id:
              description: Asset this budget constrains
              example: 550e8400-e29b-41d4-a716-446655440000
              format: uuid
              type: string
            interval:
              description: >-
                Duration for INTERVAL-based resets; h/d/w units (e.g. "30d",
                "720h")
              example: 30d
              type: string
            limit:
              description: >-
                Maximum allowed spend per budget period, as a positive decimal
                string (e.g. "10000.00"). Budgets are static: ${{ }} expressions
                are not supported here.
              example: '10000.00'
              pattern: >-
                ^\+?(?:0*[1-9][0-9]*(?:\.[0-9]*)?|0*\.[0-9]*[1-9][0-9]*)(?:[eE][-+]?[0-9]+)?$
              type: string
            schedule_type:
              description: >-
                Reset schedule type: CRON or INTERVAL. Omit for lifetime
                (no-reset) budgets.
              enum:
                - INTERVAL
              example: INTERVAL
              type: string
          required:
            - asset_id
            - limit
            - schedule_type
            - interval
          title: Interval budget
          type: object
      title: Budget
    models.RuleActionBroadcast:
      additionalProperties: false
      description: >-
        Fan an event out to every participant in the program immediately. target
        is rejected because the broadcast already reaches everyone, and delay
        belongs to SCHEDULE_EVENT.
      example:
        event_name: season_reset
        type: BROADCAST
      properties:
        event_name:
          description: >-
            Event type to inject. For SCHEDULE_EVENT: fires after the delay
            expires. For BROADCAST: fans out to all participants immediately.
          example: check_status
          type: string
        payload:
          description: >-
            Additional data included with the event when it fires. String values
            may embed ${{ }} CEL expressions

            (at any nesting depth, values only), resolved against the triggering
            rule's context when the action executes.
          type: object
        type:
          description: Action kind. Selects which other fields this action accepts.
          enum:
            - BROADCAST
          example: BROADCAST
          type: string
      required:
        - type
        - event_name
      title: BROADCAST action
      type: object
    models.RuleActionCounter:
      additionalProperties: false
      description: >-
        Increment a counter on the target. key is a literal name; value is a
        static number or a ${{ }} expression resolving to one.
      example:
        key: purchase_count
        type: COUNTER
        value: '1'
      properties:
        key:
          description: Counter or attribute key name
          example: purchase_count
          type: string
        reset_after:
          description: >-
            Auto-reset duration for COUNTER actions. The counter resets to 0
            after this duration elapses since the last reset; h/d/w units (e.g.
            "30d", "720h"). Send an empty string to remove auto-reset.
          example: 30d
          type: string
        target:
          allOf:
            - $ref: '#/components/schemas/models.ActionTarget'
          description: >-
            Alternate recipient for this action. Defaults to the event's
            participant. Supported for CREDIT, DEBIT, TAG, UNTAG, COUNTER,
            SET_ATTRIBUTE, SET_TIER.
        type:
          description: Action kind. Selects which other fields this action accepts.
          enum:
            - COUNTER
          example: COUNTER
          type: string
        value:
          description: >-
            Static numeric string (e.g. "1", or "-1" to decrement) or a ${{ }}
            CEL expression returning a number. Unlike amount, a COUNTER value
            has no bare-CEL form: an unmarked non-numeric value is rejected, so
            dynamic values must use ${{ }}.
          example: '1'
          pattern: >-
            ^(?:[-+]?(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)(?:[eE][-+]?[0-9]+)?|[\s\S]*\$\{\{\s*[^\s][\s\S]*\}\}[\s\S]*)$
          type: string
      required:
        - type
        - key
        - value
      title: COUNTER action
      type: object
    models.RuleActionCredit:
      additionalProperties: false
      description: >-
        Credit an asset to the target. Requires asset_id and a positive amount.
        reference_id, expires_at, and matures_at apply to LOT-mode assets only.
      example:
        amount: ${{ event.amount * 0.03 }}
        asset_id: 550e8400-e29b-41d4-a716-446655440000
        description: Purchase reward
        expires_at: 365d
        matures_at: 30d
        type: CREDIT
      properties:
        amount:
          description: >-
            Static positive numeric string (e.g. "100") or a ${{ }} CEL
            expression returning a positive number (e.g. "${{ event.amount *
            0.03 }}"). A static amount of zero or less is rejected at rule
            create/update, and a dynamic expression must also resolve to a
            positive amount at execution time. An unmarked non-numeric value is
            still compiled as bare CEL for stored-rule compatibility; new rules
            should use ${{ }}.
          example: ${{ event.amount * 0.03 }}
          pattern: >-
            ^(?:\s*\+?(?:0*[1-9][0-9]*(?:\.[0-9]*)?|0*\.[0-9]*[1-9][0-9]*)(?:[eE][-+]?[0-9]+)?\s*|[\s\S]*\$\{\{\s*[^\s][\s\S]*\}\}[\s\S]*|[^$]*\b[A-Za-z_][A-Za-z0-9_]*\s*[.(\[][^$]*)$
          type: string
        asset_id:
          description: Asset to operate on
          example: 550e8400-e29b-41d4-a716-446655440000
          format: uuid
          type: string
        bucket:
          description: >-
            Balance bucket to target: AVAILABLE or HELD. Defaults to AVAILABLE
            for most actions, HELD for RELEASE.
          enum:
            - AVAILABLE
            - HELD
          example: AVAILABLE
          type: string
        description:
          description: Context string recorded on the ledger entry
          example: Purchase reward
          type: string
        expires_at:
          description: >-
            When the lot/tier expires. CREDIT: lot becomes unusable (LOT-mode
            assets). SET_TIER: tier assignment expires.

            Accepts an RFC3339 timestamp, a duration string with h/d/w units
            (e.g. "365d", "12w", "8760h") measured from processing time, or a
            ${{ }} CEL expression resolving to either form (e.g. "${{
            event.points_expires_at }}").
          example: 365d
          type: string
        matures_at:
          description: >-
            When the credited lot becomes usable (CREDIT only, LOT-mode assets).
            Accepts an RFC3339 timestamp, a duration string with h/d/w units
            (e.g. "30d", "720h") measured from processing time, or a ${{ }} CEL
            expression resolving to either form.
          example: 30d
          type: string
        reference_id:
          description: >-
            Correlation ID for hold/release correlation and auth/settle
            reconciliation (LOT mode only).

            Static literal (e.g. "auth_12345") or ${{ }} CEL expression (e.g.
            "${{ event.authorization_id }}").
          example: ${{ event.authorization_id }}
          type: string
        target:
          allOf:
            - $ref: '#/components/schemas/models.ActionTarget'
          description: >-
            Alternate recipient for this action. Defaults to the event's
            participant. Supported for CREDIT, DEBIT, TAG, UNTAG, COUNTER,
            SET_ATTRIBUTE, SET_TIER.
        type:
          description: Action kind. Selects which other fields this action accepts.
          enum:
            - CREDIT
          example: CREDIT
          type: string
      required:
        - type
        - asset_id
        - amount
      title: CREDIT action
      type: object
    models.RuleActionDebit:
      additionalProperties: false
      description: >-
        Debit an asset from the target. Requires asset_id and a positive amount.
        allow_negative is accepted only on DEBIT, and only when the target is
        not a PROGRAM wallet.
      example:
        amount: '50'
        asset_id: 550e8400-e29b-41d4-a716-446655440000
        type: DEBIT
      properties:
        allow_negative:
          description: >-
            Allow debit to overdraw and create a negative balance when funds are
            insufficient.

            DEBIT only. Defaults to false.
          example: false
          type: boolean
        amount:
          description: >-
            Static positive numeric string (e.g. "100") or a ${{ }} CEL
            expression returning a positive number (e.g. "${{ event.amount *
            0.03 }}"). A static amount of zero or less is rejected at rule
            create/update, and a dynamic expression must also resolve to a
            positive amount at execution time. An unmarked non-numeric value is
            still compiled as bare CEL for stored-rule compatibility; new rules
            should use ${{ }}.
          example: ${{ event.amount * 0.03 }}
          pattern: >-
            ^(?:\s*\+?(?:0*[1-9][0-9]*(?:\.[0-9]*)?|0*\.[0-9]*[1-9][0-9]*)(?:[eE][-+]?[0-9]+)?\s*|[\s\S]*\$\{\{\s*[^\s][\s\S]*\}\}[\s\S]*|[^$]*\b[A-Za-z_][A-Za-z0-9_]*\s*[.(\[][^$]*)$
          type: string
        asset_id:
          description: Asset to operate on
          example: 550e8400-e29b-41d4-a716-446655440000
          format: uuid
          type: string
        bucket:
          description: >-
            Balance bucket to target: AVAILABLE or HELD. Defaults to AVAILABLE
            for most actions, HELD for RELEASE.
          enum:
            - AVAILABLE
            - HELD
          example: AVAILABLE
          type: string
        description:
          description: Context string recorded on the ledger entry
          example: Purchase reward
          type: string
        target:
          allOf:
            - $ref: '#/components/schemas/models.ActionTarget'
          description: >-
            Alternate recipient for this action. Defaults to the event's
            participant. Supported for CREDIT, DEBIT, TAG, UNTAG, COUNTER,
            SET_ATTRIBUTE, SET_TIER.
        type:
          description: Action kind. Selects which other fields this action accepts.
          enum:
            - DEBIT
          example: DEBIT
          type: string
      required:
        - type
        - asset_id
        - amount
      title: DEBIT action
      type: object
    models.RuleActionForfeit:
      additionalProperties: false
      description: >-
        Forfeit an amount out of the participant's balance. Requires asset_id
        and a positive amount. reference_id is not supported.
      example:
        amount: '10'
        asset_id: 550e8400-e29b-41d4-a716-446655440000
        type: FORFEIT
      properties:
        amount:
          description: >-
            Static positive numeric string (e.g. "100") or a ${{ }} CEL
            expression returning a positive number (e.g. "${{ event.amount *
            0.03 }}"). A static amount of zero or less is rejected at rule
            create/update, and a dynamic expression must also resolve to a
            positive amount at execution time. An unmarked non-numeric value is
            still compiled as bare CEL for stored-rule compatibility; new rules
            should use ${{ }}.
          example: ${{ event.amount * 0.03 }}
          pattern: >-
            ^(?:\s*\+?(?:0*[1-9][0-9]*(?:\.[0-9]*)?|0*\.[0-9]*[1-9][0-9]*)(?:[eE][-+]?[0-9]+)?\s*|[\s\S]*\$\{\{\s*[^\s][\s\S]*\}\}[\s\S]*|[^$]*\b[A-Za-z_][A-Za-z0-9_]*\s*[.(\[][^$]*)$
          type: string
        asset_id:
          description: Asset to operate on
          example: 550e8400-e29b-41d4-a716-446655440000
          format: uuid
          type: string
        bucket:
          description: >-
            Balance bucket to target: AVAILABLE or HELD. Defaults to AVAILABLE
            for most actions, HELD for RELEASE.
          enum:
            - AVAILABLE
            - HELD
          example: AVAILABLE
          type: string
        description:
          description: Context string recorded on the ledger entry
          example: Purchase reward
          type: string
        type:
          description: Action kind. Selects which other fields this action accepts.
          enum:
            - FORFEIT
          example: FORFEIT
          type: string
      required:
        - type
        - asset_id
        - amount
      title: FORFEIT action
      type: object
    models.RuleActionHold:
      additionalProperties: false
      description: >-
        Move an amount from the available bucket into the held bucket.
        reference_id correlates the hold with a later RELEASE or VOID_HOLD and
        requires a LOT-mode asset.
      example:
        amount: '25'
        asset_id: 550e8400-e29b-41d4-a716-446655440000
        reference_id: ${{ event.authorization_id }}
        type: HOLD
      properties:
        amount:
          description: >-
            Static positive numeric string (e.g. "100") or a ${{ }} CEL
            expression returning a positive number (e.g. "${{ event.amount *
            0.03 }}"). A static amount of zero or less is rejected at rule
            create/update, and a dynamic expression must also resolve to a
            positive amount at execution time. An unmarked non-numeric value is
            still compiled as bare CEL for stored-rule compatibility; new rules
            should use ${{ }}.
          example: ${{ event.amount * 0.03 }}
          pattern: >-
            ^(?:\s*\+?(?:0*[1-9][0-9]*(?:\.[0-9]*)?|0*\.[0-9]*[1-9][0-9]*)(?:[eE][-+]?[0-9]+)?\s*|[\s\S]*\$\{\{\s*[^\s][\s\S]*\}\}[\s\S]*|[^$]*\b[A-Za-z_][A-Za-z0-9_]*\s*[.(\[][^$]*)$
          type: string
        asset_id:
          description: Asset to operate on
          example: 550e8400-e29b-41d4-a716-446655440000
          format: uuid
          type: string
        bucket:
          description: >-
            Balance bucket to target: AVAILABLE or HELD. Defaults to AVAILABLE
            for most actions, HELD for RELEASE.
          enum:
            - AVAILABLE
            - HELD
          example: AVAILABLE
          type: string
        description:
          description: Context string recorded on the ledger entry
          example: Purchase reward
          type: string
        reference_id:
          description: >-
            Correlation ID for hold/release correlation and auth/settle
            reconciliation (LOT mode only).

            Static literal (e.g. "auth_12345") or ${{ }} CEL expression (e.g.
            "${{ event.authorization_id }}").
          example: ${{ event.authorization_id }}
          type: string
        type:
          description: Action kind. Selects which other fields this action accepts.
          enum:
            - HOLD
          example: HOLD
          type: string
      required:
        - type
        - asset_id
        - amount
      title: HOLD action
      type: object
    models.RuleActionRelease:
      additionalProperties: false
      anyOf:
        - required:
            - amount
        - required:
            - reference_id
      description: >-
        Release held funds back to the available bucket. Provide amount for a
        partial release, or reference_id to release the correlated hold. At
        least one of the two is required.
      example:
        asset_id: 550e8400-e29b-41d4-a716-446655440000
        reference_id: ${{ event.authorization_id }}
        type: RELEASE
      properties:
        amount:
          description: >-
            Static positive numeric string (e.g. "100") or a ${{ }} CEL
            expression returning a positive number (e.g. "${{ event.amount *
            0.03 }}"). A static amount of zero or less is rejected at rule
            create/update, and a dynamic expression must also resolve to a
            positive amount at execution time. An unmarked non-numeric value is
            still compiled as bare CEL for stored-rule compatibility; new rules
            should use ${{ }}.
          example: ${{ event.amount * 0.03 }}
          pattern: >-
            ^(?:\s*\+?(?:0*[1-9][0-9]*(?:\.[0-9]*)?|0*\.[0-9]*[1-9][0-9]*)(?:[eE][-+]?[0-9]+)?\s*|[\s\S]*\$\{\{\s*[^\s][\s\S]*\}\}[\s\S]*|[^$]*\b[A-Za-z_][A-Za-z0-9_]*\s*[.(\[][^$]*)$
          type: string
        asset_id:
          description: Asset to operate on
          example: 550e8400-e29b-41d4-a716-446655440000
          format: uuid
          type: string
        bucket:
          description: >-
            Balance bucket to target: AVAILABLE or HELD. Defaults to AVAILABLE
            for most actions, HELD for RELEASE.
          enum:
            - AVAILABLE
            - HELD
          example: AVAILABLE
          type: string
        description:
          description: Context string recorded on the ledger entry
          example: Purchase reward
          type: string
        reference_id:
          description: >-
            Correlation ID for hold/release correlation and auth/settle
            reconciliation (LOT mode only).

            Static literal (e.g. "auth_12345") or ${{ }} CEL expression (e.g.
            "${{ event.authorization_id }}").
          example: ${{ event.authorization_id }}
          type: string
        type:
          description: Action kind. Selects which other fields this action accepts.
          enum:
            - RELEASE
          example: RELEASE
          type: string
      required:
        - type
        - asset_id
      title: RELEASE action
      type: object
    models.RuleActionScheduleEvent:
      additionalProperties: false
      description: >-
        Inject an event for this participant after delay elapses. event_name and
        delay are literals; payload string values may embed ${{ }} expressions
        at any depth.
      example:
        delay: 24h
        event_name: check_status
        type: SCHEDULE_EVENT
      properties:
        delay:
          description: >-
            How long to wait before firing the scheduled event; h/d/w units
            (e.g. "24h", "7d"). SCHEDULE_EVENT only.
          example: 24h
          type: string
        event_name:
          description: >-
            Event type to inject. For SCHEDULE_EVENT: fires after the delay
            expires. For BROADCAST: fans out to all participants immediately.
          example: check_status
          type: string
        payload:
          description: >-
            Additional data included with the event when it fires. String values
            may embed ${{ }} CEL expressions

            (at any nesting depth, values only), resolved against the triggering
            rule's context when the action executes.
          type: object
        type:
          description: Action kind. Selects which other fields this action accepts.
          enum:
            - SCHEDULE_EVENT
          example: SCHEDULE_EVENT
          type: string
      required:
        - type
        - event_name
        - delay
      title: SCHEDULE_EVENT action
      type: object
    models.RuleActionSetAttribute:
      additionalProperties: false
      description: >-
        Set an attribute on the target. key is a literal name; value is a
        literal string or a ${{ }} expression.
      example:
        key: region
        type: SET_ATTRIBUTE
        value: ${{ event.region }}
      properties:
        key:
          description: Counter or attribute key name
          example: purchase_count
          type: string
        target:
          allOf:
            - $ref: '#/components/schemas/models.ActionTarget'
          description: >-
            Alternate recipient for this action. Defaults to the event's
            participant. Supported for CREDIT, DEBIT, TAG, UNTAG, COUNTER,
            SET_ATTRIBUTE, SET_TIER.
        type:
          description: Action kind. Selects which other fields this action accepts.
          enum:
            - SET_ATTRIBUTE
          example: SET_ATTRIBUTE
          type: string
        value:
          description: >-
            COUNTER: static numeric string or ${{ }} CEL expression.
            SET_ATTRIBUTE: literal string or ${{ }} CEL expression.
          example: '1'
          type: string
      required:
        - type
        - key
        - value
      title: SET_ATTRIBUTE action
      type: object
    models.RuleActionSetTier:
      additionalProperties: false
      description: >-
        Assign a tier level on the target. tier and level are literal keys.
        expires_at is the canonical expiry field for new writes.
      example:
        level: gold
        tier: status
        type: SET_TIER
      properties:
        expires_at:
          description: >-
            When the lot/tier expires. CREDIT: lot becomes unusable (LOT-mode
            assets). SET_TIER: tier assignment expires.

            Accepts an RFC3339 timestamp, a duration string with h/d/w units
            (e.g. "365d", "12w", "8760h") measured from processing time, or a
            ${{ }} CEL expression resolving to either form (e.g. "${{
            event.points_expires_at }}").
          example: 365d
          type: string
        level:
          description: Tier level within the track (e.g. "gold", "platinum")
          example: gold
          type: string
        target:
          allOf:
            - $ref: '#/components/schemas/models.ActionTarget'
          description: >-
            Alternate recipient for this action. Defaults to the event's
            participant. Supported for CREDIT, DEBIT, TAG, UNTAG, COUNTER,
            SET_ATTRIBUTE, SET_TIER.
        tier:
          description: Tier track name (e.g. "status", "loyalty")
          example: status
          type: string
        type:
          description: Action kind. Selects which other fields this action accepts.
          enum:
            - SET_TIER
          example: SET_TIER
          type: string
      required:
        - type
        - tier
        - level
      title: SET_TIER action
      type: object
    models.RuleActionTag:
      additionalProperties: false
      description: >-
        Add a tag to the target. tag is a literal name; it does not accept ${{
        }} expressions.
      example:
        tag: VIP
        type: TAG
      properties:
        tag:
          description: Tag name to add (TAG) or remove (UNTAG)
          example: VIP
          type: string
        target:
          allOf:
            - $ref: '#/components/schemas/models.ActionTarget'
          description: >-
            Alternate recipient for this action. Defaults to the event's
            participant. Supported for CREDIT, DEBIT, TAG, UNTAG, COUNTER,
            SET_ATTRIBUTE, SET_TIER.
        type:
          description: Action kind. Selects which other fields this action accepts.
          enum:
            - TAG
          example: TAG
          type: string
      required:
        - type
        - tag
      title: TAG action
      type: object
    models.RuleActionUntag:
      additionalProperties: false
      description: >-
        Remove a tag from the target. tag is a literal name; it does not accept
        ${{ }} expressions.
      example:
        tag: VIP
        type: UNTAG
      properties:
        tag:
          description: Tag name to add (TAG) or remove (UNTAG)
          example: VIP
          type: string
        target:
          allOf:
            - $ref: '#/components/schemas/models.ActionTarget'
          description: >-
            Alternate recipient for this action. Defaults to the event's
            participant. Supported for CREDIT, DEBIT, TAG, UNTAG, COUNTER,
            SET_ATTRIBUTE, SET_TIER.
        type:
          description: Action kind. Selects which other fields this action accepts.
          enum:
            - UNTAG
          example: UNTAG
          type: string
      required:
        - type
        - tag
      title: UNTAG action
      type: object
    models.RuleActionVoidHold:
      additionalProperties: false
      description: >-
        Void the hold correlated by reference_id in full. reference_id is
        required and requires a LOT-mode asset; amount and bucket are rejected
        because the whole hold is voided.
      example:
        asset_id: 550e8400-e29b-41d4-a716-446655440000
        reference_id: ${{ event.authorization_id }}
        type: VOID_HOLD
      properties:
        asset_id:
          description: Asset to operate on
          example: 550e8400-e29b-41d4-a716-446655440000
          format: uuid
          type: string
        description:
          description: Context string recorded on the ledger entry
          example: Purchase reward
          type: string
        reference_id:
          description: >-
            Correlation ID for hold/release correlation and auth/settle
            reconciliation (LOT mode only).

            Static literal (e.g. "auth_12345") or ${{ }} CEL expression (e.g.
            "${{ event.authorization_id }}").
          example: ${{ event.authorization_id }}
          type: string
        type:
          description: Action kind. Selects which other fields this action accepts.
          enum:
            - VOID_HOLD
          example: VOID_HOLD
          type: string
      required:
        - type
        - asset_id
        - reference_id
      title: VOID_HOLD action
      type: object
    models.ActionTarget:
      description: >-
        Alternate recipient for an action. Supply exactly one identifier, or
        none to use the entity resolved from the event context. Supported on
        CREDIT, DEBIT, TAG, UNTAG, COUNTER, SET_ATTRIBUTE, and SET_TIER.
      oneOf:
        - additionalProperties: false
          description: >-
            A known participant or group, addressed by its public ID. type
            defaults to PARTICIPANT; GROUP requires this shape. PROGRAM is
            accepted here for compatibility but the id is ignored: the program
            wallet is always resolved from the event's program context.
          properties:
            id:
              description: >-
                ID is the public entity ID: participant_id for PARTICIPANT,
                group_id for GROUP.
              example: 550e8400-e29b-41d4-a716-446655440000
              format: uuid
              not:
                enum:
                  - 00000000-0000-0000-0000-000000000000
              type: string
            type:
              description: >-
                Type is the entity type: PARTICIPANT, GROUP, or PROGRAM.

                Optional when using id or dynamic ID fields (defaults to
                PARTICIPANT).
              enum:
                - PARTICIPANT
                - GROUP
                - PROGRAM
              example: PARTICIPANT
              type: string
          required:
            - id
          title: Static entity
          type: object
        - additionalProperties: false
          description: >-
            A participant resolved at execution time from a ${{ }} expression
            over event data that yields an external_id. PARTICIPANT only.
          properties:
            external_id:
              description: >-
                ExternalID is a ${{ }} CEL expression that evaluates to an
                external_id string.

                Cannot be combined with ID or ParticipantID.

                Example: "${{ event.referrer_id }}" where referrer_id contains
                an external_id like "user_123"
              example: ${{ event.referrer_id }}
              type: string
            id:
              description: >-
                Always serialized. The nil UUID means no static entity ID was
                set on this target.
              enum:
                - 00000000-0000-0000-0000-000000000000
              example: 00000000-0000-0000-0000-000000000000
              format: uuid
              type: string
            type:
              description: >-
                Type is the entity type: PARTICIPANT, GROUP, or PROGRAM.

                Optional when using id or dynamic ID fields (defaults to
                PARTICIPANT).
              enum:
                - PARTICIPANT
              example: PARTICIPANT
              type: string
          required:
            - external_id
          title: Dynamic participant by external_id
          type: object
        - additionalProperties: false
          description: >-
            A participant resolved at execution time from a ${{ }} expression
            over event data that yields a participant UUID. PARTICIPANT only.
          properties:
            id:
              description: >-
                Always serialized. The nil UUID means no static entity ID was
                set on this target.
              enum:
                - 00000000-0000-0000-0000-000000000000
              example: 00000000-0000-0000-0000-000000000000
              format: uuid
              type: string
            participant_id:
              description: >-
                ParticipantID is a ${{ }} CEL expression that evaluates to a
                participant UUID string.

                Cannot be combined with ID or ExternalID.

                Example: "${{ event.recipient_id }}" where recipient_id contains
                a participant UUID
              example: ${{ event.recipient_id }}
              type: string
            type:
              description: >-
                Type is the entity type: PARTICIPANT, GROUP, or PROGRAM.

                Optional when using id or dynamic ID fields (defaults to
                PARTICIPANT).
              enum:
                - PARTICIPANT
              example: PARTICIPANT
              type: string
          required:
            - participant_id
          title: Dynamic participant by participant_id
          type: object
        - additionalProperties: false
          description: >-
            No identifier: PARTICIPANT resolves to the event's participant and
            PROGRAM resolves to the program wallet.
          properties:
            id:
              description: >-
                Always serialized. The nil UUID means no static entity ID was
                set on this target.
              enum:
                - 00000000-0000-0000-0000-000000000000
              example: 00000000-0000-0000-0000-000000000000
              format: uuid
              type: string
            type:
              description: >-
                Type is the entity type: PARTICIPANT, GROUP, or PROGRAM.

                Optional when using id or dynamic ID fields (defaults to
                PARTICIPANT).
              enum:
                - PARTICIPANT
                - PROGRAM
              example: PARTICIPANT
              type: string
          title: Contextual entity
          type: object
      title: Action target
  securitySchemes:
    ApiKeyAuth:
      description: API key passed in the X-API-Key header.
      in: header
      name: X-API-Key
      type: apiKey
    BearerAuth:
      description: Bearer token passed in the Authorization header (e.g. "Bearer sk_...").
      in: header
      name: Authorization
      type: apiKey

````