Use loyalty card
curl --request POST \
--url https://tapcoupon.at/api/v1/loyalty-cards \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'X-Device-ID: <x-device-id>' \
--header 'X-Employee-Token: <api-key>' \
--data '
{
"cardId": "9866191586296"
}
'import requests
url = "https://tapcoupon.at/api/v1/loyalty-cards"
payload = { "cardId": "9866191586296" }
headers = {
"X-Device-ID": "<x-device-id>",
"Authorization": "Bearer <token>",
"X-Employee-Token": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Device-ID': '<x-device-id>',
Authorization: 'Bearer <token>',
'X-Employee-Token': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({cardId: '9866191586296'})
};
fetch('https://tapcoupon.at/api/v1/loyalty-cards', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://tapcoupon.at/api/v1/loyalty-cards",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'cardId' => '9866191586296'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"X-Device-ID: <x-device-id>",
"X-Employee-Token: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://tapcoupon.at/api/v1/loyalty-cards"
payload := strings.NewReader("{\n \"cardId\": \"9866191586296\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Device-ID", "<x-device-id>")
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("X-Employee-Token", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://tapcoupon.at/api/v1/loyalty-cards")
.header("X-Device-ID", "<x-device-id>")
.header("Authorization", "Bearer <token>")
.header("X-Employee-Token", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"cardId\": \"9866191586296\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://tapcoupon.at/api/v1/loyalty-cards")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Device-ID"] = '<x-device-id>'
request["Authorization"] = 'Bearer <token>'
request["X-Employee-Token"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"cardId\": \"9866191586296\"\n}"
response = http.request(request)
puts response.read_body{
"scansLeft": 5,
"renewsLeft": 0,
"rewardEarned": true,
"success": true,
"message": "You earned a free coffee!"
}{
"error": "<string>",
"errorCode": "<string>"
}{
"error": "<string>",
"errorCode": "<string>"
}{
"error": "<string>",
"errorCode": "<string>"
}{
"error": "<string>",
"errorCode": "<string>"
}{
"error": "<string>",
"errorCode": "<string>"
}{
"error": "<string>",
"errorCode": "<string>"
}{
"error": "<string>",
"errorCode": "<string>"
}Cards
Use loyalty card
Record one stamp and report whether the customer earned a reward.
POST
/
loyalty-cards
Use loyalty card
curl --request POST \
--url https://tapcoupon.at/api/v1/loyalty-cards \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'X-Device-ID: <x-device-id>' \
--header 'X-Employee-Token: <api-key>' \
--data '
{
"cardId": "9866191586296"
}
'import requests
url = "https://tapcoupon.at/api/v1/loyalty-cards"
payload = { "cardId": "9866191586296" }
headers = {
"X-Device-ID": "<x-device-id>",
"Authorization": "Bearer <token>",
"X-Employee-Token": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Device-ID': '<x-device-id>',
Authorization: 'Bearer <token>',
'X-Employee-Token': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({cardId: '9866191586296'})
};
fetch('https://tapcoupon.at/api/v1/loyalty-cards', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://tapcoupon.at/api/v1/loyalty-cards",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'cardId' => '9866191586296'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"X-Device-ID: <x-device-id>",
"X-Employee-Token: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://tapcoupon.at/api/v1/loyalty-cards"
payload := strings.NewReader("{\n \"cardId\": \"9866191586296\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Device-ID", "<x-device-id>")
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("X-Employee-Token", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://tapcoupon.at/api/v1/loyalty-cards")
.header("X-Device-ID", "<x-device-id>")
.header("Authorization", "Bearer <token>")
.header("X-Employee-Token", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"cardId\": \"9866191586296\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://tapcoupon.at/api/v1/loyalty-cards")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Device-ID"] = '<x-device-id>'
request["Authorization"] = 'Bearer <token>'
request["X-Employee-Token"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"cardId\": \"9866191586296\"\n}"
response = http.request(request)
puts response.read_body{
"scansLeft": 5,
"renewsLeft": 0,
"rewardEarned": true,
"success": true,
"message": "You earned a free coffee!"
}{
"error": "<string>",
"errorCode": "<string>"
}{
"error": "<string>",
"errorCode": "<string>"
}{
"error": "<string>",
"errorCode": "<string>"
}{
"error": "<string>",
"errorCode": "<string>"
}{
"error": "<string>",
"errorCode": "<string>"
}{
"error": "<string>",
"errorCode": "<string>"
}{
"error": "<string>",
"errorCode": "<string>"
}POST /loyalty-cards
Record one stamp and report whether the customer earned a reward.
Send Authorization: Bearer YOUR_API_KEY and X-Device-ID: YOUR_DEVICE_ID. Also send X-Employee-Token: YOUR_EMPLOYEE_TOKEN. See authentication.
Use rewardEarned to decide whether to give the reward. When a reward is earned and renewals remain, the card immediately resets currentScans to zero and decrements amountRenews unless renewals are unlimited. Consequently, scansLeft can equal scansNeeded in a response with rewardEarned: true.
Without another renewal, the final successful stamp returns scansLeft: 0 and rewardEarned: true. A subsequent scan returns 422 CARD_FULLY_USED. Renewal setup is billed according to your account; see prices.
Card eligibility
The card must be activated, unarchived, unexpired, and valid for the API key’s location. Test cards are usable only during the test period. Inactive cards return422, archived cards return 410, and expired or location-mismatched cards return 400.
sessionToken is optional. Supply it when completing a partner payment session. The session must be pending, unexpired, and support the card type. A successful operation completes it; an unsupported type returns 400, and an unavailable session returns 410.
Success messages can contain $t(...) translation expressions. Use the structured response fields to determine the outcome.
Example request
curl -X POST "https://tapcoupon.at/api/v1/loyalty-cards" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Device-ID: YOUR_DEVICE_ID" \
-H "X-Employee-Token: YOUR_EMPLOYEE_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"cardId": "9866191586296"
}'
Example response
{
"scansLeft": 5,
"renewsLeft": 0,
"rewardEarned": true,
"success": true,
"message": "You earned a free coffee!"
}
Authorizations
Location API key. Also requires X-Device-ID.
Employee session token from /employee/login.
Headers
Stable device identifier. API key binds to this value on first use.
