Skip to content

Trigger a key-card read on a registered terminal

POST
/v1/key-charge/tap
curl --request POST \
--url https://api.aerandil.com/v1/key-charge/tap \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "device_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0" }'

The name-echo half of tap-to-charge: triggers an NFC read on a registered Adyen terminal and resolves the tapped card to its in-house stay, so staff can confirm the guest out loud before anything is posted. This route is the resolve_access_credential function invocation with a hardware pre-step, and carries that function’s scope; the posting that follows the confirmation goes through the ordinary post_charge_by_credential action route, not this one. Resolution fails closed with a single generic error for unknown, revoked, expired and checked-out credentials alike — a probing caller learns nothing from which one it was. 501 unless AERANDIL_ADYEN_ENABLED=1.

Media typeapplication/json
object
device_id
required

The registered hospitality.device to trigger. Must be active and carry the Adyen POIID in vendor_device_ref.

string format: uuid
Examplegenerated
{
"device_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0"
}

The card was read and resolved to a stay.

Media typeapplication/json
object
data
required
object
credential
required
object
credential_id
required
string format: uuid
daily_cap
object
amount
required
string format: decimal
currency
required
string format: iso-4217
expires_at
string format: date-time
folio_id
required
string format: uuid
guest_name
string
kind
required
string
Allowed values: key_card wristband mobile_key other
per_charge_cap
object
amount
required
string format: decimal
currency
required
string format: iso-4217
room_number
string
stay_id
required
string format: uuid
token_hint
string
nfc_variant

The terminal’s reading of which card technology answered, when it reports one.

string | null
token
required

The opaque vendor token read at tap time. Not the card’s UID in the clear.

string
Example
{
"data": {
"credential": {
"kind": "key_card"
}
}
}
Cache-Control
string

Always no-store. Object and link state is live data and is never cacheable.

The bearer authenticated but does not hold the scope this operation requires.

Media typeapplication/json

Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.

object
error
required
object
code
required

Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).

string
instance_id

Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.

string
message
required

Human-readable explanation of the failure.

string
parameters

Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).

Examplegenerated
{
"error": {
"code": "example",
"instance_id": "example",
"message": "example",
"parameters": "example"
}
}

terminal_busy — the terminal is taking something else (a payment) or is not logged in; nothing was read and the terminal was left alone.

Media typeapplication/json

Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.

object
error
required
object
code
required

Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).

string
instance_id

Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.

string
message
required

Human-readable explanation of the failure.

string
parameters

Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).

Examplegenerated
{
"error": {
"code": "example",
"instance_id": "example",
"message": "example",
"parameters": "example"
}
}

The device is not a payment terminal, not active, or carries no Adyen POIID, the read failed, or the tap resolved to nothing usable. One generic refusal by design.

Media typeapplication/json

Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.

object
error
required
object
code
required

Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).

string
instance_id

Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.

string
message
required

Human-readable explanation of the failure.

string
parameters

Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).

Examplegenerated
{
"error": {
"code": "example",
"instance_id": "example",
"message": "example",
"parameters": "example"
}
}

The Adyen bridge is not enabled on this deployment.

Media typeapplication/json

Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.

object
error
required
object
code
required

Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).

string
instance_id

Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.

string
message
required

Human-readable explanation of the failure.

string
parameters

Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).

Examplegenerated
{
"error": {
"code": "example",
"instance_id": "example",
"message": "example",
"parameters": "example"
}
}