openapi: 3.0.3
info:
  title: Everflow Network API - Customer Value
  description: >
    Endpoints for managing Customer Value data points and rules. Customer Value
    tracks the lifetime activity of an individual customer (identified by the
    `user_id` passed on conversions) and adjusts payout and revenue based on what
    that customer has done so far. Data points are the custom attributes you send
    with conversions; rules define the goals a customer must reach and the payout
    or revenue outcome applied once they do.
  version: 1.0.0
servers:
  - url: https://api.eflow.team/v1
tags:
  - name: Data Points
  - name: Rules
paths:
  /networks/customervalue/datapoints:
    get:
      summary: List Data Points
      description: >
        Retrieve every Customer Value data point defined for the network,
        including inactive ones. This endpoint is not paginated and takes no
        filters.
      tags:
        - Data Points
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                type: object
                properties:
                  data_points:
                    type: array
                    items:
                      $ref: "#/components/schemas/DataPoint"
      security:
        - API Key: []
    post:
      summary: Create Data Point
      description: >
        Create a Customer Value data point. The `identifier` is lowercased on
        save and must be unique within the network. `type` is required and is
        rejected rather than coerced if it is not `text` or `number`, since it
        cannot be changed afterwards.
      tags:
        - Data Points
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DataPointInput"
            example:
              identifier: "subscription_tier"
              name: "Subscription tier"
              type: "text"
              status: "active"
              description: "The plan the customer is subscribed to."
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DataPoint"
      security:
        - API Key: []
    put:
      summary: Update Data Point
      description: >
        Update a Customer Value data point. Send the complete object — the
        `data_point_id` selects the record to update. Only `name`, `status`, and
        `description` are applied: `identifier` and `type` are immutable once the
        data point exists, because rules and stored customer history reference
        them. Both must still be present and valid in the payload. Omitting
        `status` leaves the stored status unchanged, so an `inactive` data point
        is not silently reactivated.
      tags:
        - Data Points
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DataPointUpdateInput"
            example:
              data_point_id: 12
              identifier: "subscription_tier"
              name: "Subscription plan"
              type: "text"
              status: "inactive"
              description: "No longer sent by the storefront."
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DataPoint"
      security:
        - API Key: []
  /networks/customervalue/datapoints/{dataPointId}:
    get:
      summary: Get Data Point by ID
      description: Retrieve a single Customer Value data point by its ID.
      tags:
        - Data Points
      parameters:
        - in: path
          name: dataPointId
          required: true
          schema:
            type: integer
          description: The data point identifier.
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DataPoint"
      security:
        - API Key: []
    delete:
      summary: Delete Data Point
      description: >
        Delete a Customer Value data point. The request fails if the data point
        is referenced by any rule — as a goal metric, as a payout or revenue
        source, or as a progress setting. Remove those references first, or set
        the data point to `inactive` to stop using it while keeping its history.
      tags:
        - Data Points
      parameters:
        - in: path
          name: dataPointId
          required: true
          schema:
            type: integer
          description: The data point identifier.
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                type: object
                properties:
                  result:
                    type: boolean
      security:
        - API Key: []
  /networks/customervalue/rules:
    get:
      summary: List Rules
      description: >
        Retrieve every Customer Value rule defined for the network. This endpoint
        is not paginated and takes no filters.
      tags:
        - Rules
      parameters:
        - in: query
          name: relationship
          schema:
            type: string
            enum:
              - event
              - all
          description: >
            Include related data. Use `event` to resolve the display names of the
            scoped and tied payout/revenue events, or `all` for the same result.
            Repeat the parameter for multiple values.
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                type: object
                properties:
                  rules:
                    type: array
                    items:
                      $ref: "#/components/schemas/Rule"
      security:
        - API Key: []
    post:
      summary: Create Rule
      description: >
        Create a Customer Value rule. See
        [Customer Value](/api-reference/customer-value-overview) for how goals,
        cycles, and outcomes fit together and which field combinations are valid.
      tags:
        - Rules
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RuleInput"
            example:
              name: "Third purchase bonus"
              status: "active"
              segmentation: "shared"
              offer_ids:
                - 33
              start_date: "2026-08-01"
              end_date: "2026-12-31"
              cycle_type: "month"
              outcome_type: "bonus"
              outcome_trigger: "instant"
              goals:
                - metric: "conversion"
                  operator: "greater_than"
                  value: "2"
              payout_method: "model"
              payout_type: "cpa"
              payout_value: 5
              revenue_method: "model"
              revenue_type: "rpa"
              revenue_value: 8
              progress_settings:
                - metric: "conversions"
                  condition: "any_value"
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Rule"
      security:
        - API Key: []
    put:
      summary: Update Rule
      description: >
        Update a Customer Value rule. Send the complete object — the `rule_id`
        selects the record to update, and omitted fields are treated as cleared,
        not preserved.


        Which fields are applied depends on the rule's current `state`, so that a
        rule cannot be redefined out from under the customer history it has
        already accumulated:


        - `scheduled` — every field is applied.

        - `running` / `stopped_running` — `name`, `status`, `end_date`,
        the scope (`offer_ids`, `advertiser_ids`, `affiliate_ids`,
        `payout_revenue_id`), the payout and revenue settings, and
        `outcome_payout_revenue_id` are applied. `start_date`, `segmentation`,
        `timezone_id`, the cycle settings, `goals`, `outcome_type`,
        `outcome_trigger`, and `progress_settings` are locked.

        - `expired` — only `name` is applied.


        For a rule with an `end_of_cycle` outcome trigger, changing `status`
        settles the open cycle before the change takes effect.
      tags:
        - Rules
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RuleUpdateInput"
            example:
              rule_id: 87
              name: "Third purchase bonus"
              status: "inactive"
              end_date: "2027-01-31"
              offer_ids:
                - 33
                - 41
              payout_method: "model"
              payout_type: "cpa"
              payout_value: 7
              revenue_method: "model"
              revenue_type: "rpa"
              revenue_value: 10
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Rule"
      security:
        - API Key: []
  /networks/customervalue/rules/{ruleId}:
    get:
      summary: Get Rule by ID
      description: Retrieve a single Customer Value rule by its ID.
      tags:
        - Rules
      parameters:
        - in: path
          name: ruleId
          required: true
          schema:
            type: integer
          description: The rule identifier.
        - in: query
          name: relationship
          schema:
            type: string
            enum:
              - event
              - all
          description: >
            Include related data. Use `event` to resolve the display names of the
            scoped and tied payout/revenue events, or `all` for the same result.
            Repeat the parameter for multiple values.
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Rule"
      security:
        - API Key: []
    delete:
      summary: Delete Rule
      description: >
        Delete a Customer Value rule. Deletion is permanent and removes the rule
        regardless of its state. To stop a rule while keeping it, set its
        `status` to `inactive` instead.
      tags:
        - Rules
      parameters:
        - in: path
          name: ruleId
          required: true
          schema:
            type: integer
          description: The rule identifier.
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                type: object
                properties:
                  result:
                    type: boolean
      security:
        - API Key: []
components:
  schemas:
    DataPoint:
      type: object
      properties:
        network_id:
          type: integer
          example: 1
          readOnly: true
          description: Network ID.
        data_point_id:
          type: integer
          example: 12
          readOnly: true
          description: Unique data point ID.
        identifier:
          type: string
          maxLength: 255
          example: "subscription_tier"
          description: >
            The key used to send this data point on a conversion. Lowercased on
            save and unique within the network.
        name:
          type: string
          maxLength: 255
          example: "Subscription tier"
          description: Display name of the data point.
        type:
          type: string
          enum:
            - text
            - number
          description: >
            The value type. `number` data points can be summed and compared and
            are the only ones usable as a payout or revenue source; `text` data
            points support string comparisons only.
        status:
          type: string
          enum:
            - active
            - inactive
          description: >
            Only `active` data points can be referenced by a rule. Setting a data
            point to `inactive` stops new rules from using it.
        description:
          type: string
          description: Free-form description of the data point.
        time_created:
          type: integer
          example: 1734455015
          readOnly: true
          description: Unix timestamp of creation.
        time_saved:
          type: integer
          example: 1734455015
          readOnly: true
          description: Unix timestamp of last update.
    DataPointInput:
      type: object
      required:
        - identifier
        - name
        - type
      properties:
        identifier:
          type: string
          maxLength: 255
          description: >
            The key used to send this data point on a conversion. Lowercased on
            save and must be unique within the network.
        name:
          type: string
          maxLength: 255
          description: Display name of the data point.
        type:
          type: string
          enum:
            - text
            - number
          description: >
            The value type. Required — there is no default, and a value outside
            `text` and `number` is rejected rather than coerced. Cannot be
            changed after creation, so a wrong type means recreating the data
            point.
        status:
          type: string
          enum:
            - active
            - inactive
          default: active
          description: Whether rules can reference this data point.
        description:
          type: string
          description: Free-form description of the data point.
    DataPointUpdateInput:
      type: object
      required:
        - data_point_id
        - identifier
        - name
        - type
      properties:
        data_point_id:
          type: integer
          description: The data point to update.
        identifier:
          type: string
          maxLength: 255
          description: >
            Must be present and non-empty, but changes are ignored — the
            identifier is immutable.
        name:
          type: string
          maxLength: 255
          description: Display name of the data point.
        type:
          type: string
          enum:
            - text
            - number
          description: >
            Must be present and valid, but changes are ignored — the type is
            immutable.
        status:
          type: string
          enum:
            - active
            - inactive
          description: >
            Whether rules can reference this data point. Omit it to leave the
            current status unchanged.
        description:
          type: string
          description: Free-form description of the data point.
    Rule:
      type: object
      properties:
        network_id:
          type: integer
          example: 1
          readOnly: true
          description: Network ID.
        rule_id:
          type: integer
          example: 87
          description: >
            Unique rule ID. Assigned on creation; required when updating.
        name:
          type: string
          maxLength: 255
          example: "Third purchase bonus"
          description: Display name of the rule.
        status:
          type: string
          enum:
            - active
            - inactive
          default: active
          description: >
            Whether the rule is enabled. An `inactive` rule never evaluates,
            whatever its `state`.
        state:
          type: string
          enum:
            - scheduled
            - running
            - stopped_running
            - expired
          readOnly: true
          description: >
            Where the rule sits in its lifecycle, derived from its timeframe and
            configuration. `scheduled` before its start date, `expired` on or
            after its end date, `stopped_running` when its configuration is no
            longer valid to apply, and `running` otherwise. The state controls
            which fields an update can change.
        stopped_running_reason:
          type: string
          enum:
            - default
            - private_event
          readOnly: true
          description: >
            Why the rule is `stopped_running`. `private_event` means the rule
            defines a payout setting on a scoped event that is private; only
            revenue may be adjusted in that case.
        segmentation:
          type: string
          enum:
            - shared
            - affiliate
            - offer
            - advertiser
            - affiliate_offer
            - affiliate_advertiser
          default: shared
          description: >
            How a customer's accumulated history is partitioned. `shared` tracks
            one history per customer across everything in scope; the other values
            track a separate history per partner, per offer, per advertiser, or
            per combination, so the same customer can progress independently in
            each.
        offer_ids:
          type: array
          items:
            type: integer
          description: >
            Offers the rule applies to. Empty means every offer. Mutually
            exclusive with `advertiser_ids`.
        advertiser_ids:
          type: array
          items:
            type: integer
          description: >
            Advertisers the rule applies to, covering all of their offers. Empty
            means every advertiser. Ignored when `offer_ids` is set.
        affiliate_ids:
          type: array
          items:
            type: integer
          description: Partners the rule applies to. Empty means every partner.
        payout_revenue_id:
          type: integer
          description: >
            Restricts the rule to a single event (payout/revenue entry) of the
            offer in `offer_ids`. `0` means the rule applies to the offer's base
            conversion and all of its events.
        timezone_id:
          type: integer
          example: 67
          description: >
            Timezone used to interpret `start_date`, `end_date`, and calendar
            cycle boundaries. Defaults to the network's timezone.
        start_date:
          type: string
          example: "2026-08-01"
          description: >
            Inclusive start date, `yyyy-MM-dd`. Empty means the rule starts as
            soon as it is created.
        end_date:
          type: string
          example: "2026-12-31"
          description: >
            Exclusive end date, `yyyy-MM-dd`. Must be after `start_date`. Empty
            means the rule never expires.
        cycle_type:
          type: string
          enum:
            - day
            - week
            - month
            - quarter
            - rule_duration
            - from_first_conversion
          default: rule_duration
          description: >
            When the customer's accumulated totals reset to zero. Calendar
            cycles (`day`, `week`, `month`, `quarter`) reset on the boundary in
            the rule's timezone. `rule_duration` never resets — the whole rule
            is a single cycle. `from_first_conversion` never resets either;
            instead the rule stops applying to a customer `cycle_duration` days
            after that customer's first conversion.
        cycle_duration:
          type: integer
          example: 30
          description: >
            Length of the cycle in days. Required and at least `1` when
            `cycle_type` is `from_first_conversion`; ignored otherwise.
        goals:
          type: array
          description: >
            Conditions the customer's accumulated totals must satisfy for the
            outcome to apply, evaluated over the whole history rather than
            against a single conversion. All goals must be satisfied. A rule may
            only be goalless when `cycle_type` is `from_first_conversion` and
            `outcome_type` is `substitution`.
          items:
            $ref: "#/components/schemas/RuleGoal"
        outcome_type:
          type: string
          enum:
            - substitution
            - bonus
          default: substitution
          description: >
            How the outcome is applied. Each incoming conversion is added to the
            customer's history before the goals are checked, so the outcome lands
            on the conversion being processed when the history first satisfies
            them. `substitution` replaces that conversion's payout and revenue.
            `bonus` records a separate bonus conversion on top of it, leaving it
            untouched.
        outcome_trigger:
          type: string
          enum:
            - instant
            - end_of_cycle
          description: >
            When a `bonus` outcome is granted. `instant` grants it on the
            incoming conversion that brought the history to the goals;
            `end_of_cycle` grants it once when the cycle closes, aggregating the
            whole cycle. Required when `outcome_type` is `bonus`.
        outcome_payout_revenue_id:
          type: integer
          description: >
            The event the bonus conversion is recorded against. Optional for an
            `instant` trigger — omit it to tie the bonus to the incoming event —
            and required for `end_of_cycle`.
        payout_method:
          type: string
          enum:
            - disabled
            - modifier
            - model
            - data_point
          description: >
            How the payout is computed. `disabled` leaves the payout untouched,
            `modifier` adjusts the original payout, `model` computes a new payout
            from a payout type, and `data_point` derives it from a numeric data
            point. At least one of `payout_method` and `revenue_method` must be
            enabled.
        payout_modifier:
          type: string
          enum:
            - increase
            - decrease
            - flat_increase
            - flat_decrease
          description: >
            Direction of the adjustment when `payout_method` is `modifier`.
            `increase` and `decrease` treat `payout_value` as a percentage;
            `flat_increase` and `flat_decrease` treat it as an absolute amount.
        payout_type:
          type: string
          enum:
            - cpa
            - cps
            - cpa_cps
            - prv
            - cpm
          description: >
            Payout model used when `payout_method` is `model`. Required in that
            case, and must be `cpa` when `outcome_type` is `bonus`. This is a
            narrower set than an offer payout type accepts — the `_sku` variants
            and `cpc` are rejected. Responses return `blank` for any other
            `payout_method`, which carries no payout type.
        payout_value:
          type: number
          format: double
          example: 5
          description: >
            The payout amount, percentage, or per-unit rate, depending on
            `payout_method`. Cannot be negative, must not exceed `100` for a
            `decrease` modifier, and must be greater than `0` for `data_point`.
        payout_percentage:
          type: number
          format: double
          description: >
            Percentage of sale amount (`cps`, `cpa_cps`) or of revenue (`prv`)
            used when `payout_method` is `model`.
        payout_data_point_identifier:
          type: string
          description: >
            Identifier of the numeric data point the payout is derived from.
            Required when `payout_method` is `data_point`; the data point must
            exist, be `active`, and have type `number`.
        payout_data_point_calculation:
          type: string
          enum:
            - current
            - accumulated
          default: accumulated
          description: >
            Which value of the data point to use — `current` for the value on the
            incoming conversion, `accumulated` for the total across the cycle.
            Defaults to `accumulated`. `current` is not allowed with an
            `end_of_cycle` outcome trigger.
        revenue_method:
          type: string
          enum:
            - disabled
            - modifier
            - model
            - data_point
          description: >
            How the revenue is computed. Mirrors `payout_method`. At least one of
            `payout_method` and `revenue_method` must be enabled.
        revenue_modifier:
          type: string
          enum:
            - increase
            - decrease
            - flat_increase
            - flat_decrease
          description: >
            Direction of the adjustment when `revenue_method` is `modifier`.
            Mirrors `payout_modifier`.
        revenue_type:
          type: string
          enum:
            - rpa
            - rps
            - rpa_rps
            - rpm
          description: >
            Revenue model used when `revenue_method` is `model`. Required in that
            case, and must be `rpa` when `outcome_type` is `bonus`. This is a
            narrower set than an offer revenue type accepts — the `_sku` variants
            and `rpc` are rejected. Responses return `blank` for any other
            `revenue_method`, which carries no revenue type.
        revenue_value:
          type: number
          format: double
          example: 8
          description: >
            The revenue amount, percentage, or per-unit rate, depending on
            `revenue_method`. Same constraints as `payout_value`.
        revenue_percentage:
          type: number
          format: double
          description: >
            Percentage of sale amount used when `revenue_method` is `model` with
            `rps` or `rpa_rps`.
        revenue_data_point_identifier:
          type: string
          description: >
            Identifier of the numeric data point the revenue is derived from.
            Required when `revenue_method` is `data_point`; the data point must
            exist, be `active`, and have type `number`.
        revenue_data_point_calculation:
          type: string
          enum:
            - current
            - accumulated
          default: accumulated
          description: >
            Which value of the data point to use. Mirrors
            `payout_data_point_calculation`.
        progress_settings:
          type: array
          description: >
            Exceptions to the cycle reset. Every metric and data point
            accumulates toward the rule's goals and, by default, resets at the
            end of each cycle; each entry here names one that carries its total
            over into the next cycle instead. Each metric may appear at most
            once. Only meaningful on calendar cycles — a `rule_duration` or
            `from_first_conversion` cycle never resets.
          items:
            $ref: "#/components/schemas/RuleProgressSetting"
        relationship:
          type: object
          readOnly: true
          description: >
            Related data, returned only when requested with the `relationship`
            query parameter.
          properties:
            scoped_payout_revenue_name:
              type: string
              description: >
                Display name of the event in `payout_revenue_id`. `Base` for the
                offer's base conversion.
            tied_payout_revenue_name:
              type: string
              description: >
                Display name of the event in `outcome_payout_revenue_id`.
        time_created:
          type: integer
          example: 1734455015
          readOnly: true
          description: Unix timestamp of creation.
        time_saved:
          type: integer
          example: 1734455015
          readOnly: true
          description: Unix timestamp of last update.
    RuleGoal:
      type: object
      required:
        - metric
        - operator
        - value
      properties:
        goal_id:
          type: integer
          readOnly: true
          description: Unique goal ID.
        metric:
          type: string
          enum:
            - revenue
            - payout
            - sale_amount
            - conversion
            - event
            - data_point
          description: >
            What the goal measures. `conversion` counts base conversions and
            cannot be combined with a `payout_revenue_id` that points to an
            event; `event` counts events and cannot be used when
            `payout_revenue_id` points to the base conversion.
        metric_data_point_identifier:
          type: string
          description: >
            Identifier of the data point the goal measures. Required when
            `metric` is `data_point`; the data point must exist and be `active`.
        logic:
          type: string
          enum:
            - min
            - max
            - sum
            - all
            - some
            - current
          description: >
            How the data point's values across the cycle are reduced before
            comparison. Required when `metric` is `data_point`. Use `min`, `max`,
            or `sum` for numeric data points and `all`, `some`, or `current` for
            text data points. `current` is not allowed with an `end_of_cycle`
            outcome trigger.
        operator:
          type: string
          enum:
            - greater_than
            - less_than
            - equals
            - begins_with
            - ends_with
            - contains
            - exact_match
          description: >
            Comparison applied to `value`. `greater_than`, `less_than`, and
            `equals` are numeric; `begins_with`, `ends_with`, `contains`, and
            `exact_match` are string comparisons.
        value:
          type: string
          example: "2"
          description: >
            The threshold, always sent as a string. Must parse as a number when
            the operator is numeric, and must be non-empty when the operator is a
            string comparison.
    RuleProgressSetting:
      type: object
      required:
        - metric
        - condition
      properties:
        setting_id:
          type: integer
          readOnly: true
          description: Unique progress setting ID.
        metric:
          type: string
          enum:
            - conversions
            - events
            - payout
            - revenue
            - sale_amount
            - data_points
          description: The metric whose accumulated total carries over.
        data_point_identifier:
          type: string
          description: >
            Identifier of the data point whose accumulated total carries over.
            Required when `metric` is `data_points`; the data point must exist
            and be `active`. Each data point may appear at most once.
        condition:
          type: string
          enum:
            - any_value
            - negative_balance
          description: >
            When the carry-over applies. `any_value` always carries the total
            over, so it never resets. `negative_balance` carries it over only
            when the total is negative at the cycle boundary — a zero or
            positive total resets as usual — so a customer left in the red by
            refunds or chargebacks starts the next cycle still in the red. Text
            data points have no balance and never carry over under this
            condition.
    RuleInput:
      allOf:
        - $ref: "#/components/schemas/Rule"
        - type: object
          required:
            - name
    RuleUpdateInput:
      allOf:
        - $ref: "#/components/schemas/Rule"
        - type: object
          required:
            - rule_id
            - name
  securitySchemes:
    API Key:
      description: The Everflow API key generated from the Control Center > Security.
      in: header
      name: X-Eflow-Api-Key
      type: apiKey
