Changelog
Welcome to the Changelog, your go-to resource for staying informed about the latest updates and improvements to our APIs.
TBD, 2026 - New Feature
Pay at Table: /poslink/v1/tabs endpoints
Added a new set of endpoints under /poslink/v1/tabs that let ePOS applications register tables (or open orders) with PosLink, list and inspect them, respond to terminal-initiated bill and payment requests, and close them once payment is complete.
Key endpoints (ePOS-facing):
POST /poslink/v1/tabs: open a tab. Body:{ "tab_id", "tab_name", "currency" }.tab_idis an ePOS-chosen identifier;tab_nameis the display label (e.g."Patio 3") shown on the terminal's open-tabs screen;currencyis the ISO 4217 code all payments on the tab must use.GET /poslink/v1/tabs: paginated list of tabs. Query:statuses=OPEN,PAYING,PAUSED,COMPLETED,CLOSED(defaults to active statuses),after/before(opaque cursors),limit.GET /poslink/v1/tabs/{tab_id}: full tab detail including line items, payment requests, and the bill file id.DELETE /poslink/v1/tabs/{tab_id}: close a tab. PosLink also auto-closes tabs that have had no activity for 24 hours.
Terminal-initiated event stream (Server-Sent Events):
GET /poslink/v1/tabs/events: SSE stream for the linked store. Notifies the ePOS ofSHOW_BILL_REQUEST,PAY_REQUEST,TAB_PAYMENT_STATUS_PROGRESS,TAB_PAYMENT_COMPLETED,TAB_PAUSED,TAB_RESUMED,TAB_COMPLETED,TAB_BILL_HIDDEN, and connection state changes triggered by terminals against any open tab.
ePOS response endpoints (in reply to events):
POST /poslink/v1/tabs/{tab_id}/bill: respond to aSHOW_BILL_REQUESTevent with the bill total, plus an optionalprint_modelortab_item_data(application/json), or a pre-rendered bill image (multipart/form-data, maximum 200 KB per image and 220 KB per request; exceeding either returns413PAYLOAD_TOO_LARGEwith codeBILL_IMAGE_TOO_LARGE).POST /poslink/v1/tabs/{tab_id}/errors: reject a terminal-initiated request with an error code.
Pay-at-Table response on existing payment endpoint:
POST /poslink/v3/payment-requestsnow acceptstab_id,payment_type(FULLorSPLIT) andpayment_method(CARDorCASH) in the request body. Send them to settle a tab, fully or partially, in response to aPAY_REQUESTevent; leave them out for regular payments.payment_typeis required whenevertab_idis present. The payment is tagged against the tab and surfaces underGET /poslink/v1/tabs/{tab_id}as aPaymentRequestSummary.
Store-level enablement:
PUT /poslink/v1/stores/{store_id}/configs/PAT_ENABLEDaccepts{ "value": "true" }to toggle PAT for the store. Store-wide capability flag; per-terminal opt-out is local to each terminal. Disabling is an entry-point gate only; in-progress sessions run to completion.
Action Required
No action required for existing integrations. Pay at Table is opt-in: partners that don't call the tab endpoints see no change.
For partners adopting PAT:
- Enable PAT at the store level via
PUT /poslink/v1/stores/{store_id}/configs/PAT_ENABLED. - Open a tab when a table is seated or an order is opened (
POST /poslink/v1/tabs). - Subscribe to
/poslink/v1/tabs/eventsto receive terminal-initiated bill and payment requests. - Respond to
SHOW_BILL_REQUESTevents with the bill, and toPAY_REQUESTevents by creating a payment withtab_idandpayment_type. - Close the tab when fully paid (
DELETE /poslink/v1/tabs/{tab_id}).
See the Pay at Table integration guide (Android) for the end-to-end flow and code samples. iOS and Windows guides ship alongside their respective SDK releases.
Nov 11, 2026 - Enhancement
More error responses documented
The reference now documents these error responses, with example bodies:
POST /poslink/v3/payment-requests,409:IDEMPOTENCY_KEY_REUSEDwhen theIdempotency-Keywas already used with a different body, andLOCAL_PAYMENT_REQUEST_MISMATCHwhenlocal_payment_request_idor theIdempotency-Keybelongs to another payment.POST /poslink/v3/payment-requests,422:INVALID_TAB_REQUESTwhen the request is not valid for a tab, for exampletransaction_typeREFUNDsent with atab_id, with the rejected field ininvalid_params; andLOCAL_PAYMENT_REQUEST_INVALIDwhenlocal_payment_request_idis sent for a refund or a payment on a tab.POST /poslink/v1/epos/register,409:STORE_CREDENTIALS_REMOVEDwhen the partner's credentials for the store have been removed.- The
/poslink/v1/tabs/{tab_id}endpoints,404:TAB_NOT_FOUNDwhen no tab exists for the giventab_id.
The Errors section of the reference also lists every error code documented for each status, with its example.
Action Required
None.
Nov 10, 2026 - Bug Fix
V2 Refunds: No 202 Response
The API reference listed a 202 "Refund is being processed asynchronously" response for POST /poslink/v2/refunds. This endpoint never returns 202. It has been removed from the reference.
A refund can still come back without a final result:
201withstatusPENDING400with codeUNKNOWN, which can mean a refund with the sameIdempotency-Keyis still being processed
There is no endpoint to fetch a refund later. In both cases, repeat the same request with the same Idempotency-Key and body. The repeated request returns the stored refund instead of creating a new one.
Action Required
Always send an Idempotency-Key on POST /poslink/v2/refunds, and handle PENDING and 400 UNKNOWN by repeating the request with the same key. Without a key, every request creates a new refund.
No API behaviour changed. This entry corrects the documentation only.
See Refunds in the API reference and Make a refund.
Nov 9, 2026 - New Feature
Terminal Names: GET /poslink/v2/stores/{store_id}/terminals
Added a new version of the terminal listing that returns each terminal's actual name, and its device model in a separate field.
What changes from V1:
terminal_namenow returns the name of the terminal, which can contain emojis. In V1 this field returns the device model.device_modelis a new field that returns the device model, for examplePAX_A77.
Action Required
No action required for existing integrations: GET /poslink/v1/stores/{store_id}/terminals does not change. To show terminal names, move to V2. If you read the device model from terminal_name, read device_model instead.
Sep 3, 2026 - Bug Fix
V2 Refunds: Which Identifier Goes in transaction_id
The May 21, 2026 deprecation notice below was misleading about POST /poslink/v2/refunds. It read as though V2 takes a different identifier from V1. It does not.
The request field is named transaction_id, but the value it expects is the gateway_payment_id of the original payment, the same identifier V1 refunds took. The field name and the identifier name simply differ.
Send the gateway_payment_id of the original payment, delivered when that payment completes on its status stream (GET /poslink/v3/payment-requests/{payment-request-id}):
{
"transaction_id": "39e3bacdd5d38d9ce611cf88afbcc86df829a9a5641880b3",
"amount": 1500
}
Do not send the deprecated transaction_id from the V1 payment request response. Despite the matching field name it is a different identifier and the refund will fail with 404 TRANSACTION_NOT_FOUND.
Action Required
None if your refunds are working today. If you see 404 TRANSACTION_NOT_FOUND, check you are sending the gateway_payment_id of the original payment.
No API behaviour changed. This entry corrects the documentation only.
See Refunds in the API reference and Make a refund.
Aug 17, 2026 - New Feature
Receipt Text Endpoint
Added GET /poslink/v3/payment-requests/{payment-request-id}/receipt-text, which returns a JSON response with a receipt_text field containing the plain-text receipt for a SUCCESSFUL payment request or refund.
What the receipt includes:
- Store name and address
- UTC transaction date/time
- Amount, tip, and total
- Card details, AID, MID, TID, approval code, response code, entry mode, verification method, card type, and card issuing country
- DCC details, where applicable
- Receipt references (gateway reference and merchant reference)
Optional fields are omitted when absent, so no blank labels are printed.
Required scopes (one of the following):
payment_requests/iddefault_access(deprecated; included for backward compatibility with existing integrations)
Action Required
No action required for existing integrations. The endpoint is additive and opt-in: call it after a payment request reaches SUCCESSFUL if you want a ready-to-print text receipt instead of composing one from the payment metadata yourself.
Jul 22, 2026 - Enhancement
V3 Payment Request Stream
GET /poslink/v3/payment-requests/{payment-request-id} supersedes the V2 endpoint for Transaction Updates over Server-Sent Events. Unlike V2, it also streams refunds and returns the raw status_reason rather than collapsing unrecognised reasons to EXPIRED.
New status_reason values on V3 (all reported as EXPIRED on V2):
TERMINAL_UNREACHABLE: the terminal could not be reached to deliver the push notificationNOTIFICATION_EXPIRED: the push notification expired before the terminal received itSUPERSEDED_BY_NEW_TRANSACTION: a newer payment request was started on the same terminalTRANSACTION_ALREADY_IN_PROGRESS: the terminal is already processing a transactionUNSUPPORTED_CURRENCY: the terminal does not support the requested currencyFEATURE_NOT_ACTIVATED_UNREFERENCED_REFUNDS: unreferenced refunds are not activated for the terminal
Action Required
- Move Transaction Update subscriptions from
GET /poslink/v2/payment-requests/{payment-request-id}to V3. - Handle the
status_reasonvalues above, and keep tolerating unrecognised values, more may be added over time.
Cancelling a payment request is unaffected and remains on PATCH /poslink/v2/payment-requests/{payment-request-id}.
Jul 22, 2026 - Breaking Change
V1 Payment Requests List and V1 Refunds Removed
GET /poslink/v1/payment-requests and POST /poslink/v1/refunds have been removed.
Action Required
- Move from
GET /poslink/v1/payment-requeststoGET /poslink/v2/payment-requests, which also returns refunds alongside payments and addstypeand date-range filters. - Move from
POST /poslink/v1/refundstoPOST /poslink/v2/refunds, deprecated since May 21, 2026 (see below) and now fully removed.
May 21, 2026 - Deprecation
V1 Refunds Endpoint Deprecated
The V1 refunds endpoint POST /poslink/v1/refunds is now deprecated in favour of the new V2 refunds endpoint (POST /poslink/v2/refunds).
Action Required
Migrate your refund integrations from V1 to V2:
- Switch from
POST /poslink/v1/refundstoPOST /poslink/v2/refunds. - Move the original payment's
gateway_payment_idinto the V2 request field namedtransaction_id. The field name differs from V1, the identifier you send does not. - Update your response handling for the richer V2 payload (
issuer_result,dcc, and theREFUND/REVERSALtransaction types). - Do not send
terminal_idin the request body unless you authenticate with client credentials (M2M). V1 had no such field; V2 added it, and sending it with a user token is rejected with403 FORBIDDENon every attempt. POSLink refunds are referenced online refunds - the terminal is derived from the original payment, so omittingterminal_idloses nothing.
Corrected Sep 3, 2026. Step 2 previously read "Identify the original transaction using transaction_id instead of gateway_payment_id", which wrongly implied V2 takes a different identifier. V2 takes the same gateway_payment_id as V1, in a field named transaction_id. See the Sep 3, 2026 correction above.
May 21, 2026 - New Feature
V2 Refunds Endpoint
Added POST /poslink/v2/refunds for refunding a previously processed transaction. The original payment is identified by its gateway_payment_id, sent in a request field named transaction_id, and the response carries richer settlement data than V1.
Key Features:
- Refund by the original payment's
gateway_payment_id, with optional partial amounts via theamountfield (smallest currency unit) - Optional
Idempotency-Keyheader to safely retry requests without creating duplicate refunds - Response includes the issuer authorisation result (
issuer_result) and Dynamic Currency Conversion details (dcc) when applicable - Supports both
REFUNDandREVERSALtransaction types
See Refunds in the API reference.
Nov 14, 2025 - Added Real-Time Payment Status API with SSE Support
Added new API method GET payment-request V2
, which provides real-time updates of payment status over the Server-Sent Events (SSE) protocol.
June 18, 2025 - Deprecation
Deprecation of source_reference_id in Favor of merchant_reference in POSLink API Responses
Affected APIs
Why This Change?
The source_reference_id is currently used across various internal and external systems inside Teya, which has led to inconsistencies and confusion across services.
To provide a clear, unified reference for merchants and developers, we are consolidating this field under a single standard: merchant_reference
Example Response Before and After
Before (Past Response)
{
"payment_request_id": "xxx",
"source_reference_id": "some_ref_123"
}Action Required
Please update your ePOS integration to:
- Stop using
source_reference_idin your logic and data pipelines. - Start using
merchant_referenceinstead.
June 11, 2025 - Added
Idempotency-Key Header Support
Added support for the Idempotency-Key header for the Create Payment Request endpoint.
Please see section Send a payment request
May 15, 2025 - Changed
Technical Change Description
Effective May 15, 2025, POSLink will improve the metadata experience by changing the source of the data when a transaction is approved. This will ensure metadata becomes available to partners in under 3 seconds, enhancing the responsiveness of the Get a Payment Request API.
As part of this update, the structure of the metadata field in the API response will be slightly adjusted.
API Response Changes
Current API Response
{
"payment_request_id": "bee17dec-01dd-4ee5-a17d-ec01dd2ee5ca",
"requested_amount": {
"currency": "GBP",
"amount": 70,
"tip": 0
},
"status": "SUCCESSFUL",
"transaction_type": "SALE",
"created_at": "2022-06-15T16:24:120Z",
"updated_at": "2022-06-15T16:26:120Z",
"source_reference_id": "423897430",
"transaction_id": "te3c89aa-d84f-4916-b88b-7e6a051765fa",
"gateway_payment_id": "39e3bacdd5d38d9ce611cf88afbcc86df829a9a5641880b3",
"terminal_id": "70dc65ba-1c13-492a-82a0-15821e5f63ba",
"store_id": "f04fe1ce-e7bd-4c5b-b873-b156643c0bc3",
"metadata": {
"payment_method_details": {
"card": {
"last4": "1234",
"issuing_country": "GB",
"brand": "MASTERCARD",
"type": "CREDIT"
},
"entry_mode": "CONTACTLESS",
"verification_method": "OFFLINE_PIN",
"application_id": "A0000000041010",
"mid": "5006544",
"response_code": "00",
"authorisation_code": "A8RLR8"
}
}
}Summary of Changes
issuing_country (UK, HUN, HRV)•
type (CREDIT / DEBIT)bin (e.g. 518637)•
application_name (e.g. Debit MasterCard)Partner Impact
Each partner is encouraged to review and analyse their current integration to assess whether any adjustments are necessary to support the updated metadata structure.
Issuing Country and Card Type
• These fields will be deprecated and return null in the API response
• They will be removed from POSLink on May 31, 2025
• Action Required: Partners should update their integrations to remove any dependency on these deprecated fields.
Card Bin, APN (Application Preferred Name)
• A new field, card bin and application preferred name will be included in the API response.
• This provides the first 6-8 digits of the card number and card application related.
• Action Required: Partners will have to update their ePOS system if they wish to include the new fields (Card Bin & Application Preferred Name).
Merchant Impact
This change is expected to have a positive impact for merchants. For setups where the merchant's system relies on metadata to print receipts, this data will now be available in less than 3 seconds after the transaction is approved. This helps to:
- Reduce delays in receipt printing
- Avoid cancelled or duplicate requests due to missing metadata
No action is required from merchants to benefit from this improvement.
Oct 17, 2024 - Added
Add validation on Store ID and Terminal ID
POSLink is introducing a new validation to ensure that the Terminal ID belongs to the given Store ID in Create a Payment Request. If the Terminal ID provided doesn't belong to the Store ID, POSLink will reject this request with the below response:
HTTP 403 Forbidden
{
"code": "TERMINAL_NOT_REGISTERED_WITH_STORE",
"description": "Terminal is not registered with the store provided in the request"
}
May 7, 2024 - Changed
Major documentation updated
Introduction to the 4 Stages of Integration:
- Stage 1 - Design
- Stage 2 - Develop
- Stage 3 - Test
- Stage 4 - Get Certified
In addition to the above information, the following pages have been added:
- FAQ (Frequently Asked Questions)
- Integration Check List
- Template for Teya Terminal Setup
April 1, 2024 - Changed
URL Updates
URL updated in all documentation from:
Old URLs
https://identity.cloud.saltpay.co/
https://api.cloud.saltpay.co/pos-link/February 14, 2024 - Changed
API Response Updates
- Response of Retrieve a payment request updated to include
mid, in the metadata object, for all successful transactions. - The
statusquery parameter for the Retrieve a list of payment requests is now optional. If you omit the status query parameter, the returned list will include all payment requests.
November 07, 2023
Added
- Added optional query parameters:
start_date_timeandend_date_timeto the Retrieve a list of payment requests endpoint. - Released an updated version of the cancel flow, allowing transactions to be canceled up until a card is presented to the terminal.
Deprecated
- Deprecated version 1 of the cancel flow in favour of version 2.
September 28, 2023
Added
- Transaction Metadata - SUCCESSFUL response of Retrieve a payment request updated to include additional transaction metadata fields. This addition is intended to support various use cases, including consolidated receipt printing.
Changed
- Removed deprecation notice on
gateway_payment_idwhich will replacetransaction_idnow marked for deprecation. (Deprecation date for this change is yet to be confirmed. We are committed to communicating this update well in advance to our valued partners, ensuring a seamless transition).
Impacted endpoints:
- Response of Retrieve a payment request
- Response of Retrieve a list of payment requests
- Request and Response of Create a new refund request
September 04, 2023
Added
- Returning
terminal_idin the following responses:- Response of Retrieve a payment request
- Response of Retrieve a list of payment requests
Changed
- Added
transaction_idas a replacement togateway_payment_idwhich has been marked for deprecation (Deprecation date for this change is yet to be confirmed).
Impacted endpoints:
- Response of Retrieve a payment request
- Response of Retrieve a list of payment requests
- Request and Response of Create a new refund request
Either value may be used interchangeably until deprecation of gateway_payment_id has been finalised.
- Create a payment request response updated to include additional transaction fields
Removed
successfield in Cancel a payment request has been marked for deprecation. This can be inferred fromstatusfield. (Deprecation date for this change is yet to be confirmed).
March 13, 2023 - Initial Release
Initial release
The initial release of POSLink API documentation.