Skip to content

Point of Sale

Point of Sale

Tables and open tabs for on-location selling. A tab is a running order, not a document: it carries no number, is never fiscalized and holds no payments. It becomes an invoice through the normal POST /invoices flow.

The lifecycle of a tab is:

1. POST /pos/tabs opens one, optionally on a table.
2. POST /pos/tabs/{id}/items adds to it. Appends to an open tab are additive: concurrent additions serialize and merge quantities on matching lines. New appends return 409 already_claimed while a payment claim is active. Retrying a previously accepted append_id returns the current tab without adding the items again.
3. POST /pos/tabs/{id}/claim reserves it for one device before payment, so a second device cannot issue the same tab and produce a duplicate invoice and duplicate fiscal record. Claims expire after five minutes.
4. Issue the invoice however you normally would, then POST /pos/tabs/{id}/close with the invoice_id. Close is idempotent, which is what makes a lost response after a successful issue recoverable.

Edits and removals use PATCH /pos/tabs/{id} with expected_version and get a 409 carrying the current tab if another device changed it first.

To keep devices in a venue in sync, poll GET /pos/tabs and send the previous ETag back as If-None-Match; an unchanged venue answers 304.

The Point of Sale object

object

Attributes

idstring
Other attributes
entity_idstring
table_idstringnullable
statusstring
itemsarray of objects
notestringnullable
customer_idstringnullable
opened_by_user_idstringnullable
updated_by_user_idstringnullable
claimed_by_devicestringnullable
claimed_atstring<date-time>nullable
invoice_idstringnullable
versioninteger
opened_atstring<date-time>
issued_atstring<date-time>nullable
metadatastringnullable
deleted_atstring<date-time>nullable
created_atstring<date-time>
updated_atstring<date-time>
Examplejson
{
  "id": "ptab_65f1a2b3c4d5e6f7a8b9c0d5",
  "entity_id": "ent_65f1a2b3c4d5e6f7a8b9c0d2",
  "table_id": "ptbl_65f1a2b3c4d5e6f7a8b9c0d1",
  "status": "open",
  "items": [
    {
      "line_id": "line_7f3a",
      "item_id": "item_65f1a2b3c4d5e6f7a8b9c0d3",
      "name": "Glass of red wine",
      "quantity": 2,
      "unit_gross_price": 5.5,
      "discount_percent": null,
      "tax_rates": null,
      "note": null,
      "added_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
      "added_at": "2026-07-31T20:12:00.000Z"
    }
  ],
  "note": null,
  "customer_id": null,
  "opened_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
  "updated_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
  "claimed_by_device": null,
  "claimed_at": null,
  "invoice_id": null,
  "version": 3,
  "opened_at": "2026-07-31T20:05:00.000Z",
  "issued_at": null,
  "metadata": {},
  "deleted_at": null,
  "created_at": "2026-07-31T20:05:00.000Z",
  "updated_at": "2026-07-31T20:12:00.000Z"
}

Create a point-of-sale table

POST/pos/tables

Create a point-of-sale table

Header parameters

entity_idstringoptional

Entity ID on which the request is made. Auto-selected when only one entity exists, required when multiple entities exist.

Body parameters

labelstringrequired

Table name as staff refer to it — "1", "12", "Terrace 3".

Other parameters
sort_orderintegeroptionalnullable
is_activebooleanoptionalnullable
metadataobjectoptionalnullable
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';

const sdk = new SpaceInvoices('YOUR_API_KEY');

const response = await sdk.pointOfSale.createTable({
  label: "4",
  sort_order: 4
});

console.log(response);

Returns

idstring
Other parameters
entity_idstring
labelstring
sort_orderinteger
is_activeboolean
metadatastringnullable
deleted_atstring<date-time>nullable
created_atstring<date-time>
updated_atstring<date-time>
json
{
  "id": "ptbl_65f1a2b3c4d5e6f7a8b9c0d1",
  "entity_id": "ent_65f1a2b3c4d5e6f7a8b9c0d2",
  "label": "4",
  "sort_order": 4,
  "is_active": true,
  "metadata": {},
  "deleted_at": null,
  "created_at": "2026-07-31T18:00:00.000Z",
  "updated_at": "2026-07-31T18:00:00.000Z"
}

Open a tab

POST/pos/tabs

Open a tab

Header parameters

entity_idstringoptional

Entity ID on which the request is made. Auto-selected when only one entity exists, required when multiple entities exist.

Body parameters

table_idstringoptionalnullable
itemsarray of objectsoptionalnullable
notestringoptionalnullable
customer_idstringoptionalnullable
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';

const sdk = new SpaceInvoices('YOUR_API_KEY');

const response = await sdk.pointOfSale.createTab({
  table_id: "ptbl_65f1a2b3c4d5e6f7a8b9c0d1"
});

console.log(response);

Returns

idstring
Other parameters
entity_idstring
table_idstringnullable
statusstring
itemsarray of objects
notestringnullable
customer_idstringnullable
opened_by_user_idstringnullable
updated_by_user_idstringnullable
claimed_by_devicestringnullable
claimed_atstring<date-time>nullable
invoice_idstringnullable
versioninteger
opened_atstring<date-time>
issued_atstring<date-time>nullable
metadatastringnullable
deleted_atstring<date-time>nullable
created_atstring<date-time>
updated_atstring<date-time>
json
{
  "id": "ptab_65f1a2b3c4d5e6f7a8b9c0d5",
  "entity_id": "ent_65f1a2b3c4d5e6f7a8b9c0d2",
  "table_id": "ptbl_65f1a2b3c4d5e6f7a8b9c0d1",
  "status": "open",
  "items": [],
  "note": null,
  "customer_id": null,
  "opened_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
  "updated_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
  "claimed_by_device": null,
  "claimed_at": null,
  "invoice_id": null,
  "version": 1,
  "opened_at": "2026-07-31T20:05:00.000Z",
  "issued_at": null,
  "metadata": {},
  "deleted_at": null,
  "created_at": "2026-07-31T20:05:00.000Z",
  "updated_at": "2026-07-31T20:12:00.000Z"
}

Switch the acting operator

POST/pos/operators/switch

Verifies the PIN and returns a shift-length token for that member, so the sales they ring up carry their own fiscal operator identity. Requires an existing valid session for the same entity. Repeated failures lock the PIN with an escalating backoff.

Header parameters

entity_idstringoptional

Entity ID on which the request is made. Auto-selected when only one entity exists, required when multiple entities exist.

Body parameters

user_idstringrequired
pinstringrequired
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';

const sdk = new SpaceInvoices('YOUR_API_KEY');

const response = await sdk.pointOfSale.switchOperator({
  user_id: "usr_65f1a2b3c4d5e6f7a8b9c0d8",
  pin: "482"
});

console.log(response);

Returns

idstring

Bearer token for the switched-to operator.

Other parameters
user_idstring
entity_idstring
ttlinteger
scopestringnullable
created_atstring<date-time>
json
{
  "id": "tok_65f1a2b3c4d5e6f7a8b9c0da",
  "user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d8",
  "entity_id": "ent_65f1a2b3c4d5e6f7a8b9c0d2",
  "ttl": 43200,
  "scope": "pos_operator",
  "created_at": "2026-07-31T20:25:00.000Z"
}

List point-of-sale tables

GET/pos/tables

List point-of-sale tables

Header parameters

entity_idstringoptional

Entity ID on which the request is made. Auto-selected when only one entity exists, required when multiple entities exist.

Query parameters

include_inactivebooleanoptional

Include deactivated tables.

import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';

const sdk = new SpaceInvoices('YOUR_API_KEY');

const response = await sdk.pointOfSale.listTables();

console.log(response);

Returns

dataarray of objects
json
{
  "data": [
    {
      "id": "ptbl_65f1a2b3c4d5e6f7a8b9c0d1",
      "entity_id": "ent_65f1a2b3c4d5e6f7a8b9c0d2",
      "label": "1",
      "sort_order": 1,
      "is_active": true,
      "metadata": {},
      "deleted_at": null,
      "created_at": "2026-07-31T18:00:00.000Z",
      "updated_at": "2026-07-31T18:00:00.000Z"
    },
    {
      "id": "ptbl_65f1a2b3c4d5e6f7a8b9c0e1",
      "entity_id": "ent_65f1a2b3c4d5e6f7a8b9c0d2",
      "label": "2",
      "sort_order": 2,
      "is_active": true,
      "metadata": {},
      "deleted_at": null,
      "created_at": "2026-07-31T18:00:00.000Z",
      "updated_at": "2026-07-31T18:00:00.000Z"
    },
    {
      "id": "ptbl_65f1a2b3c4d5e6f7a8b9c0e2",
      "entity_id": "ent_65f1a2b3c4d5e6f7a8b9c0d2",
      "label": "Terrace 1",
      "sort_order": 3,
      "is_active": true,
      "metadata": {},
      "deleted_at": null,
      "created_at": "2026-07-31T18:00:00.000Z",
      "updated_at": "2026-07-31T18:00:00.000Z"
    }
  ]
}

List point-of-sale tabs

GET/pos/tabs

Returns the full set of tabs in the requested statuses. Send the previous ETag back as If-None-Match to get a 304 when nothing changed — this is the intended polling path for keeping devices in a venue in sync.

Header parameters

entity_idstringoptional

Entity ID on which the request is made. Auto-selected when only one entity exists, required when multiple entities exist.

if-none-matchstringoptional

ETag from a previous response. Returns 304 when the tab set is unchanged.

Query parameters

statusstringoptional

Comma-separated statuses to include. Defaults to open and issuing.

import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';

const sdk = new SpaceInvoices('YOUR_API_KEY');

const response = await sdk.pointOfSale.listTabs();

console.log(response);

Returns

dataarray of objects
json
{
  "data": [
    {
      "id": "ptab_65f1a2b3c4d5e6f7a8b9c0d5",
      "entity_id": "ent_65f1a2b3c4d5e6f7a8b9c0d2",
      "table_id": "ptbl_65f1a2b3c4d5e6f7a8b9c0d1",
      "status": "open",
      "items": [
        {
          "line_id": "line_7f3a",
          "item_id": "item_65f1a2b3c4d5e6f7a8b9c0d3",
          "name": "Glass of red wine",
          "quantity": 2,
          "unit_gross_price": 5.5,
          "discount_percent": null,
          "tax_rates": null,
          "note": null,
          "added_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
          "added_at": "2026-07-31T20:12:00.000Z"
        }
      ],
      "note": null,
      "customer_id": null,
      "opened_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
      "updated_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
      "claimed_by_device": null,
      "claimed_at": null,
      "invoice_id": null,
      "version": 3,
      "opened_at": "2026-07-31T20:05:00.000Z",
      "issued_at": null,
      "metadata": {},
      "deleted_at": null,
      "created_at": "2026-07-31T20:05:00.000Z",
      "updated_at": "2026-07-31T20:12:00.000Z"
    }
  ]
}

Daily takings

GET/pos/reports/daily

What the venue took on one day, split by payment type, tax rate, item category and operator.

This is a business report, not a fiscal one: Slovenia and Croatia confirm every cash invoice with the authority as it is issued, so there is no daily close to file and nothing here is submitted anywhere. Voided documents are counted separately and excluded from the totals. Operator attribution comes from the fiscal record, which is where the acting operator is stored.

Header parameters

entity_idstringoptional

Entity ID on which the request is made. Auto-selected when only one entity exists, required when multiple entities exist.

Query parameters

datestringrequired

The day to report on, by document date.

import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';

const sdk = new SpaceInvoices('YOUR_API_KEY');

const response = await sdk.pointOfSale.dailyReport({
  date: "2026-08-15"
});

console.log(response);

Returns

datestring
currency_codestringnullable
totalsobject
by_payment_typearray of objects
by_tax_ratearray of objects
by_categoryarray of objects
by_operatorarray of objects
json
{
  "date": "2026-08-15",
  "currency_code": "EUR",
  "totals": {
    "invoices": 42,
    "voided": 1,
    "net": 1011.89,
    "tax": 222.61,
    "gross": 1234.5
  },
  "by_payment_type": [
    {
      "type": "cash",
      "invoices": 30,
      "total": 800
    },
    {
      "type": "card",
      "invoices": 12,
      "total": 434.5
    }
  ],
  "by_tax_rate": [
    {
      "rate": 22,
      "base": 1011.89,
      "amount": 222.61
    }
  ],
  "by_category": [
    {
      "category": "wine",
      "quantity": 61,
      "total": 700
    },
    {
      "category": "food",
      "quantity": 24,
      "total": 534.5
    }
  ],
  "by_operator": [
    {
      "operator": "Ana",
      "invoices": 42,
      "total": 1234.5
    }
  ]
}

List staff who can operate this point of sale

GET/pos/operators

List staff who can operate this point of sale

Header parameters

entity_idstringoptional

Entity ID on which the request is made. Auto-selected when only one entity exists, required when multiple entities exist.

import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';

const sdk = new SpaceInvoices('YOUR_API_KEY');

const response = await sdk.pointOfSale.listOperators();

console.log(response);

Returns

dataarray of objects
json
{
  "data": [
    {
      "user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
      "name": "Ana",
      "email": "ana@winebar.example",
      "role": "admin",
      "has_pin": true
    },
    {
      "user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d8",
      "name": "Luka",
      "email": "luka@winebar.example",
      "role": "editor",
      "has_pin": false
    }
  ]
}

Get a tab

GET/pos/tabs/{id}

Get a tab

Header parameters

entity_idstringoptional

Entity ID on which the request is made. Auto-selected when only one entity exists, required when multiple entities exist.

Path parameters

idstring<resource-id>required

Unique resource identifier

import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';

const sdk = new SpaceInvoices('YOUR_API_KEY');

const response = await sdk.pointOfSale.getTab("inv_6595a27b5d35015c3ef0c3fd");

console.log(response);

Returns

idstring
Other parameters
entity_idstring
table_idstringnullable
statusstring
itemsarray of objects
notestringnullable
customer_idstringnullable
opened_by_user_idstringnullable
updated_by_user_idstringnullable
claimed_by_devicestringnullable
claimed_atstring<date-time>nullable
invoice_idstringnullable
versioninteger
opened_atstring<date-time>
issued_atstring<date-time>nullable
metadatastringnullable
deleted_atstring<date-time>nullable
created_atstring<date-time>
updated_atstring<date-time>
json
{
  "id": "ptab_65f1a2b3c4d5e6f7a8b9c0d5",
  "entity_id": "ent_65f1a2b3c4d5e6f7a8b9c0d2",
  "table_id": "ptbl_65f1a2b3c4d5e6f7a8b9c0d1",
  "status": "open",
  "items": [
    {
      "line_id": "line_7f3a",
      "item_id": "item_65f1a2b3c4d5e6f7a8b9c0d3",
      "name": "Glass of red wine",
      "quantity": 2,
      "unit_gross_price": 5.5,
      "discount_percent": null,
      "tax_rates": null,
      "note": null,
      "added_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
      "added_at": "2026-07-31T20:12:00.000Z"
    }
  ],
  "note": null,
  "customer_id": null,
  "opened_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
  "updated_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
  "claimed_by_device": null,
  "claimed_at": null,
  "invoice_id": null,
  "version": 3,
  "opened_at": "2026-07-31T20:05:00.000Z",
  "issued_at": null,
  "metadata": {},
  "deleted_at": null,
  "created_at": "2026-07-31T20:05:00.000Z",
  "updated_at": "2026-07-31T20:12:00.000Z"
}

Update a point-of-sale table

PATCH/pos/tables/{id}

Update a point-of-sale table

Header parameters

entity_idstringoptional

Entity ID on which the request is made. Auto-selected when only one entity exists, required when multiple entities exist.

Path parameters

idstring<resource-id>required

Unique resource identifier

Body parameters

labelstringoptionalnullable
sort_orderintegeroptionalnullable
is_activebooleanoptionalnullable
metadataobjectoptionalnullable
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';

const sdk = new SpaceInvoices('YOUR_API_KEY');

const response = await sdk.pointOfSale.updateTable("inv_6595a27b5d35015c3ef0c3fd", {
  label: "Terrace 1",
  sort_order: 7
});

console.log(response);

Returns

idstring
Other parameters
entity_idstring
labelstring
sort_orderinteger
is_activeboolean
metadatastringnullable
deleted_atstring<date-time>nullable
created_atstring<date-time>
updated_atstring<date-time>
json
{
  "id": "ptbl_65f1a2b3c4d5e6f7a8b9c0d1",
  "entity_id": "ent_65f1a2b3c4d5e6f7a8b9c0d2",
  "label": "Terrace 1",
  "sort_order": 7,
  "is_active": true,
  "metadata": {},
  "deleted_at": null,
  "created_at": "2026-07-31T18:00:00.000Z",
  "updated_at": "2026-07-31T18:00:00.000Z"
}

Replace a tab's contents

PATCH/pos/tabs/{id}

Replacing write for edits and removals, guarded by expected_version. A 409 means another device changed the tab first and carries the current tab.

Header parameters

entity_idstringoptional

Entity ID on which the request is made. Auto-selected when only one entity exists, required when multiple entities exist.

Path parameters

idstring<resource-id>required

Unique resource identifier

Body parameters

expected_versionintegerrequired

Version the client last saw. The request is rejected with 409 if the tab changed since, and the response carries the current tab.

Other parameters
itemsarray of objectsoptionalnullable
notestringoptionalnullable
customer_idstringoptionalnullable
table_idstringoptionalnullable
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';

const sdk = new SpaceInvoices('YOUR_API_KEY');

const response = await sdk.pointOfSale.updateTab("inv_6595a27b5d35015c3ef0c3fd", {
  items: [
    {
      line_id: "line_7f3a",
      item_id: "item_65f1a2b3c4d5e6f7a8b9c0d3",
      name: "Glass of red wine",
      quantity: 2,
      unit_gross_price: 5.5,
      discount_percent: null,
      tax_rates: null,
      note: null,
      added_by_user_id: "usr_65f1a2b3c4d5e6f7a8b9c0d4",
      added_at: "2026-07-31T20:12:00.000Z"
    }
  ],
  expected_version: 3
});

console.log(response);

Returns

idstring
Other parameters
entity_idstring
table_idstringnullable
statusstring
itemsarray of objects
notestringnullable
customer_idstringnullable
opened_by_user_idstringnullable
updated_by_user_idstringnullable
claimed_by_devicestringnullable
claimed_atstring<date-time>nullable
invoice_idstringnullable
versioninteger
opened_atstring<date-time>
issued_atstring<date-time>nullable
metadatastringnullable
deleted_atstring<date-time>nullable
created_atstring<date-time>
updated_atstring<date-time>
json
{
  "id": "ptab_65f1a2b3c4d5e6f7a8b9c0d5",
  "entity_id": "ent_65f1a2b3c4d5e6f7a8b9c0d2",
  "table_id": "ptbl_65f1a2b3c4d5e6f7a8b9c0d1",
  "status": "open",
  "items": [
    {
      "line_id": "line_7f3a",
      "item_id": "item_65f1a2b3c4d5e6f7a8b9c0d3",
      "name": "Glass of red wine",
      "quantity": 2,
      "unit_gross_price": 5.5,
      "discount_percent": null,
      "tax_rates": null,
      "note": null,
      "added_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
      "added_at": "2026-07-31T20:12:00.000Z"
    }
  ],
  "note": null,
  "customer_id": null,
  "opened_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
  "updated_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
  "claimed_by_device": null,
  "claimed_at": null,
  "invoice_id": null,
  "version": 4,
  "opened_at": "2026-07-31T20:05:00.000Z",
  "issued_at": null,
  "metadata": {},
  "deleted_at": null,
  "created_at": "2026-07-31T20:05:00.000Z",
  "updated_at": "2026-07-31T20:12:00.000Z"
}

Set an operator PIN

PUT/pos/operators/{user_id}/pin

Sets the PIN used to switch to this member on a shared device. Callers may set their own PIN; entity admins may set anyone's. The PIN identifies who is acting, it does not grant access: the device must already hold a valid session for the same entity. Exactly three digits, so a till can act on the last one without a confirm step.

Header parameters

entity_idstringoptional

Entity ID on which the request is made. Auto-selected when only one entity exists, required when multiple entities exist.

Path parameters

user_idstringrequired

Body parameters

pinstringrequired

Exactly three digits.

import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';

const sdk = new SpaceInvoices('YOUR_API_KEY');

const response = await sdk.pointOfSale.setOperatorPin('USER_ID', {
  pin: "482"
});

console.log(response);

Delete a point-of-sale table

DELETE/pos/tables/{id}

Delete a point-of-sale table

Header parameters

entity_idstringoptional

Entity ID on which the request is made. Auto-selected when only one entity exists, required when multiple entities exist.

Path parameters

idstring<resource-id>required

Unique resource identifier

import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';

const sdk = new SpaceInvoices('YOUR_API_KEY');

await sdk.pointOfSale.deleteTable("inv_6595a27b5d35015c3ef0c3fd");

console.log('Deleted successfully');

Cancel a tab

DELETE/pos/tabs/{id}

Send expected_version when cancelling because the tab looked empty: a poll-based view can be seconds stale, and without the guard a round another device just added would be discarded. Omit it to cancel regardless, which is what an operator picking "Cancel tab" means.

Header parameters

entity_idstringoptional

Entity ID on which the request is made. Auto-selected when only one entity exists, required when multiple entities exist.

Path parameters

idstring<resource-id>required

Unique resource identifier

Query parameters

expected_versionintegeroptionalnullable

Refuse with 409 unless the tab is still at this version.


Remove an operator PIN

DELETE/pos/operators/{user_id}/pin

Remove an operator PIN

Header parameters

entity_idstringoptional

Entity ID on which the request is made. Auto-selected when only one entity exists, required when multiple entities exist.

Path parameters

user_idstringrequired
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';

const sdk = new SpaceInvoices('YOUR_API_KEY');

await sdk.pointOfSale.clearOperatorPin('USER_ID');

console.log('Deleted successfully');

Add items to a tab

POST/pos/tabs/{id}/items

Appends to an open tab are additive: concurrent additions serialize and merge quantities on matching lines. New appends return 409 already_claimed while a payment claim is active. Retrying a previously accepted append_id returns the current tab without adding the items again.

Header parameters

entity_idstringoptional

Entity ID on which the request is made. Auto-selected when only one entity exists, required when multiple entities exist.

Path parameters

idstring<resource-id>required

Unique resource identifier

Body parameters

itemsarray of objectsrequired
Other parameters
append_idstringoptionalnullable
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';

const sdk = new SpaceInvoices('YOUR_API_KEY');

const response = await sdk.pointOfSale.appendTabItems("inv_6595a27b5d35015c3ef0c3fd", {
  items: [
    {
      line_id: "line_7f3a",
      item_id: "item_65f1a2b3c4d5e6f7a8b9c0d3",
      name: "Glass of red wine",
      quantity: 2,
      unit_gross_price: 5.5,
      discount_percent: null,
      tax_rates: null,
      note: null,
      added_by_user_id: "usr_65f1a2b3c4d5e6f7a8b9c0d4",
      added_at: "2026-07-31T20:12:00.000Z"
    }
  ]
});

console.log(response);

Returns

idstring
Other parameters
entity_idstring
table_idstringnullable
statusstring
itemsarray of objects
notestringnullable
customer_idstringnullable
opened_by_user_idstringnullable
updated_by_user_idstringnullable
claimed_by_devicestringnullable
claimed_atstring<date-time>nullable
invoice_idstringnullable
versioninteger
opened_atstring<date-time>
issued_atstring<date-time>nullable
metadatastringnullable
deleted_atstring<date-time>nullable
created_atstring<date-time>
updated_atstring<date-time>
json
{
  "id": "ptab_65f1a2b3c4d5e6f7a8b9c0d5",
  "entity_id": "ent_65f1a2b3c4d5e6f7a8b9c0d2",
  "table_id": "ptbl_65f1a2b3c4d5e6f7a8b9c0d1",
  "status": "open",
  "items": [
    {
      "line_id": "line_7f3a",
      "item_id": "item_65f1a2b3c4d5e6f7a8b9c0d3",
      "name": "Glass of red wine",
      "quantity": 4,
      "unit_gross_price": 5.5,
      "discount_percent": null,
      "tax_rates": null,
      "note": null,
      "added_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
      "added_at": "2026-07-31T20:12:00.000Z"
    }
  ],
  "note": null,
  "customer_id": null,
  "opened_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
  "updated_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
  "claimed_by_device": null,
  "claimed_at": null,
  "invoice_id": null,
  "version": 4,
  "opened_at": "2026-07-31T20:05:00.000Z",
  "issued_at": null,
  "metadata": {},
  "deleted_at": null,
  "created_at": "2026-07-31T20:05:00.000Z",
  "updated_at": "2026-07-31T20:12:00.000Z"
}

Reserve a tab for payment

POST/pos/tabs/{id}/claim

Marks the tab as being paid on one device so a second device cannot issue it at the same time, which would produce a duplicate invoice and a duplicate fiscal record. Claims expire after five minutes so a crashed device cannot lock a table.

Header parameters

entity_idstringoptional

Entity ID on which the request is made. Auto-selected when only one entity exists, required when multiple entities exist.

Path parameters

idstring<resource-id>required

Unique resource identifier

Body parameters

device_idstringrequired

Stable per-device identifier, so the claiming device can recognise its own claim after a restart.

import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';

const sdk = new SpaceInvoices('YOUR_API_KEY');

const response = await sdk.pointOfSale.claimTab("inv_6595a27b5d35015c3ef0c3fd", {
  device_id: "9C2E5F10-7A44-4E0B-9D2C-1B8E3A6F0C41"
});

console.log(response);

Returns

idstring
Other parameters
entity_idstring
table_idstringnullable
statusstring
itemsarray of objects
notestringnullable
customer_idstringnullable
opened_by_user_idstringnullable
updated_by_user_idstringnullable
claimed_by_devicestringnullable
claimed_atstring<date-time>nullable
invoice_idstringnullable
versioninteger
opened_atstring<date-time>
issued_atstring<date-time>nullable
metadatastringnullable
deleted_atstring<date-time>nullable
created_atstring<date-time>
updated_atstring<date-time>
json
{
  "id": "ptab_65f1a2b3c4d5e6f7a8b9c0d5",
  "entity_id": "ent_65f1a2b3c4d5e6f7a8b9c0d2",
  "table_id": "ptbl_65f1a2b3c4d5e6f7a8b9c0d1",
  "status": "issuing",
  "items": [
    {
      "line_id": "line_7f3a",
      "item_id": "item_65f1a2b3c4d5e6f7a8b9c0d3",
      "name": "Glass of red wine",
      "quantity": 2,
      "unit_gross_price": 5.5,
      "discount_percent": null,
      "tax_rates": null,
      "note": null,
      "added_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
      "added_at": "2026-07-31T20:12:00.000Z"
    }
  ],
  "note": null,
  "customer_id": null,
  "opened_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
  "updated_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
  "claimed_by_device": "9C2E5F10-7A44-4E0B-9D2C-1B8E3A6F0C41",
  "claimed_at": "2026-07-31T20:20:00.000Z",
  "invoice_id": null,
  "version": 4,
  "opened_at": "2026-07-31T20:05:00.000Z",
  "issued_at": null,
  "metadata": {},
  "deleted_at": null,
  "created_at": "2026-07-31T20:05:00.000Z",
  "updated_at": "2026-07-31T20:12:00.000Z"
}

Release a payment claim

POST/pos/tabs/{id}/release

Hands a claimed tab back. Only the device holding the claim may release it — otherwise the claim would be decorative, since any device could free a tab another is paying and take it over. An expired claim may be cleared by anyone.

Header parameters

entity_idstringoptional

Entity ID on which the request is made. Auto-selected when only one entity exists, required when multiple entities exist.

Path parameters

idstring<resource-id>required

Unique resource identifier

Body parameters

device_idstringrequired

The device releasing the claim. Must match the device holding it unless the claim has expired.

import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';

const sdk = new SpaceInvoices('YOUR_API_KEY');

const response = await sdk.pointOfSale.releaseTab("inv_6595a27b5d35015c3ef0c3fd", {
  device_id: "9C2E5F10-7A44-4E0B-9D2C-1B8E3A6F0C41"
});

console.log(response);

Returns

idstring
Other parameters
entity_idstring
table_idstringnullable
statusstring
itemsarray of objects
notestringnullable
customer_idstringnullable
opened_by_user_idstringnullable
updated_by_user_idstringnullable
claimed_by_devicestringnullable
claimed_atstring<date-time>nullable
invoice_idstringnullable
versioninteger
opened_atstring<date-time>
issued_atstring<date-time>nullable
metadatastringnullable
deleted_atstring<date-time>nullable
created_atstring<date-time>
updated_atstring<date-time>
json
{
  "id": "ptab_65f1a2b3c4d5e6f7a8b9c0d5",
  "entity_id": "ent_65f1a2b3c4d5e6f7a8b9c0d2",
  "table_id": "ptbl_65f1a2b3c4d5e6f7a8b9c0d1",
  "status": "open",
  "items": [
    {
      "line_id": "line_7f3a",
      "item_id": "item_65f1a2b3c4d5e6f7a8b9c0d3",
      "name": "Glass of red wine",
      "quantity": 2,
      "unit_gross_price": 5.5,
      "discount_percent": null,
      "tax_rates": null,
      "note": null,
      "added_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
      "added_at": "2026-07-31T20:12:00.000Z"
    }
  ],
  "note": null,
  "customer_id": null,
  "opened_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
  "updated_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
  "claimed_by_device": null,
  "claimed_at": null,
  "invoice_id": null,
  "version": 5,
  "opened_at": "2026-07-31T20:05:00.000Z",
  "issued_at": null,
  "metadata": {},
  "deleted_at": null,
  "created_at": "2026-07-31T20:05:00.000Z",
  "updated_at": "2026-07-31T20:12:00.000Z"
}

Close a tab against an issued invoice

POST/pos/tabs/{id}/close

Idempotent: re-closing a tab with the same invoice returns it unchanged. This is what makes a lost response after a successful issue recoverable rather than stranding the table.

Header parameters

entity_idstringoptional

Entity ID on which the request is made. Auto-selected when only one entity exists, required when multiple entities exist.

Path parameters

idstring<resource-id>required

Unique resource identifier

Body parameters

invoice_idstringrequired

Invoice the tab was issued as.

Other parameters
expected_versionintegeroptionalnullable
device_idstringoptionalnullable
priced_atstring<date-time>optionalnullable
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';

const sdk = new SpaceInvoices('YOUR_API_KEY');

const response = await sdk.pointOfSale.closeTab("inv_6595a27b5d35015c3ef0c3fd", {
  invoice_id: "inv_65f1a2b3c4d5e6f7a8b9c0d9"
});

console.log(response);

Returns

idstring
Other parameters
entity_idstring
table_idstringnullable
statusstring
itemsarray of objects
notestringnullable
customer_idstringnullable
opened_by_user_idstringnullable
updated_by_user_idstringnullable
claimed_by_devicestringnullable
claimed_atstring<date-time>nullable
invoice_idstringnullable
versioninteger
opened_atstring<date-time>
issued_atstring<date-time>nullable
metadatastringnullable
deleted_atstring<date-time>nullable
created_atstring<date-time>
updated_atstring<date-time>
json
{
  "id": "ptab_65f1a2b3c4d5e6f7a8b9c0d5",
  "entity_id": "ent_65f1a2b3c4d5e6f7a8b9c0d2",
  "table_id": "ptbl_65f1a2b3c4d5e6f7a8b9c0d1",
  "status": "issued",
  "items": [
    {
      "line_id": "line_7f3a",
      "item_id": "item_65f1a2b3c4d5e6f7a8b9c0d3",
      "name": "Glass of red wine",
      "quantity": 2,
      "unit_gross_price": 5.5,
      "discount_percent": null,
      "tax_rates": null,
      "note": null,
      "added_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
      "added_at": "2026-07-31T20:12:00.000Z"
    }
  ],
  "note": null,
  "customer_id": null,
  "opened_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
  "updated_by_user_id": "usr_65f1a2b3c4d5e6f7a8b9c0d4",
  "claimed_by_device": null,
  "claimed_at": null,
  "invoice_id": "inv_65f1a2b3c4d5e6f7a8b9c0d9",
  "version": 5,
  "opened_at": "2026-07-31T20:05:00.000Z",
  "issued_at": "2026-07-31T20:22:00.000Z",
  "metadata": {},
  "deleted_at": null,
  "created_at": "2026-07-31T20:05:00.000Z",
  "updated_at": "2026-07-31T20:12:00.000Z"
}