> ## 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.

# Reverse an event's awards

> Claw back value credited by a completed event's rules. Recovery is scoped to value still traceable to each original award and still owned by the originally credited participant or group; anything spent, expired, transferred, or currently held is reported as shortfall, never forced. V1 supports only the report shortfall policy. Cumulative reversals are capped at each original award: a request that exceeds the remaining reversible value is rejected with a conflict. State changes (counters, tags, tiers) are reported but never reverted.

Claws back value that a `COMPLETED` event's rules credited. Recovery targets the lots the original awards created, where that value is still held by the originally credited participant or group; anything already spent, expired, transferred, or currently held is reported as `shortfall_amount`, never forced. Scrip caps cumulative reversals at each original award, so repeated partial reversals cannot claw back more than was earned.

Omit `fraction` to reverse all remaining value, or pass a decimal string like `"0.5"` to reverse that share of every award line. A request that exceeds an award's remaining reversible value returns `409 Conflict` instead of clamping. The response reports each award line's requested, recovered, and shortfall amounts, lists any of the event's credit entries that are not reversible (with reasons), and includes the event's state changes. State changes are never reverted; send a compensating event if your program logic requires it.

<Note>
  For when to use this endpoint versus an event-based clawback, see [Reversing an event](/guides/event-processing#reversing-an-event) and the [refund patterns](/examples/common-patterns#reversal--refund).
</Note>


## OpenAPI

````yaml POST /v1/events/{id}/reverse
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/events/{id}/reverse:
    post:
      tags:
        - Events
      summary: Reverse an event's awards
      description: >-
        Claw back value credited by a completed event's rules. Recovery is
        scoped to value still traceable to each original award and still owned
        by the originally credited participant or group; anything spent,
        expired, transferred, or currently held is reported as shortfall, never
        forced. V1 supports only the report shortfall policy. Cumulative
        reversals are capped at each original award: a request that exceeds the
        remaining reversible value is rejected with a conflict. State changes
        (counters, tags, tiers) are reported but never reverted.
      operationId: reverseEvent
      parameters:
        - description: Event ID
          in: path
          name: id
          required: true
          schema:
            format: uuid
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/handlers.ReverseEventRequest'
        description: Reversal details
        required: true
        x-originalParamName: request
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/handlers.EventReversalResponse'
          description: Duplicate request (idempotency key matched, returns existing record)
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/handlers.EventReversalResponse'
          description: Reversal created
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/handlers.ErrBadRequestResponse'
          description: >-
            Validation failed (code: validation_error | bad_request |
            invalid_fraction | invalid_shortfall_policy)
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/handlers.ErrUnauthorizedResponse'
          description: 'Missing or invalid credentials (code: unauthorized)'
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/handlers.ErrNotFoundResponse'
          description: 'Event not found (code: not_found)'
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/handlers.ErrConflictResponse'
          description: >-
            Request exceeds remaining reversible value, event not reversible, or
            idempotency conflict (code: conflict)
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/handlers.ErrUnprocessableResponse'
          description: >-
            The event has no reversible award entries or the fraction rounds to
            zero (code: nothing_reversible | fraction_rounds_to_zero)
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/handlers.ErrInternalResponse'
          description: 'Internal server error (code: internal_error)'
      security:
        - ApiKeyAuth: []
        - BearerAuth: []
components:
  schemas:
    handlers.ReverseEventRequest:
      additionalProperties: false
      properties:
        fraction:
          description: >-
            Fraction of each original award to reverse, as a decimal string
            greater

            than 0 and at most 1. Omit to reverse all remaining value.
          example: '0.5'
          type: string
        idempotency_key:
          description: >-
            Required. The same key replays the original result; a different
            payload

            under the same key is rejected.
          example: refund-order-456-1
          maxLength: 255
          minLength: 1
          type: string
        reason:
          description: Optional context recorded on the reversal and its ledger entries.
          example: partial refund
          maxLength: 500
          type: string
        shortfall_policy:
          description: >-
            Shortfall handling policy. V1 supports report only; omitted defaults
            to report.
          enum:
            - report
          example: report
          type: string
      required:
        - idempotency_key
      type: object
    handlers.EventReversalResponse:
      properties:
        created_at:
          example: '2026-07-20T10:30:00Z'
          format: date-time
          type: string
        event_id:
          example: 550e8400-e29b-41d4-a716-446655440000
          format: uuid
          type: string
        fraction:
          example: '0.5'
          type: string
        id:
          example: 550e8400-e29b-41d4-a716-446655440000
          format: uuid
          type: string
        idempotency_key:
          example: refund-order-456-1
          type: string
        ineligible_entries:
          description: >-
            CREDIT entries of the event this reversal did not process, with
            reasons
          items:
            $ref: '#/components/schemas/handlers.IneligibleEntryResponse'
          type: array
        lines:
          description: Per original award line accounting
          items:
            $ref: '#/components/schemas/handlers.EventReversalLineResponse'
          type: array
        reason:
          example: partial refund
          type: string
        shortfall_policy:
          enum:
            - report
          example: report
          type: string
        state_changes:
          description: >-
            The original event's state changes (counters, tags, attributes,
            tiers).

            Reversals never revert state automatically; send a compensating
            event if

            your program logic requires it.
          items:
            $ref: '#/components/schemas/handlers.StateChangeResponse'
          type: array
        status:
          example: COMPLETED
          type: string
      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.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.ErrConflictResponse:
      properties:
        code:
          description: Code is the machine-readable error code
          example: conflict
          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 already exists or state conflict
          type: string
      type: object
    handlers.ErrUnprocessableResponse:
      properties:
        code:
          description: Code is the machine-readable error code
          example: unprocessable
          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: Business rule violation
          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
    handlers.IneligibleEntryResponse:
      properties:
        journal_entry_id:
          example: 550e8400-e29b-41d4-a716-446655440000
          format: uuid
          type: string
        reason:
          description: >-
            Why the entry is not reversible: SETTLEMENT_SHAPED,
            COMPLEX_POSTINGS, SIMPLE_ASSET, or NO_ENTITY_DESTINATION
          example: SETTLEMENT_SHAPED
          type: string
      type: object
    handlers.EventReversalLineResponse:
      properties:
        asset_id:
          description: Asset of the award
          example: 550e8400-e29b-41d4-a716-446655440000
          format: uuid
          type: string
        ledger_entity_id:
          description: Ledger entity that was originally credited
          example: 550e8400-e29b-41d4-a716-446655440000
          format: uuid
          type: string
        original_amount:
          description: Amount the original award credited
          example: '54.25'
          type: string
        original_journal_entry_id:
          description: Journal entry of the original award
          example: 550e8400-e29b-41d4-a716-446655440000
          format: uuid
          type: string
        recovered_amount:
          description: >-
            Amount actually recovered from value still traceable to the original
            award
          example: '27.13'
          type: string
        requested_amount:
          description: Amount this reversal asked to claw back from this line
          example: '27.13'
          type: string
        reversal_journal_entry_id:
          description: >-
            REVERSAL journal entry that debited the recovered value; absent when
            nothing was recovered
          example: 550e8400-e29b-41d4-a716-446655440000
          format: uuid
          type: string
        shortfall_amount:
          description: >-
            Requested value that could not be recovered (spent, expired,
            transferred, or held)
          example: '0'
          type: string
      type: object
    handlers.StateChangeResponse:
      properties:
        changed_at:
          description: When the change occurred (RFC 3339)
          example: '2024-01-15T10:30:00Z'
          format: date-time
          type: string
        entity_id:
          description: Public UUID of the affected entity
          example: 550e8400-e29b-41d4-a716-446655440000
          format: uuid
          type: string
        entity_type:
          description: 'Entity type affected: PARTICIPANT, GROUP, or PROGRAM'
          example: PARTICIPANT
          type: string
        key:
          description: The key that changed
          example: lifetime_spend
          type: string
        new_value:
          description: New value (null for deletes)
          example: '575'
          type: string
        old_value:
          description: Previous value (null for new keys)
          example: '500'
          type: string
        operation:
          description: 'What happened: set, delete, or auto_reset'
          example: set
          type: string
        program_id:
          description: Program scope for tier changes
          example: 550e8400-e29b-41d4-a716-446655440002
          format: uuid
          type: string
        rule_id:
          description: Rule that caused this change
          example: 550e8400-e29b-41d4-a716-446655440001
          format: uuid
          type: string
        state_type:
          description: 'Type of state: tag, counter, attribute, or tier'
          example: counter
          type: string
      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
    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
  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

````