Skip to main content
POST
/
registers
/
{registerId}
/
exchanges
Start an exchange
curl --request POST \
  --url https://api.openfiskal.com/v1/registers/{registerId}/exchanges \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "original_operation_id": "<string>",
  "cashier": {
    "id": "<string>",
    "display_name": "Maria R."
  },
  "external_id": "<string>",
  "currency": "EUR",
  "metadata": {}
}
'
{
  "id": "op_01HXYZ",
  "object": "<string>",
  "type": "sale",
  "state": "open",
  "register_id": "<string>",
  "location_id": "<string>",
  "organization_id": "<string>",
  "external_id": "<string>",
  "sequence_number": 123,
  "cashier": {
    "id": "<string>",
    "display_name": "Maria R."
  },
  "fiscal": {
    "regime": "<string>",
    "document_type": "Kassenbeleg",
    "transmission_status": "transmitted",
    "fiscal_unit_id": "fu_01HXYZ",
    "document_number": "2026-004822",
    "transmitted_at": "2023-11-07T05:31:56Z",
    "verification": {
      "url": "<string>",
      "qr_data": "<string>"
    },
    "tse_serial": "<string>",
    "client_id": "<string>",
    "signature_algorithm": "ecdsa-plain-SHA384",
    "time_format": "utcTime",
    "start_event": {
      "signed_at": "2023-11-07T05:31:56Z",
      "transaction_counter": 4821,
      "signature": "aSDinaTvuI8gbWludGxpZnk=",
      "process_type": "<string>",
      "process_data": "<string>"
    },
    "end_event": {
      "signed_at": "2023-11-07T05:31:56Z",
      "transaction_counter": 4821,
      "signature": "aSDinaTvuI8gbWludGxpZnk=",
      "process_type": "<string>",
      "process_data": "<string>"
    }
  },
  "fiscal_state": "pending",
  "references": {
    "original_operation_id": "<string>",
    "reason": "<string>"
  },
  "metadata": {},
  "started_at": "2023-11-07T05:31:56Z",
  "completed_at": "2023-11-07T05:31:56Z",
  "created_at": "2023-11-07T05:31:56Z",
  "data": {
    "original_operation_id": "<string>",
    "currency": "<string>",
    "returned_line_items": [
      {
        "id": "li_01HXYZ",
        "position": 1,
        "description": "Wiener Schnitzel",
        "quantity": 2,
        "unit": "piece",
        "unit_price_gross": 1800,
        "product_ref": "<string>",
        "flags": [
          "deposit"
        ],
        "subtotal_gross": 3600,
        "line_discounts": [
          {
            "source": "manual",
            "amount": 360,
            "id": "ldsc_01HXYZ",
            "type": "percentage",
            "label": "Happy Hour",
            "rate": "0.10"
          }
        ],
        "line_discount_amount": 360,
        "subtotal_after_line_discounts": 3240,
        "cart_discount_allocations": [
          {
            "discount_id": "cdsc_01HXYZ",
            "amount": 162,
            "label": "SAVE10 coupon"
          }
        ],
        "cart_discount_amount": 324,
        "total_gross": 2916,
        "tax": {
          "rate": "0.19",
          "category": "standard",
          "included_in_price": true,
          "taxable_amount": 2651,
          "tax_amount": 265
        },
        "total_net": 2651
      }
    ],
    "new_line_items": [
      {
        "id": "li_01HXYZ",
        "position": 1,
        "description": "Wiener Schnitzel",
        "quantity": 2,
        "unit": "piece",
        "unit_price_gross": 1800,
        "product_ref": "<string>",
        "flags": [
          "deposit"
        ],
        "subtotal_gross": 3600,
        "line_discounts": [
          {
            "source": "manual",
            "amount": 360,
            "id": "ldsc_01HXYZ",
            "type": "percentage",
            "label": "Happy Hour",
            "rate": "0.10"
          }
        ],
        "line_discount_amount": 360,
        "subtotal_after_line_discounts": 3240,
        "cart_discount_allocations": [
          {
            "discount_id": "cdsc_01HXYZ",
            "amount": 162,
            "label": "SAVE10 coupon"
          }
        ],
        "cart_discount_amount": 324,
        "total_gross": 2916,
        "tax": {
          "rate": "0.19",
          "category": "standard",
          "included_in_price": true,
          "taxable_amount": 2651,
          "tax_amount": 265
        },
        "total_net": 2651
      }
    ],
    "payments": [
      {
        "method": "cash",
        "direction": "inbound",
        "amount": 4250,
        "currency": "<string>",
        "reference": "<string>",
        "cash": {
          "amount_tendered": 5000
        },
        "card": {
          "scheme": "visa",
          "last4": "4242",
          "authorization_code": "<string>",
          "terminal_id": "<string>",
          "application_id": "<string>"
        },
        "wallet": {
          "provider": "apple_pay",
          "scheme": "visa",
          "last4": "4242",
          "authorization_code": "<string>"
        },
        "voucher": {
          "code": "SUMMER20",
          "type": "promotional"
        },
        "gift_card": {
          "gift_card_id": "<string>",
          "last4": "8821"
        },
        "online": {
          "provider": "paypal",
          "transaction_reference": "<string>"
        },
        "id": "<string>",
        "status": "approved"
      }
    ],
    "totals": {
      "subtotal_gross": 123,
      "total_line_discounts": 123,
      "subtotal_after_line_discounts": 123,
      "total_cart_discounts": 123,
      "subtotal_after_all_discounts": 123,
      "rounding_adjustment": 123,
      "total_gross": 123,
      "total_net": 123,
      "total_tax": 123,
      "tax_breakdown": [
        {
          "rate": "<string>",
          "category": "<string>",
          "taxable_amount": 123,
          "tax_amount": 123,
          "total_gross": 123
        }
      ],
      "net_payable": 123
    }
  }
}

Authorizations

Authorization
string
header
required

Platform API key sent as Authorization: Bearer ofk_platform_.... Platform integrators also pass OpenFiskal-Organization: org_xxx to act on behalf of a merchant.

Headers

OpenFiskal-Organization
string

Merchant organization ID. Required for platform integrators acting on behalf of a specific merchant. Omit when using an organization-scoped API key directly.

Idempotency-Key
string<uuid>

Unique key to make the request idempotent. If a request with this key was already processed, the original response is returned without re-executing the operation. Strongly recommended on all start and complete actions — these are fiscal events and must not be duplicated.

Path Parameters

registerId
string
required

Body

application/json
original_operation_id
string
required

The original sale being exchanged

cashier
object
external_id
string
currency
string<iso-4217>
Example:

"EUR"

metadata
object

Response

Exchange started

Shared fields present on every operation regardless of type.

id
string
Example:

"op_01HXYZ"

object
string
Allowed value: "operation"
type
enum<string>
Available options:
sale,
refund,
exchange,
void,
cash_movement,
deposit,
deposit_capture,
training
Allowed value: "exchange"
state
enum<string>

The POS lifecycle state of the operation. Transitions are one-directional and enforced server-side — invalid transitions return 409 Conflict.

  • open — operation in progress, mutations allowed
  • completed — POS finalized the operation (payment collected)
  • cancelled — POS cancelled before completion

Valid transitions

FromEventTo
openPOST .../completecompleted
openPOST .../cancelcancelled
Available options:
open,
completed,
cancelled
register_id
string
location_id
string
organization_id
string
external_id
string | null
sequence_number
integer

Monotonically increasing, register-scoped sequence number

cashier
object
fiscal
object

Jurisdiction-specific fiscal output attached to every operation. Discriminated by regime — each variant carries typed fields for its fiscal security device and signing protocol.

fiscal_state
enum<string>

The fiscalization state of the operation, tracked independently from the operation state.

  • pending — fiscalization not yet attempted or in progress
  • succeeded — fiscal device recorded the event, fiscal data available
  • failed — fiscalization failed (device unreachable, transmission error)

The POS should check fiscal.state before printing — only print fiscal data on the receipt when it is succeeded.

Available options:
pending,
succeeded,
failed
references
object

Links to related operations. The audit chain between operations lives here at the envelope level — not inside the type-specific data block — because any operation type can reference any other.

metadata
object
started_at
string<date-time>

Timestamp of the fiscal start event

completed_at
string<date-time> | null
created_at
string<date-time>
data
object