Getting Started
This guide will help you make your first API call to TSPay and understand the basic integration flow.
Table of contents
- Prerequisites
- Base URLs
- Integration Flow
- Step 1: Authenticate and Get JWT Token
- Step 2: Create Your First Virtual Card
- Step 3: Refresh the Access Token
- Understanding the Response
- Currency and Foreign Exchange
- Idempotency
- Next Steps
- Common Issues
Prerequisites
Before starting integration, ensure you have:
- API credentials provided by TSPay (contact TSPay support to obtain them)
- IP addresses registered with TSPay — API access is restricted by IP allowlisting on both Sandbox and Production environments
- An HTTP client or development environment (curl, Postman, JavaScript, Python, Java, etc.)
- HTTPS support for all outbound requests
- Ability to send and parse JSON payloads
Base URLs
TSPay provides two fully isolated environments. Each environment has separate credentials and data:
| Environment | Base URL | Purpose |
|---|---|---|
| Production | https://tspay-api.live.travelsoftpay.com | Live transactions |
| Sandbox | https://tspay-api.sandbox.travelsoftpay.com | Testing and development |
Tokens and credentials are not interchangeable between environments. All examples in this guide use the Sandbox environment.
Integration Flow
Partners integrate directly with the TSPay API. TSPay manages communication with the issuing processor and returns card provisioning responses through the API.
sequenceDiagram
participant Partner
participant TSPay API
participant Issuing Processor
Partner->>TSPay API: 1. POST /api/v1/auth/login
TSPay API-->>Partner: 2. accessToken + refreshToken
Partner->>TSPay API: 3. POST /api/v1/issuing/cards (with token)
TSPay API->>Issuing Processor: 4. Provision card
Issuing Processor-->>TSPay API: 5. Card details
TSPay API-->>Partner: 6. Card response (masked PAN, card details)
Partner->>TSPay API: 7. POST /api/v1/auth/refresh (before expiry)
TSPay API-->>Partner: 8. New accessToken
Step 1: Authenticate and Get JWT Token
Before making any API calls, you must authenticate and receive a JWT token.
Request
curl -X POST https://tspay-api.sandbox.travelsoftpay.com/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"username": "partner_company",
"password": "SecureP@ssw0rd!"
}'
Response
{
"accessToken": "eyJraWQiOi...",
"accessTokenExpiresAt": 1736515800,
"idToken": "eyJraWQiOi...",
"idTokenExpiresAt": 1736515800,
"refreshToken": "eyJjdHkiOi...",
"refreshTokenExpiresAt": 1736601600
}
All expiration fields are Unix timestamps (seconds since epoch).
The
idTokenis an OpenID Connect identity token. It is not required for most API operations and can typically be ignored unless your application needs to validate the authenticated user identity.
Store the accessToken and refreshToken securely server-side. Include the access token in the Authorization header for all subsequent API requests:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
| Token | Validity |
|---|---|
accessToken | 1 hour |
refreshToken | 24 hours |
Access tokens expire after 1 hour. Implement token refresh logic — see Step 3 below.
Step 2: Create Your First Virtual Card
Now let’s create a virtual card with spending controls.
Request
curl -X POST https://tspay-api.sandbox.travelsoftpay.com/api/v1/issuing/cards \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"requestId": "1230537f-e892-4678-b945-17bfb6d1a456",
"cardLimit": 10000,
"currency": "EUR",
"config": {
"expiryDuration": 12,
"authorizationWindow": {
"startDate": "2025-01-10T00:00:00Z",
"endDate": "2025-01-17T23:59:59Z"
},
"tolerance": {
"percentage": 5
},
"cardType": "MTA",
"maxTransactions": 1,
"allowedCategories": []
},
"metadata": {
"card_name": "Travel bookings",
"file_ref": "AB1234",
"departure_date": "2025-01-10",
"project_id": "Project-Alpha-456",
"cost_center": "Marketing-Q3",
"airline_code": "BA",
"hotel_brand": "BOOKING"
}
}'
Response
{
"cardId": "ic_1ScUKNPj0YljeLEKBRcVSSuO",
"pan": "************0054",
"cvc": "***",
"expMonth": 1,
"expYear": 2029,
"status": "active",
"requestedCardLimit": 10000,
"cardLimit": 10500,
"currency": "EUR",
"createdAt": "2025-01-10T14:30:00Z"
}
In this example,
requestedCardLimitis10000(the value submitted in the request) and the effectivecardLimitis10500because a5%tolerance was applied.
Security: PAN and CVC are masked by default. Full card details are returned only when the request includes
?revealDetails=trueand the calling credential has the required permission. Handle all card data according to PCI-DSS requirements.
Step 3: Refresh the Access Token
Before your access token expires (after 1 hour), use the refresh token to obtain a new one without logging in again:
Request
curl -X POST https://tspay-api.sandbox.travelsoftpay.com/api/v1/auth/refresh \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_CURRENT_ACCESS_TOKEN" \
-d '{
"refreshToken": "eyJjdHkiOi..."
}'
Response
{
"accessToken": "eyJraWQiOi...",
"accessTokenExpiresAt": 1736519400
}
Replace your stored access token with the new one. If the refresh token itself has expired (after 24 hours), call /api/v1/auth/login again.
Understanding the Response
| Field | Description |
|---|---|
cardId | Unique identifier for the card — use this for future queries and operations |
pan | Primary Account Number (masked by default) |
cvc | Card Verification Code (masked by default) |
expMonth | Expiration month (1–12) |
expYear | Expiration year (4 digits) |
status | Card status: active, canceled, or inactive |
requestedCardLimit | The cardLimit value submitted in the request, before tolerance is applied |
cardLimit | Effective spending limit in minor units (after tolerance is applied) |
currency | ISO 4217 currency code (uppercase, e.g., EUR) |
Currency and Foreign Exchange
The transaction currency of a card is defined when the card is created using the currency field.
Supported currencies depend on the issuing programme configuration of the issuing account. For example:
- EU issuing programmes typically support EUR
- UK issuing programmes may support GBP
Cards must be created in a currency enabled for the issuing account. Attempting to create a card in an unsupported currency returns a validation error.
When additional currencies are enabled in the future, the API will support them without requiring changes to the integration.
Contact TSPay support to confirm the currencies enabled for your issuing account.
Idempotency
Card creation is idempotent to prevent duplicate issuance during retries.
How It Works
- Idempotency key: Use the
requestIdfield to uniquely identify each card creation request. TherequestIdmust be included in the request body. - Idempotency window: 24 hours
- Behavior: Repeated requests using the same
requestIdwithin 24 hours return the originally created card without creating additional cards. If a repeated request uses the samerequestIdwithin the idempotency window, TSPay returns the original result even if the new request payload differs. The new payload is ignored and no update is applied. - Retry safety: Safe to retry failed requests with the same
requestId - Scope: Idempotency keys are scoped per issuing account — the same
requestIdused by different accounts does not collide
Using
requestIdis required for all card creation requests to prevent duplicate issuance on network errors or timeouts.
Example
# First request
curl -X POST https://tspay-api.sandbox.travelsoftpay.com/api/v1/issuing/cards \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"requestId": "1230537f-e892-4678-b945-17bfb6d1a456", ...}'
# Returns: {"cardId": "ic_abc123", ...}
# Retry with same requestId (e.g., after network error)
curl -X POST https://tspay-api.sandbox.travelsoftpay.com/api/v1/issuing/cards \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"requestId": "1230537f-e892-4678-b945-17bfb6d1a456", ...}'
# Returns: Same card {"cardId": "ic_abc123", ...} — no duplicate created
Next Steps
Congratulations! You’ve successfully:
- Obtained a JWT token
- Created a virtual card
- Understood token refresh, idempotency, and FX handling
Continue Learning
- Authentication Guide - Deep dive into JWT authentication and security
- Virtual Cards - Learn more about card creation options
Common Issues
Authentication Failed (401)
Problem: Invalid credentials or expired token
Solution:
- Verify your API username and password with TSPay support
- If your access token has expired (after 1 hour), call
POST /api/v1/auth/loginto obtain a new session. To avoid this, refresh the token before it expires — see Step 3 - If your refresh token has expired (after 24 hours), call
POST /api/v1/auth/loginagain
Invalid Request (400)
Problem: Malformed JSON or missing required fields
Solution:
- Validate your JSON payload
- Ensure all required fields are present (
requestId,cardLimit,currency) - Verify data types match the API specification (e.g.,
cardLimitandmaxTransactionsare integers, not strings)