Overview
The HTTP API provides three endpoints for terminal and payment management:| Method | Endpoint | Description |
|---|---|---|
| GET | /v1/terminals | List available terminals |
| POST | /v1/terminals/{terminalId}/payments | Initiate a payment |
| GET | /v1/transactions/{transactionId} | Check transaction status |
Base URL
Replace
{your-api-endpoint} with your provisioned API endpoint. Contact support@moduluslabs.io to obtain your endpoint URL.GET /v1/terminals
Retrieve all active terminals in your group.Headers
| Header | Required | Description |
|---|---|---|
x-api-key | Yes | Your API key |
x-timestamp | Yes | ISO 8601 timestamp |
x-signature | Yes | HMAC-SHA256 signature |
Response (200 OK)
Response Fields
| Field | Type | Description |
|---|---|---|
terminals | array | List of available terminals |
terminals[].connectionId | string | Unique connection identifier |
terminals[].terminalId | string | Primary identifier (deviceId if available) |
terminals[].deviceId | string | Stable device identifier (if configured) |
terminals[].connectedAt | string | ISO 8601 timestamp of connection |
terminals[].lastActivity | string | ISO 8601 timestamp of last activity |
terminals[].status | string | online, offline, or reconnecting |
terminals[].metadata | object | Custom terminal metadata |
count | number | Total number of terminals |
timestamp | string | ISO 8601 timestamp of the response |
Error Responses
| Status | Code | Description |
|---|---|---|
| 401 | UNAUTHORIZED | Invalid or missing authentication |
| 403 | GROUP_MISMATCH | Only desktop devices can list terminals |
| 500 | INTERNAL_ERROR | Server error |
Code Example
POST /v1/terminals//payments
Initiate a payment to a specific terminal. By default, this endpoint uses long-polling and waits up to 90 seconds for the terminal to respond. Alternatively, setwebhookMode: true for immediate response with asynchronous notification via webhook.
Path Parameters
The terminal identifier. Resolved as
deviceId first, falling back to connectionId. See Terminal ID Resolution.The
terminalId is resolved as a deviceId first, falling back to connectionId for legacy integrations. See Terminal ID Resolution for details.Headers
| Header | Required | Description |
|---|---|---|
Content-Type | Yes | application/json |
x-api-key | Yes | Your API key |
x-timestamp | Yes | ISO 8601 timestamp |
x-signature | Yes | HMAC-SHA256 signature |
Request Body
Unique transaction identifier. Auto-generated if not provided.
Payment amount.
ISO 4217 currency code (e.g.,
"USD", "EUR").Payment method:
"CARD", "CASH", "MOBILE", or "OTHER".Array of products in the transaction.
Customer information.
Custom key-value pairs for your use.
When
true, disables 90-second long-polling and returns 202 Accepted immediately. The payment result will be delivered via webhook to your configured endpoints. Requires at least one webhook endpoint to be configured.Request Example
Response (200 OK) - Success
Response (202 Accepted) - Webhook Mode
Returned whenwebhookMode: true. The payment has been sent to the terminal and results will be delivered via webhook:
When using webhook mode, you must have at least one webhook endpoint configured. The payment result will be delivered to your endpoints as a
payment.completed, payment.failed, payment.cancelled, or payment.timeout event.Response (202 Accepted) - Terminal Disconnected
Returned when the terminal disconnects during payment processing (standard mode only):Response (504 Gateway Timeout)
Returned when the terminal doesn’t respond within 90 seconds:Error Responses
| Status | Code | Description |
|---|---|---|
| 400 | INVALID_REQUEST | Invalid request body or missing fields |
| 400 | INVALID_AMOUNT | Amount doesn’t match products total |
| 400 | NO_WEBHOOK_ENDPOINTS | webhookMode: true requires at least one webhook endpoint |
| 401 | UNAUTHORIZED | Invalid authentication |
| 403 | GROUP_MISMATCH | Terminal not in your group |
| 404 | TERMINAL_NOT_FOUND | Terminal not found |
| 409 | PAYMENT_IN_PROGRESS | Another payment is being processed |
| 502 | TERMINAL_CONNECTION_ERROR | Failed to communicate with terminal |
| 503 | TERMINAL_OFFLINE | Terminal is offline |
| 504 | TIMEOUT | Terminal did not respond in time |
Code Example
GET /v1/transactions/
Retrieve the status of a transaction. Useful for reconciliation or checking status after a timeout.Path Parameters
The transaction ID to query.
Headers
| Header | Required | Description |
|---|---|---|
x-api-key | Yes | Your API key |
x-timestamp | Yes | ISO 8601 timestamp |
x-signature | Yes | HMAC-SHA256 signature |
Response (200 OK)
Response Fields
| Field | Type | Description |
|---|---|---|
transactionId | string | Unique transaction identifier |
status | string | Transaction status (see below) |
request | object | Original payment request |
response | object | Payment response (if completed) |
createdAt | string | ISO 8601 timestamp of creation |
updatedAt | string | ISO 8601 timestamp of last update |
completedAt | string | ISO 8601 timestamp of completion |
terminalDeviceId | string | Terminal device ID (if available) |
voidedAt | string | Timestamp when voided (if applicable) |
voidReason | string | Reason for voiding (if voided) |
timestamp | string | ISO 8601 timestamp of this response |
Transaction Status Values
| Status | Description |
|---|---|
PENDING | Transaction created, awaiting terminal response |
COMPLETED | Transaction completed successfully |
FAILED | Transaction failed (see error details) |
CANCELLED | Transaction was cancelled |
AWAITING_RECONNECT | Terminal disconnected, waiting for reconnection |
VOIDED | Payment was voided (terminal reconnected too late) |
Error Responses
| Status | Code | Description |
|---|---|---|
| 401 | UNAUTHORIZED | Invalid authentication |
| 403 | GROUP_MISMATCH | Transaction not in your group |
| 404 | TRANSACTION_NOT_FOUND | Transaction not found |
| 500 | INTERNAL_ERROR | Server error |
Code Example
Rate Limiting
The API implements rate limiting to ensure service stability. Current limits are applied per API key.| Limit Type | Value |
|---|---|
| Requests per minute | Contact support |
| Concurrent payments | 1 per terminal |
429 Too Many Requests response:
Contact support@moduluslabs.io if you require higher rate limits for your integration.
Troubleshooting
Authentication Issues
Authentication Issues
Common causes:
- Invalid API key or secret
- System clock not synchronized (timestamp must be within 5 minutes)
- Incorrect SHA256 body hash computation (must be hex-encoded)
- String-to-sign format mismatch (check newline characters)
- Verify your API key and secret are correct
- Check your system clock is synchronized with NTP
- Log the string-to-sign and compare with documentation
- Ensure body hash is computed on the exact JSON string sent
Payment Timeouts
Payment Timeouts
What to do after a 504 timeout:
- Do not retry the payment immediately
- Call
GET /v1/transactions/{transactionId}to check actual status - The payment may have completed on the terminal
- Only retry if status is
FAILEDorCANCELLED
- Verify terminal is online before initiating payments
- Monitor terminal status with
GET /v1/terminals
Terminal Not Found
Terminal Not Found
Causes:
- Terminal is offline
- Using wrong terminal ID (connectionId vs deviceId)
- Terminal in different group
- Refresh terminal list with
GET /v1/terminals - Use
deviceIdinstead ofconnectionId - Verify API key matches terminal’s group
Payment In Progress (409)
Payment In Progress (409)
Cause: Another payment is already being processed on the terminal.Solution: Wait for the current payment to complete before initiating a new one. Terminals can only process one payment at a time.