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

# Create a simulated Terminal

> Creates a ready logical Terminal for the authenticated Merchant and
test mode. The returned `tmr_…` is a normal Terminal ID: retain and
reuse it across test runs. No physical provisioning request, hardware
assignment, serial number, or device credential is created or returned.




## OpenAPI

````yaml /openapi/terminal-testing.yaml post /terminals
openapi: 3.0.3
info:
  title: Ionic Terminal Testing API
  version: '2026-08-24'
  description: |
    Create reusable, Merchant-owned simulated Terminals and arm deterministic
    one-shot card-present outcomes. These endpoints accept only test-mode
    secret keys and never provision or contact physical hardware.

    After arming a scenario, process its exact PaymentIntent through the normal
    `POST /terminals/{id}/process_payment_intent` endpoint. Your POS
    integration stays the same when you move from the simulator to a physical
    Terminal.
servers:
  - url: '{baseUrl}/v1'
    variables:
      baseUrl:
        default: https://api.ionicfi.com
        description: API base URL for the selected environment.
security:
  - secretKey: []
tags:
  - name: Terminal Testing
    description: Build automated card-present tests without physical hardware.
paths:
  /terminals:
    post:
      tags:
        - Terminal Testing
      summary: Create a simulated Terminal
      description: |
        Creates a ready logical Terminal for the authenticated Merchant and
        test mode. The returned `tmr_…` is a normal Terminal ID: retain and
        reuse it across test runs. No physical provisioning request, hardware
        assignment, serial number, or device credential is created or returned.
      operationId: createSimulatedTerminal
      parameters:
        - $ref: '#/components/parameters/IonicAccount'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateSimulatedTerminalRequest'
            example:
              type: simulated
              location_id: loc_R7pA3nB9qK2mX5
              label: CI checkout reader
              metadata:
                test_suite: checkout
      responses:
        '201':
          description: A ready simulated Terminal.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Terminal'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/LocationNotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - secretKey:
            - terminals:write
components:
  parameters:
    IonicAccount:
      name: Ionic-Account
      in: header
      required: false
      description: |
        Merchant ID when an authorized Platform acts for a connected Merchant.
        Omit when authenticating directly as that Merchant.
      schema:
        type: string
        pattern: ^mer_[0-9A-Za-z]{14}$
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: true
      description: Reuse only when retrying the same route and request body.
      schema:
        type: string
        minLength: 1
        maxLength: 255
  schemas:
    CreateSimulatedTerminalRequest:
      type: object
      additionalProperties: false
      required:
        - type
        - location_id
        - label
      properties:
        type:
          type: string
          enum:
            - simulated
          description: >-
            Creates a logical test Terminal. Physical hardware uses terminal
            provisioning instead.
        location_id:
          type: string
          pattern: ^loc_[0-9A-Za-z]{14}$
          description: Test-mode location owned by the same Merchant.
        label:
          type: string
          minLength: 1
          maxLength: 100
        metadata:
          type: object
          additionalProperties:
            type: string
    Terminal:
      type: object
      additionalProperties: false
      required:
        - id
        - object
        - merchant_id
        - location_id
        - livemode
        - label
        - device
        - status
        - connection_status
        - connection_status_stale
        - connection_observed_at
        - capabilities
        - last_seen_at
        - metadata
        - created_at
        - updated_at
      properties:
        id:
          type: string
          pattern: ^tmr_[0-9A-Za-z]{14}$
        object:
          type: string
          enum:
            - terminal
        merchant_id:
          type: string
          pattern: ^mer_[0-9A-Za-z]{14}$
        location_id:
          type: string
          pattern: ^loc_[0-9A-Za-z]{14}$
        livemode:
          type: boolean
          enum:
            - false
        label:
          type: string
        device:
          $ref: '#/components/schemas/TerminalDevice'
        status:
          type: string
          enum:
            - provisioning
            - requires_action
            - ready
            - disabled
            - replacing
            - failed
        connection_status:
          type: string
          enum:
            - online
            - offline
            - unknown
        connection_status_stale:
          type: boolean
        connection_observed_at:
          type: integer
          format: int64
          nullable: true
        capabilities:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/TerminalCapability'
        last_seen_at:
          type: integer
          format: int64
          nullable: true
        metadata:
          type: object
          additionalProperties:
            type: string
        created_at:
          type: integer
          format: int64
        updated_at:
          type: integer
          format: int64
    TerminalDevice:
      type: object
      additionalProperties: false
      required:
        - model
        - serial_number_last4
      properties:
        model:
          type: string
          example: Ionic Simulator
        serial_number_last4:
          type: string
          pattern: ^[0-9A-Za-z]{4}$
    TerminalCapability:
      type: object
      additionalProperties: false
      required:
        - support
        - status
      properties:
        support:
          type: string
          enum:
            - supported
            - unsupported
            - conditional
        status:
          type: string
          enum:
            - ready
            - pending
            - not_ready
            - unknown
        reason:
          type: string
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
            message:
              type: string
  responses:
    BadRequest:
      description: Invalid JSON, field value, resource mode, or scenario combination.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Missing or invalid API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: >-
        Inactive Merchant, invalid delegation, or missing `terminals:write`
        permission.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    LocationNotFound:
      description: The location was not found in the authenticated Merchant and test mode.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Conflict:
      description: Idempotency or resource uniqueness conflict.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    RateLimited:
      description: Too many requests.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    InternalError:
      description: Unexpected server error.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    secretKey:
      type: http
      scheme: bearer
      bearerFormat: Ionic test secret key
      description: >-
        A test-mode Merchant secret key, or an authorized Platform test key with
        delegation.

````