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

# Arm the next subscription collection outcome

> Configures a one-shot outcome for the next automatic collection attempt
on an owned test-mode subscription. The next newly recorded charge
attempt consumes the scenario. A retry of that same attempt observes
the same result, while a later retry requires a new scenario.

Arm a decline before advancing to a renewal or retry boundary. After
Ionic records the failed attempt and schedules the next retry, arm a
success and advance to that retry time to verify recovery. Platforms
can use the resulting Ionic objects and events to verify access control,
notifications, reporting, and connected-account isolation.

Only one unconsumed scenario may exist for a subscription. When no
scenario is armed, automatic collection follows the normal test-mode
collection path.




## OpenAPI

````yaml /openapi/test-clocks.yaml post /test_helpers/subscriptions/{id}/collection_scenarios
openapi: 3.0.3
info:
  title: Ionic Test Clocks API
  version: '2026-08-30'
  description: |
    Advance logical time for test customers and their recurring billing
    objects. Test clocks let you exercise trials, renewals, collection retries,
    scheduled cancellations, and recovery without waiting for wall-clock time.

    Ionic remains authoritative for subscription state, invoices, collection
    schedules, and public events. Platforms use the resulting objects and
    events to verify their own access control, notifications, reporting, and
    account state. A successful Ionic billing transition can still produce a
    broken customer experience if an integration applies it to the wrong
    account, applies it twice, or reacts at the wrong lifecycle stage.

    Test clocks are available only with test-mode credentials and can affect
    only test objects owned by the selected Ionic account. An authorized
    platform may use the `Ionic-Account` header to operate a connected test
    account. Live objects never use logical test time.

    Advancement is asynchronous. Poll the returned clock until `status` is
    `ready` before asserting the final billing state. All timestamps are Unix
    epoch seconds.
servers:
  - url: '{baseUrl}/v1'
    variables:
      baseUrl:
        default: https://api.ionicfi.com
        description: Ionic API base URL.
security:
  - secretKey: []
tags:
  - name: Test clocks
    description: Accelerate test-mode recurring billing scenarios.
paths:
  /test_helpers/subscriptions/{id}/collection_scenarios:
    post:
      tags:
        - Test clocks
      summary: Arm the next subscription collection outcome
      description: |
        Configures a one-shot outcome for the next automatic collection attempt
        on an owned test-mode subscription. The next newly recorded charge
        attempt consumes the scenario. A retry of that same attempt observes
        the same result, while a later retry requires a new scenario.

        Arm a decline before advancing to a renewal or retry boundary. After
        Ionic records the failed attempt and schedules the next retry, arm a
        success and advance to that retry time to verify recovery. Platforms
        can use the resulting Ionic objects and events to verify access control,
        notifications, reporting, and connected-account isolation.

        Only one unconsumed scenario may exist for a subscription. When no
        scenario is armed, automatic collection follows the normal test-mode
        collection path.
      operationId: subscription_test_helpers_collection_scenarios_create
      parameters:
        - $ref: '#/components/parameters/SubscriptionId'
        - $ref: '#/components/parameters/IdempotencyKey'
        - $ref: '#/components/parameters/IonicAccount'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateSubscriptionCollectionScenarioRequest'
            examples:
              decline:
                summary: Decline the next attempt
                value:
                  outcome: declined
                  decline_code: insufficient_funds
              success:
                summary: Succeed on the next attempt
                value:
                  outcome: succeeded
      responses:
        '201':
          description: The armed one-shot collection scenario.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionCollectionScenario'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/TestModeRequired'
        '404':
          $ref: '#/components/responses/SubscriptionNotFound'
        '409':
          $ref: '#/components/responses/ScenarioConflict'
        '422':
          $ref: '#/components/responses/InvalidSubscriptionState'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - secretKey:
            - subscriptions:write
components:
  parameters:
    SubscriptionId:
      name: id
      in: path
      required: true
      description: >-
        Subscription whose next automatic collection attempt will consume the
        scenario.
      schema:
        type: string
        pattern: ^sub_[0-9A-Za-z]{24}$
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: true
      description: Unique key used to replay this mutation safely.
      schema:
        type: string
        minLength: 1
        maxLength: 255
    IonicAccount:
      name: Ionic-Account
      in: header
      required: false
      description: |
        Connected Ionic account to operate when using an authorized platform
        credential. Omit when using the account's own credential.
      schema:
        type: string
  schemas:
    CreateSubscriptionCollectionScenarioRequest:
      type: object
      additionalProperties: false
      required:
        - outcome
      properties:
        outcome:
          type: string
          enum:
            - succeeded
            - declined
        decline_code:
          type: string
          description: >-
            Required for a declined outcome and omitted for a successful
            outcome.
          enum:
            - insufficient_funds
            - card_velocity_exceeded
            - withdrawal_count_limit
            - do_not_honor
            - generic_decline
            - transaction_not_permitted
            - expired_card
            - incorrect_number
            - incorrect_cvc
            - duplicate_transaction
            - stolen_card
            - lost_card
            - fraudulent
            - pickup_card
            - restricted_card
            - security_violation
            - processing_error
            - issuer_not_available
            - try_again_later
            - processor_declined
    SubscriptionCollectionScenario:
      type: object
      additionalProperties: false
      required:
        - id
        - object
        - merchant_id
        - subscription_id
        - livemode
        - outcome
        - consumed
        - created_at
      properties:
        id:
          type: string
          format: uuid
        object:
          type: string
          enum:
            - subscription.collection_scenario
        merchant_id:
          type: string
          pattern: ^mer_[0-9A-Za-z]{14}$
        subscription_id:
          type: string
          pattern: ^sub_[0-9A-Za-z]{24}$
        livemode:
          type: boolean
          enum:
            - false
        outcome:
          type: string
          enum:
            - succeeded
            - declined
        decline_code:
          type: string
        consumed:
          type: boolean
        consumed_at:
          type: integer
          format: int64
        created_at:
          type: integer
          format: int64
    ErrorEnvelope:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
            message:
              type: string
  responses:
    BadRequest:
      description: Malformed identifier, body, timestamp, or idempotency key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    Unauthorized:
      description: Authentication failed.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    TestModeRequired:
      description: >-
        Subscription testing resources cannot be used with a live-mode
        credential.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    SubscriptionNotFound:
      description: The subscription does not exist in the selected account and mode.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    ScenarioConflict:
      description: >-
        An unconsumed collection scenario is already armed for this
        subscription.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    InvalidSubscriptionState:
      description: The subscription is ended or does not use automatic collection.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    RateLimited:
      description: Concurrent test-clock advancement limit exceeded.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    InternalError:
      description: Ionic could not complete the request.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
  securitySchemes:
    secretKey:
      type: http
      scheme: bearer
      bearerFormat: Ionic secret key

````