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

# List this terminal's transactions

> Returns charges made by the calling terminal, newest first. Scope comes from the authenticated credential — there is no merchant or terminal query parameter, and one terminal can never read another's history.

This is also how you learn a VAT receipt number, since the charge response cannot carry one, and it doubles as a credential probe: `GET /v1/transactions?limit=1` returning `200` proves a username and password pair is live.



## OpenAPI

````yaml /openapi.json get /v1/transactions
openapi: 3.1.0
info:
  title: Vibepay Charge API
  version: 1.0.0
  description: >-
    The public API a merchant point-of-sale charges a Vibepay meal-benefit
    wallet against.


    A cardholder's card lives in Apple or Google Wallet as a pass that displays
    a rotating QR token. Your terminal scans that token, posts it here with an
    amount in tugrik, and the wallet is debited atomically. Every card charge
    also produces a Mongolian VAT receipt (ДДТД), issued asynchronously.


    This surface is authenticated per terminal with HTTP Basic and is intended
    for server-to-server or native POS callers. It sends no CORS headers, so a
    browser page cannot call it cross-origin.
  contact:
    name: Vibepay integrations
    email: info@vibepay.mn
    url: https://vibepay.mn
servers:
  - url: https://api.vibepay.mn
    description: >-
      Production. There is no separate sandbox — see the Environments guide for
      the small-amount charge-and-reverse loop used to verify an integration.
security:
  - terminalBasic: []
tags:
  - name: Transactions
    description: Charge a wallet, reverse a charge, and read this terminal's own history.
  - name: Service
    description: Unauthenticated liveness and readiness probes.
paths:
  /v1/transactions:
    get:
      tags:
        - Transactions
      summary: List this terminal's transactions
      description: >-
        Returns charges made by the calling terminal, newest first. Scope comes
        from the authenticated credential — there is no merchant or terminal
        query parameter, and one terminal can never read another's history.


        This is also how you learn a VAT receipt number, since the charge
        response cannot carry one, and it doubles as a credential probe: `GET
        /v1/transactions?limit=1` returning `200` proves a username and password
        pair is live.
      operationId: listTerminalTransactions
      parameters:
        - name: from
          in: query
          required: false
          description: >-
            Start of the window, inclusive, as an RFC 3339 timestamp. Defaults
            to 30 days ago.
          schema:
            type: string
            format: date-time
          example: '2026-08-01T00:00:00Z'
        - name: to
          in: query
          required: false
          description: >-
            End of the window, as an RFC 3339 timestamp. Defaults to now. Must
            not be earlier than `from`.
          schema:
            type: string
            format: date-time
          example: '2026-08-18T00:00:00Z'
        - name: cursor
          in: query
          required: false
          description: >-
            The `nextCursor` from the previous page. Opaque — do not parse or
            construct it. Omit for the first page.
          schema:
            type: string
        - name: limit
          in: query
          required: false
          description: Rows per page. Defaults to 100 and is clamped to 1000.
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
          example: 100
      responses:
        '200':
          description: One page of transactions, newest first.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionPage'
        '400':
          description: A query parameter was rejected.
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/PlainTextError'
              examples:
                badFrom:
                  summary: from is not RFC 3339
                  value: |
                    invalid `from` (expected RFC3339)
                badTo:
                  summary: to is not RFC 3339
                  value: |
                    invalid `to` (expected RFC3339)
                badRange:
                  summary: The window runs backwards
                  value: |
                    `from` must be before `to`
                badLimit:
                  summary: limit is not a positive integer
                  value: |
                    invalid `limit`
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  schemas:
    TransactionPage:
      type: object
      title: Transaction page
      required:
        - transactions
        - nextCursor
      properties:
        transactions:
          type: array
          description: This page of transactions, newest first.
          items:
            $ref: '#/components/schemas/TerminalTransaction'
        nextCursor:
          type: string
          description: >-
            Pass as `cursor` to fetch the next page. An empty string means there
            are no more pages.
          example: ''
    PlainTextError:
      type: string
      title: Plain-text error
      description: >-
        Every status other than `422` returns `text/plain; charset=utf-8` — a
        bare English message with a trailing newline, and no JSON and no error
        code. Branch on the HTTP status, not on this text.
    TerminalTransaction:
      type: object
      title: Transaction
      description: >-
        The projection a terminal sees. It deliberately omits the wallet, card,
        employer and merchant identifiers: a device handled by cashiers carries
        no more customer-identifying data than it needs.
      required:
        - id
        - amountMNT
        - status
        - type
        - vatReceiptID
        - createdAt
      properties:
        id:
          type: string
          description: >-
            Transaction identifier. Store this — it is the only handle for a
            later reversal.
          example: tx_01k2y7v9j0e8ra7cx3mbq4d5nf
        amountMNT:
          type: integer
          format: int64
          description: >-
            Amount in whole tugrik, always positive. A reversal does not negate
            it; `status` carries that instead.
          example: 12500
        status:
          type: string
          description: '`COMPLETED` for a live charge, `REVERSED` once it has been refunded.'
          enum:
            - COMPLETED
            - REVERSED
          example: COMPLETED
        type:
          type: string
          description: >-
            `CHARGE` is the only type a terminal creates. `CREDIT` (an employer
            top-up) and `RECLAIM` (a leaver's unspent balance being swept) exist
            elsewhere in the system and are never reversible from a terminal.
          enum:
            - CHARGE
            - CREDIT
            - RECLAIM
          example: CHARGE
        vatReceiptID:
          type: string
          description: >-
            The Mongolian VAT receipt number (ДДТД) once the tax authority has
            issued it. Empty on a fresh charge, because issuance is
            asynchronous. Retained after a reversal as the historical record.
          example: ''
        vatStatus:
          type: string
          description: >-
            Where the charge sits in the VAT pipeline. Present only on a
            `CHARGE`. `pending` means the receipt is queued, `issued` means
            `vatReceiptID` is populated, and `voided` means the charge was
            reversed and its receipt cancelled.
          enum:
            - pending
            - issued
            - voided
          example: pending
        terminalID:
          type: string
          description: >-
            The terminal that took the payment. Omitted on transactions created
            outside a terminal.
          example: ter_01k2y7v8t5f3s9wq1mzd7b6cxa
        createdAt:
          type: string
          format: date-time
          description: When the transaction committed, as an RFC 3339 timestamp in UTC.
          example: '2026-08-18T09:14:22.481739Z'
  responses:
    Unauthorized:
      description: >-
        The credentials are missing, unrecognized, wrong, or belong to a
        suspended terminal. All four cases are indistinguishable by design. Stop
        retrying and re-pair the terminal.
      headers:
        WWW-Authenticate:
          description: Always `Basic realm="vibepay-terminal"`.
          schema:
            type: string
      content:
        text/plain:
          schema:
            $ref: '#/components/schemas/PlainTextError'
          examples:
            unauthorized:
              summary: Any authentication failure
              value: |
                unauthorized
    TooManyRequests:
      description: >-
        The API gateway's request ceiling was hit. The limit applies to the
        whole surface rather than to your terminal alone, so back off
        exponentially with jitter and retry — reusing the same `Idempotency-Key`
        if you are retrying a charge.
      content:
        application/json:
          schema:
            type: object
            properties:
              message:
                type: string
                description: Always `Too Many Requests`.
    InternalError:
      description: >-
        Something failed on Vibepay's side. The charge may or may not have been
        applied, so never assume it failed: retry with the same
        `Idempotency-Key`, or confirm with `GET /v1/transactions` before handing
        goods over.
      content:
        text/plain:
          schema:
            $ref: '#/components/schemas/PlainTextError'
          examples:
            internal:
              summary: Unexpected server error
              value: |
                internal error
  securitySchemes:
    terminalBasic:
      type: http
      scheme: basic
      description: >-
        Per-terminal HTTP Basic credentials, issued in the Vibepay merchant
        dashboard under Terminals. The username starts with `term_` and the
        password with `vpt_`. Every authentication failure — missing header,
        unknown username, wrong password, suspended terminal — returns the same
        `401`, so the response can never be used to discover valid usernames.

````