Getting Started

This guide will help you make your first API call to TSPay and understand the basic integration flow.

Table of contents

  1. Prerequisites
  2. Base URLs
  3. Integration Flow
  4. Step 1: Authenticate and Get JWT Token
    1. Request
    2. Response
  5. Step 2: Create Your First Virtual Card
    1. Request
    2. Response
  6. Step 3: Refresh the Access Token
    1. Request
    2. Response
  7. Understanding the Response
  8. Currency and Foreign Exchange
  9. Idempotency
    1. How It Works
    2. Example
  10. Next Steps
    1. Continue Learning
  11. Common Issues
    1. Authentication Failed (401)
    2. Invalid Request (400)

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 idToken is 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, requestedCardLimit is 10000 (the value submitted in the request) and the effective cardLimit is 10500 because a 5% tolerance was applied.

Security: PAN and CVC are masked by default. Full card details are returned only when the request includes ?revealDetails=true and 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 requestId field to uniquely identify each card creation request. The requestId must be included in the request body.
  • Idempotency window: 24 hours
  • Behavior: Repeated requests using the same requestId within 24 hours return the originally created card without creating additional cards. If a repeated request uses the same requestId within 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 requestId used by different accounts does not collide

Using requestId is 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


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/login to 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/login again

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., cardLimit and maxTransactions are integers, not strings)

Back to top

© 2026 Travelsoft Pay — Confidential Partner Documentation