API Reference
This document is intended for external system integrators who need to interact with the SportyWallet Worker service over HTTP.
Base URL
The Worker service exposes a local HTTP endpoint:
| Protocol | URL |
|---|---|
| HTTP | http://localhost:60000 |
Authentication
Requests to GET /readcard, GET /info, POST /writecard, and POST /dischargecard must include the following header:
| Header | Value |
|---|---|
X-Api-Key |
Your assigned API key |
If the header is missing or invalid, the Worker returns 401 Unauthorized.
Rate Limiting
The following endpoints are subject to a fixed-window rate limit:
- Max n requests per *t* per client (n and t are depending on the request)
- Excess requests receive an HTTP
429 Too Many Requestsresponse
The /ping endpoint is not rate-limited.
Endpoints
GET /ping
A simple health-check endpoint. Use this to verify that the Worker service is running and reachable.
Rate limited: No
Auth required: No
Response
| Status | Body | Description |
|---|---|---|
200 OK |
"pong" |
Service is running |
Example
# Response
HTTP/1.1 200 OK
Content-Type: application/json
"pong"
GET /readcard
Reads the ID of the card currently placed on the connected reader device.
Rate limited: Yes, 5 requests per 10 seconds
Auth required: Yes (X-Api-Key header)
Response
| Status | Body | Description |
|---|---|---|
200 OK |
{ "cardId": "...", "credits": 5, "rechargeAmount": null } |
The identifier of the detected card and its current credits. rechargeAmount is always null on this endpoint (it is only meaningful for /writecard) |
400 Bad Request |
{ "error": "Missing customerId from auth flow" } |
The API key was validated but no customer identifier was resolved |
400 Bad Request |
{ "error": "NoCard" } |
No card is present on the reader |
400 Bad Request |
{ "error": "AuthenticationFail" } |
The card could not be authenticated |
401 Unauthorized |
{ "error": "Unauthorized: missing api key" } |
The X-Api-Key header was not provided |
401 Unauthorized |
{ "error": "Unauthorized: invalid api key" } |
The provided API key is invalid |
429 Too Many Requests |
Rate limit exceeded | |
500 Internal Server Error |
{ "error": "..." } |
An unexpected error occurred |
Example
HTTP/1.1 200 OK
Content-Type: application/json
{
"cardId": "card_1234567890",
"credits": 5,
"rechargeAmount": null
}
GET /info
Returns the current number of credits associated with the authenticated customer in the SportyWallet cloud system. This reflects the server-side record, not the value stored on the card.
Rate limited: Yes, 5 requests per 10 seconds
Auth required: Yes (X-Api-Key header)
Response
| Status | Body | Description |
|---|---|---|
200 OK |
{ "credits": "5", "creditCost": "0.5" } |
Customer's current credits in the cloud system and the € cost of a single credit. Both values are returned as strings |
400 Bad Request |
{ "error": "Missing customerId from auth flow" } |
The API key was validated but no customer identifier was resolved |
400 Bad Request |
{ "error": "CustomerReadError" } |
The customer record could not be retrieved |
401 Unauthorized |
{ "error": "Unauthorized: missing api key" } |
The X-Api-Key header was not provided |
401 Unauthorized |
{ "error": "Unauthorized: invalid api key" } |
The provided API key is invalid |
429 Too Many Requests |
Rate limit exceeded | |
500 Internal Server Error |
{ "error": "..." } |
An unexpected error occurred |
Example
HTTP/1.1 200 OK
Content-Type: application/json
{
"credits": "5",
"creditCost": "0.5"
}
POST /writecard
Recharges the card currently placed on the reader with the specified amount of credits.
Rate limited: Yes, 10 requests per minute
Auth required: Yes (X-Api-Key header)
Request
| Component | Value |
|---|---|
| Method | POST |
| Path | /writecard |
| Headers | Content-Type: application/json, X-Api-Key: <your-api-key> |
| Body | JSON object with credits or amount |
Request Body
Recharge by number of credits:
{
"credits": 10
}
Recharge by € amount (converted to credits using the customer's credit cost):
{
"amount": 1.5
}
| Field | Type | Required | Description |
|---|---|---|---|
credits |
integer |
One of credits or amount |
Number of credits to add directly to the card |
amount |
number |
One of credits or amount |
€ value to convert into credits using the customer's credit cost |
Response
| Status | Body | Description |
|---|---|---|
200 OK |
{ "cardId": "...", "credits": 17, "rechargeAmount": 8.5 } |
The identifier of the detected card, credits after the recharge, and the € amount charged for the recharge |
400 Bad Request |
{ "error": "Invalid credits or amount value" } |
The request body is missing both credits and amount, or they are null |
400 Bad Request |
{ "error": "Missing customerId from auth flow" } |
The API key was validated but no customer identifier was resolved |
400 Bad Request |
{ "error": "NoCard" } |
No card is present on the reader |
400 Bad Request |
{ "error": "AuthenticationFail" } |
The card could not be authenticated |
401 Unauthorized |
{ "error": "Unauthorized: missing api key" } |
The X-Api-Key header was not provided |
401 Unauthorized |
{ "error": "Unauthorized: invalid api key" } |
The provided API key is invalid |
429 Too Many Requests |
Rate limit exceeded | |
500 Internal Server Error |
{ "error": "NoCredits" } |
The card has no credits to recharge from |
500 Internal Server Error |
{ "error": "NegativeCredits" } |
The card has a negative credit balance |
500 Internal Server Error |
{ "error": "..." } |
An unexpected error occurred |
Example Request
POST /writecard HTTP/1.1
Host: localhost:60000
X-Api-Key: your-api-key
Content-Type: application/json
{
"credits": 10
}
Example - Success
HTTP/1.1 200 OK
Content-Type: application/json
{
"cardId": "XXXXXX",
"credits": 17,
"rechargeAmount": 8.5
}
Example - Missing API Key
HTTP/1.1 401 Unauthorized
Content-Type: text/plain
Unauthorized: missing api key
Example - No Card
HTTP/1.1 400 Bad Request
Content-Type: application/json
{ "error": "NoCard" }
POST /dischargecard
Discharges (resets to zero) the card currently placed on the reader. The operation is tracked in the cloud system before and after the card is cleared.
Rate limited: Yes, 10 requests per minute
Auth required: Yes (X-Api-Key header)
Request
| Component | Value |
|---|---|
| Method | POST |
| Path | /dischargecard |
| Headers | X-Api-Key: <your-api-key> |
| Body | None |
Response
| Status | Body | Description |
|---|---|---|
200 OK |
{ "cardId": "...", "dischargedCredits": 5, "dischargedAmount": 2.5 } |
The identifier of the discharged card, the credits that were removed, and the € amount credited back for the discharge |
400 Bad Request |
{ "error": "Missing customerId from auth flow" } |
The API key was validated but no customer identifier was resolved |
400 Bad Request |
{ "error": "NoCard" } |
No card is present on the reader |
400 Bad Request |
{ "error": "AuthenticationFail" } |
The card could not be authenticated |
401 Unauthorized |
{ "error": "Unauthorized: missing api key" } |
The X-Api-Key header was not provided |
401 Unauthorized |
{ "error": "Unauthorized: invalid api key" } |
The provided API key is invalid |
429 Too Many Requests |
Rate limit exceeded | |
500 Internal Server Error |
{ "error": "ErrorTrackingDischargeMovement" } |
The discharge movement could not be tracked in the cloud |
500 Internal Server Error |
{ "error": "..." } |
An unexpected error occurred |
Example - Success
HTTP/1.1 200 OK
Content-Type: application/json
{
"cardId": "XXXXXX",
"dischargedCredits": 17,
"dischargedAmount": 8.5
}
Example - No Card
HTTP/1.1 400 Bad Request
Content-Type: application/json
{ "error": "NoCard" }
Error Reference
| HTTP Status | Meaning |
|---|---|
200 OK |
Request succeeded |
400 Bad Request |
Invalid request payload, missing customer identifier, no card detected, or card authentication failure |
401 Unauthorized |
Missing or invalid API key |
429 Too Many Requests |
Rate limit exceeded — wait before retrying |
500 Internal Server Error |
Card or cloud operation failed — check the error field in the response body |
Error codes in response body
All error responses from the Worker use the same JSON format: { "error": "<code>" }.
| Error code | Status | Endpoint | Meaning |
|---|---|---|---|
Missing customerId from auth flow |
400 |
all authenticated endpoints | The API key was validated but no customer identifier could be resolved |
Invalid credits or amount value |
400 |
/writecard |
The request body is missing both credits and amount, or they are null |
NoCard |
400 |
/readcard, /writecard, /dischargecard |
No card is present on the reader |
AuthenticationFail |
400 |
/readcard, /writecard, /dischargecard |
The card could not be authenticated |
CustomerReadError |
400 |
/info |
The customer record could not be retrieved |
NoCredits |
500 |
/writecard |
The card has no credits |
NegativeCredits |
500 |
/writecard |
The card has a negative credit balance |
ErrorTrackingDischargeMovement |
500 |
/dischargecard |
The discharge could not be tracked in the cloud |