Expi API Documentation

Welcome to the Expi API documentation. All endpoints are accessed via the central query handler.

The API is built for quick integration: send JSON requests, receive JSON responses, and keep all payment workflows in one place. Use it to build custom checkout experiences, manage customers, issue invoices, and automate recurring billing with minimal overhead.

If you are new to the platform, start with Authentication, then explore the endpoint sections for the resources you need. Each section highlights core fields and common workflows.

Base URL: https://your-domain.com/query

Authentication

Every request must be authenticated. You can do this via Basic Auth or by including credentials in the JSON body. Pick one method and keep it consistent across your integration.

Use your merchant username as x_login and your secret key as x_tran_key for protected merchant endpoints. The login token flow on /query/auth/* is public and uses user credentials instead.

Quick Checklist
  • Credentials are present on every request.
  • Only one auth method is used per request.
  • Secrets never appear in client-side code.
Auth Endpoints
  • POST /query/auth/mfatoken — Validates username/password and returns an mfa_token.
  • POST /query/auth/token — If payload contains mfa_token and code, verifies MFA and issues an access token.
  • POST /query/auth/token — If payload contains username (or email) and password, it also requires trusted-device credentials to issue an access token.
  • GET /query/me — Returns the current authenticated user and merchant context (requires authentication).
Example: Login Step 1 (POST /query/auth/mfatoken)
{
  "username": "user@example.com",
  "password": "your_password"
}
MFA Challenge Response (HTTP 200)
{
  "result": "success",
  "mfa_token": "dummy_mfa_token",
  "expires_in": 300
}
Example: Login Step 2 (POST /query/auth/token)
{
  "mfa_token": "dummy_mfa_token",
  "code": "123456",
  "remember_device": 1
}
Example: Trusted Login (POST /query/auth/token)
{
  "username": "user@example.com",
  "password": "your_password",
  "trusted_device_id": "32_hex_device_id",
  "trusted_device_token": "device_token"
}
MFA Success (remembered device)
{
  "result": "success",
  "user_id": 12,
  "merchant": "MERCHANTCODE",
  "access_token": "dummy_access_token",
  "token_type": "Bearer",
  "expires_in": 3600,
  "trusted_device_id": "32_hex_device_id",
  "trusted_device_token": "device_token",
  "trusted_device_expires_in": 2592000
}
Example: Me (GET /query/me)
Authorization: Bearer <access_token>
Option 1: Basic Auth (Header)
Authorization: Basic <base64(username:secret_key)>

Base64 must be generated from the exact string username:secret_key (one colon, no extra spaces).

Option 2: Body Parameters
{
  "x_login": "your_username",
  "x_tran_key": "your_secret_key"
}
Common Pitfalls
  • Wrong key: Make sure you use the secret key, not a public identifier.
  • Mixed methods: Do not send both Basic Auth and body credentials in the same request.
  • Invalid JSON: Trailing commas or comments will cause auth to fail.
  • MFA challenge shape: An MFA-required login returns result: "success" with mfa_token and expires_in.
  • Remember device default: If remember_device is omitted during MFA verification, the device is remembered by default.
  • Trusted login requirements: The username/password token flow requires both trusted_device_id and trusted_device_token; otherwise it fails with Unknown Device.
Security Tips
  • Store secrets in server-side environment variables.
  • Rotate keys regularly and after staff changes.
  • Never log raw credentials in application logs.

REST API

Streamline Transactions with Expitrans API


Our REST API allows developers to integrate online payment functionalities into their applications. By making API requests, you can process transactions, manage customers, handle subscriptions, and generate invoices programmatically.

How It Works

The API uses JSON format for requests and responses, ensuring seamless communication between your application and our payment gateway. Authentication is required for secure access, and each request must include the necessary credentials.

Our REST API provides several key functionalities:

  • Customers – Create profiles, store billing details, and manage customer data.
  • Invoices – Generate invoices, track status, and collect payments.
  • Products – Define items and pricing used across invoices and recurring.
  • Card Issuing – Issue cards, fund balances, and fetch card activity.
  • Recurring – Automate scheduled billing with flexible intervals.
Optional Pagination Query Parameters

List endpoints support optional pagination query parameters:

  • page (optional): Page number to return (1-based).
  • pageSize (optional): Number of records per page. Defaults to 50 when not provided.

Pagination is only applied when page is provided. If page is omitted, the full list is returned.

These endpoints allow businesses to automate payment workflows and enhance their integration capabilities. In the next sections, we’ll provide detailed instructions on how to use each API.

Tokens

Create short-lived card tokens for use with the Charges API.

Authentication:

- Authorization: Bearer <access_token> (recommended if you use the login/JWT flow)

- or Authorization: Basic (merchant x_login / x_tran_key)

- or include x_login and x_tran_key in the JSON body

POST /tokens Create Card Token
Body Parameters
Field Type Required Description
numberstringYes16-digit card number.
monthstringYes2-digit month 0112.
yearstringYes2-digit year YY.
x_loginstringNoMerchant login (only if not using Authorization header).
x_tran_keystringNoMerchant tran key/secret (only if not using Authorization header).
Create Token Body
{
  "number": "4242424242424242",
  "month": "12",
    "year": "30"
}
Sample Response
{
  "result": "success",
  "token": "tok_..."
}

Charges

Charge operations backed by Transactions. A charge id corresponds to the Transaction presentation_id within the authenticated merchant scope.

Authentication:

- Authorization: Bearer <access_token> (recommended if you use the login/JWT flow)

- or Authorization: Basic (merchant x_login / x_tran_key)

- or include x_login and x_tran_key in the JSON body

GET /charges List Charges
POST /charges Create a Charge
Create Charge Body Parameters
Field Type Required Description
tokenstringConditionalToken from /tokens. Required unless charging with payment_method_id.
payment_method_idnumberConditionalExisting saved payment method id (CustomerDetails). Required unless charging with token. Aliases: x_payment_id, paymentmethodid.
cvcstringConditionalRequired for token-based charges. Provide at charge time (do not store). You can also pass billing.cvc.
amountnumberYesCharge amount.
transtypestringNoDefaults to AUTH_CAPTURE. Use AUTH_ONLY for auth-then-capture flows.
billingobjectNoBilling/contact fields (first_name, last_name, address, city, state, zip, country, phone, email, description).
customer_idnumberNoOptional customer id. When charging with payment_method_id, if provided it must match the payment method’s customer.
save_payment_methodbooleanNoIf true, creates a customer/payment method (if needed) and charges it. Requires token-based charge (raw card data is needed).
use_customer_profilebooleanNoIf true and customer_id is set, instructs the gateway to use the stored customer profile where supported. Auto-enabled for payment_method_id charges.
x_loginstringNoMerchant login (only if not using Authorization header).
x_tran_keystringNoMerchant tran key/secret (only if not using Authorization header).
GET /charges/{id} Retrieve a Charge
PUT /charges/{id} Update a Charge
POST /charges/{id}/capture Capture a Charge
GET /charges/search?q={query} Search Charges
Create Charge (Token) Body
{
    "token": "tok_...",
    "cvc": "123",
    "amount": 12.34,
    "transtype": "AUTH_CAPTURE",
    "billing": {
        "first_name": "Jane",
        "last_name": "Smith",
        "address": "123 Main St",
        "city": "New York",
        "state": "NY",
        "zip": "10001",
        "country": "USA",
        "email": "jane@example.com",
        "phone": "5550123",
        "description": "Online Purchase"
    }
}
Create Charge (Payment Method) Body
{
  "payment_method_id": 12345,
  "customer_id": 67890,
  "amount": 12.34,
  "transtype": "AUTH_CAPTURE"
}
Create Charge + Save Payment Method
{
  "token": "tok_...",
    "cvc": "123",
  "amount": 12.34,
  "save_payment_method": true,
  "billing": {
    "first_name": "Jane",
    "last_name": "Smith",
    "email": "jane@example.com",
    "company": "Acme Inc",
    "address": "123 Main St",
    "city": "New York",
    "state": "NY",
    "zip": "10001",
    "country": "USA",
    "phone": "5550123"
  }
}
Create Charge (Sample Response)
{
  "result": "success",
  "charge": {
    "id": 123456,
    "transaction_id": 98765,
    "amount": 12.34,
    "currency": "USD",
    "status": 1,
    "status_text": "succeeded",
    "type": 1,
    "created": "...",
    "description": "Online Purchase",
    "notes": null,
    "reference_id": 0,
    "last4": "4242"
  },
    "customer_id": 67890,
    "payment_method_id": 12345,
  "transaction": {
    "status": 1,
    "status_text": "Success",
    "reason_text": "...",
    "transaction_id": "123456"
    }
}
Capture Charge Body Parameters
Field Type Required Description
amountnumberNoOptional capture amount (omit for full capture where supported).
x_loginstringNoMerchant login (only if not using Authorization header).
x_tran_keystringNoMerchant tran key/secret (only if not using Authorization header).
Capture Charge Body
{
  "amount": 12.34
}

Transactions

Transaction records are backed by the transactions table.

ID behavior: for GET /query/transaction/{id}, the endpoint first resolves {id} against merchant-scoped presentation_id, then falls back to internal transaction_id. In responses, uniqueID reflects merchant-facing presentation_id.

Authentication:

- Authorization: Bearer <access_token> (recommended if you use the login/JWT flow)

- or Authorization: Basic (merchant x_login / x_tran_key)

- or include x_login and x_tran_key in the JSON body

GET /query/transaction List Transactions

Optional query parameters for GET /query/transaction:

  • page: page number (1-based). When provided, results are paginated.
  • pageSize: records per page. Optional; defaults to 50.
List Query Parameters
Field Type Required Description
pageintegerNoOptional page number for list results.
pageSizeintegerNoOptional page size for list results.
filtersstringNoOptional filter expression (same behavior as other Expi list endpoints).
sortstringNoOptional sort key (for example -uniqueID).
modifiersstringNoOptional comma-separated response field projection.
List Transactions Example
GET /query/transaction?page=1&pageSize=25&sort=-uniqueID
GET /query/transaction/{id} Retrieve a Transaction
POST /query/transaction Create a Transaction Record
Create Transaction Body Parameters
Field Type Required Description
amount_total / amountnumberYesTransaction amount. amount_total matches the response structure.
amount_taxnumberNoOptional tax amount.
amount_discountnumberNoOptional discount amount.
amount_shippingnumberNoOptional shipping amount.
amount_surchargenumberNoOptional surcharge amount.
amount_tipnumberNoOptional tip amount.
currencystringNoOptional currency code (for example USD).
descriptionstringNoOptional description.
notesstringNoOptional notes.
coupon_idnumberNoOptional coupon id association.
recurring_idnumberNoOptional recurring/subscription id association.
transtypestring|numberNoDefaults to AuthCapture. Accepts string or numeric code.
statusstring|numberNoNot accepted on create. Always stored as Unprocessed.
statestring|numberNoDefaults to Unknown. Accepts string or numeric code.
sourcestring|numberNoDefaults to Endpoint. Accepts string or numeric code; response returns the human-readable label (for example, Endpoint).
created / transdatestringNoOptional transaction timestamp (if omitted, DB/defaults apply). created matches the response structure.
invoicing_id / invoice_idnumberNoOptional link to an invoice.
invoiceobjectNoIf provided and invoice id is omitted (invoicing_id / invoice_id), an invoice is created and linked.
items / line_itemsarrayNoOptional line items. Stored on the linked invoice as invoice details. If no invoice context is supplied, an invoice will be created (requires customer_id or enough customer/billing data to create one).
customer_idnumberNoCustomer association. If omitted, a customer record is created from customer or billing/shipping.
customerobjectNoOptional customer payload used to create a customer when customer_id is omitted.
payment_information.methodnumber|stringNoNon-sensitive payment method indicator (ex: CC, echeck, or numeric code).
payment_information.last4stringNoNon-sensitive last 4 digits (stored as provided digits only).
billingobjectNoOptional billing/contact fields (first_name, last_name, address, city, state, zip, country, phone1, phone2, email). phone is also accepted as an alias for phone1.
shippingobjectNoOptional shipping/contact fields (first_name, last_name, address, city, state, zip, country, phone1, phone2, email). phone is also accepted as an alias for phone1.
PUT /query/transaction/{id} Update a Transaction
DELETE /query/transaction/{id} Delete a Transaction
Create Transaction Body
{
    "amount_total": 12.34,
    "amount_tax": 0.50,
    "amount_discount": 1.00,
    "amount_shipping": 2.50,
    "amount_surcharge": 0.25,
    "amount_tip": 1.50,
    "currency": "USD",
    "description": "Order #1001",
    "notes": "Recorded from mobile tap-to-pay",
    "transtype": "AuthCapture",
    "state": "Settled",
    "created": "2026-01-29 12:34:56",
    "payment_information": {
        "method": "CC",
        "last4": "4242"
    },
    "billing": {
        "first_name": "Jane",
        "last_name": "Smith",
        "email": "jane@example.com",
        "phone1": "555-555-5555"
    },
    "items": [
        {"title": "T-Shirt", "quantity": 1, "unit_price": 12.34}
    ]
}
Transaction (Sample Response)
{
  "result": "success",
  "transaction": {
    "uniqueID": 123456,
    "customer_id": 555,
    "coupon_id": 0,
    "recurring_id": 0,
    "amount_total": 12.34,
    "amount_tax": 0,
    "amount_discount": 12.34,
    "amount_shipping": 0,
    "amount_surcharge": 0,
    "amount_tip": 0,
    "currency": "USD",
    "created": "2026-01-29 12:34:56",
    "description": "Order #1001",
    "notes": "Created by integration",
    "billing": {
      "first_name": "Jane",
      "last_name": "Smith",
      "email": "jane@example.com",
      "phone1": "555-555-5555",
      "phone2": "",
      "address": "",
      "address2": "",
      "city": "",
      "state": "",
      "zip": "",
      "country": ""
    },
    "shipping": {
      "first_name": "",
      "last_name": "",
      "email": "",
      "phone1": "",
      "phone2": "",
      "address": "",
      "address2": "",
      "city": "",
      "state": "",
      "zip": "",
      "country": ""
    },
    "payment_information": {
      "method": 16,
      "last4": "4242"
    },
    "invoicing_id": null,
    "reference_id": null,
    "status": "Unprocessed",
    "state": "Settled",
    "transtype": "AuthCapture",
    "source": "Endpoint"
  }
}

Refunds

Refund operations backed by Transactions. Refunds are processed as gateway CREDIT transactions against an existing charge (Transaction presentation_id) within the authenticated merchant scope.

Authentication:

- Authorization: Bearer <access_token> (recommended if you use the login/JWT flow)

- or Authorization: Basic (merchant x_login / x_tran_key)

- or include x_login and x_tran_key in the JSON body

POST /refunds Create a Refund
Create Refund Body Parameters
Field Type Required Description
charge_idnumberYesOriginal charge Transaction presentation_id. Alias: transaction_id.
amountnumberYesRefund amount. Must be greater than 0 and not exceed the original charge amount.
notesstringNoOptional notes sent to the gateway.
x_loginstringNoMerchant login (only if not using Authorization header).
x_tran_keystringNoMerchant tran key/secret (only if not using Authorization header).
Create Refund (Body)
{
  "charge_id": 123456,
  "amount": 12.34,
  "notes": "Customer requested refund"
}
Create Refund (Sample Response)
{
  "result": "success",
  "refund": {
    "id": 222222,
    "transaction_id": 98765,
    "amount": 12.34,
    "currency": "USD",
    "status": 1,
    "status_text": "succeeded",
    "type": 4,
    "created": "...",
    "description": null,
    "notes": null,
    "reference_id": 0,
    "last4": "4242"
  },
  "original_charge": {
    "id": 123456,
    "transaction_id": 12345,
    "amount": 12.34,
    "currency": "USD",
    "status": 1,
    "status_text": "succeeded",
    "type": 1,
    "created": "...",
    "description": "Online Purchase",
    "notes": null,
    "reference_id": 0,
    "last4": "4242"
  },
  "transaction": {
    "status": 1,
    "status_text": "Success",
    "reason_text": "...",
    "transaction_id": "222222"
  }
}

Customer

Manage customer profiles with a single endpoint. Create customers and store contact, billing, and custom fields for downstream billing workflows.

GET /query/customer Get All Customers
List Query Parameters
Field Type Required Description
pageintegerNoOptional page number for customer list results.
pageSizeintegerNoOptional page size for customer list results.
filtersstringNoOptional filter expression.
sortstringNoOptional sort key (for example -uniqueID).
modifiersstringNoOptional comma-separated response field projection.
List Customers Example
GET /query/customer?page=1&pageSize=25&sort=-uniqueID
GET /query/customer/{id} Get Single Customer
Sample Response
{
  "result": "success",
  "customer": {
    "uniqueID": 1234,
    "customer_information": {
      "firstname": "Alex",
      "lastname": "Rivera",
      "address1": "123 Market Street",
      "address2": "",
      "city": "San Francisco",
      "state": "CA",
      "zip": "94105",
      "country": "USA",
      "phone1": "4155550134",
      "phone2": "",
      "email": "alex.rivera@example.com"
    },
    "billing_information": {
      "firstname": "Alex",
      "lastname": "Rivera",
      "address1": "123 Market Street",
      "address2": "",
      "city": "San Francisco",
      "state": "CA",
      "zip": "94105",
      "country": "USA",
      "phone": "4155550134",
      "email": "alex.rivera@example.com"
    },
    "custom": {
      "custom1": "A-1001",
      "custom2": "Gold",
      "custom3": "West",
      "custom4": "",
      "custom5": "",
      "custom6": "",
      "custom7": "",
      "custom8": "",
      "custom9": "",
      "custom10": ""
    },
    "defaultPaymentID": 2002,
    "customer_payments": [
      {
        "paymentID": 2001,
        "paymenttype": "Credit Card",
        "lastfour": "4242"
      },
      {
        "paymentID": 2002,
        "paymenttype": "Checking",
        "lastfour": "6789"
      }
    ]
  }
}
POST /query/customer Create Customer
Body Parameters
{
  "x_login": "...",
  "x_tran_key": "...",
  "customer": {
    "customer_information": {
      "firstname": "Jane",
      "lastname": "Smith",
      "email": "jane@example.com",
      "phone1": "555-0123",
      "address1": "123 Main St",
      "city": "New York",
      "state": "NY",
      "zip": "10001",
      "country": "US"
    },
    "billing_information": {
      "firstname": "Jane",
      "lastname": "Smith",
      "address1": "123 Main St",
      "city": "New York",
      "state": "NY",
      "zip": "10001",
      "country": "US"
    },
    "custom": {
      "custom1": "VIP Client"
    }
  }
}
PUT /query/customer/{id} Update Customer
Update Customer Body
{
  "x_login": "...",
  "x_tran_key": "...",
  "_method": "PUT",
  "customer": {
    "customer_information": {
      "firstname": "Jane",
      "lastname": "Smith",
      "email": "jane@example.com",
      "phone1": "555-0123"
    },
    "billing_information": {
      "address1": "456 Elm St",
      "city": "New York",
      "state": "NY",
      "zip": "10001",
      "country": "US"
    },
    "custom": {
      "custom1": "VIP Client"
    },
    "customer_payments": [
      {
        "paymentID": 2002
      }
    ]
  }
}
DELETE /query/customer/{id} Delete Customer

Recurring

Create and manage recurring billing schedules through the central query handler.

Required: customer_id, payment_id, and product_id are required to create a recurring schedule.

GET /query/recurring Get All Recurring
List Query Parameters
Field Type Required Description
pageintegerNoOptional page number for recurring list results.
pageSizeintegerNoOptional page size for recurring list results.
filtersstringNoOptional filter expression.
sortstringNoOptional sort key (for example -uniqueID).
modifiersstringNoOptional comma-separated response field projection.
List Recurring Example
GET /query/recurring?page=1&pageSize=25&sort=-uniqueID
GET /query/recurring/{id} Get Single Recurring
POST /query/recurring Create Recurring
Parameters
Field Required Notes
customer_idYesCustomer for the schedule.
payment_idNoStored payment method for the customer. If omitted, uses the customer's default payment method when available; otherwise returns a failed response.
product_idYesCreates the recurring item; amount is product price + surcharge.
intervalNoOverrides product rule: 1=Day, 2=Week, 3=Month, 4=Year.
interval_numberNoOverrides product rule: interval multiplier.
run_untilNo0=Until terminated, 1=Specific date, 2=Fixed count.
run_limitNoRequired when run_until is 2.
end_dateNoRequired when run_until is 1 (YYYY-MM-DD).
run_nextNoNext run date (YYYY-MM-DD); ignored if run_transaction is true.
surchargeNoAdded to product price for total amount.
statusNo1=Active, 2=Completed, 4=Paused, 5=Terminated.
run_transactionNoWhen true, runs immediately and recalculates next run.
Sample Body (Full)
{
  "x_login": "...",
  "x_tran_key": "...",
  "recurring": {
    "customer_id": 123,
    "payment_id": 456,
    "product_id": 111,
    "run_transaction": true,
    "status": 1,
    "interval": 2,
    "interval_number": 1,
    "run_until": 2,
    "run_limit": 12,
    "end_date": null,
    "run_next": "2024-12-01",
    "surcharge": 0.00
  }
}
Sample Body (Override Schedule)
{
  "x_login": "...",
  "x_tran_key": "...",
  "recurring": {
    "customer_id": 123,
    "payment_id": 456,
    "product_id": 111,
    "interval": 2,
    "interval_number": 1,
    "run_until": 2,
    "run_limit": 12,
    "run_next": "2024-12-01",
    "surcharge": 3.50,
    "status": 1
  }
}
PUT /query/recurring/{id} Update Recurring
Parameters
Field Required Description
uniqueIDNoOptional when calling /query/recurring/{id}; otherwise required.
statusNo1=Active, 2=Completed, 4=Paused, 5=Terminated.
intervalNo1=Day, 2=Week, 3=Month, 4=Year.
interval_numberNoNumber of intervals between runs.
run_untilNo0=Until terminated, 1=Specific date, 2=Fixed count.
run_limitNoRequired when run_until is 2 (count).
end_dateNoRequired when run_until is 1 (YYYY-MM-DD).
run_nextNoNext run date (YYYY-MM-DD).
surchargeNoSurcharge amount added to product price.
payment_idNoStored payment method ID.

Note: Recurring line items cannot be updated via the update endpoint.

Sample Update Body
{
  "x_login": "...",
  "x_tran_key": "...",
  "_method": "PUT",
  "recurring": {
    "status": 1,
    "interval": 2,
    "interval_number": 1,
    "run_until": 2,
    "run_limit": 12,
    "run_next": "2024-12-08"
  }
}
DELETE /query/recurring/{id} Delete Recurring

Invoice

Create and manage invoices.

GET /query/invoice Get All Invoices
List Query Parameters
Field Type Required Description
pageintegerNoOptional page number for invoice list results.
pageSizeintegerNoOptional page size for invoice list results.
filtersstringNoOptional filter expression.
sortstringNoOptional sort key (for example -uniqueID).
modifiersstringNoOptional comma-separated response field projection.
List Invoices Example
GET /query/invoice?page=1&pageSize=25&sort=-uniqueID

Supports optional invoice filters:

Filter Description
customer_idLimit to a specific customer
statusInvoice status (e.g., Pending, Sent, Paid)
due_beforeInvoices due before date (YYYY-MM-DD)
due_afterInvoices due after date (YYYY-MM-DD)
GET /query/invoice/{id} Get Single Invoice

Returns a single invoice by unique ID. If not found, returns 404.

POST /query/invoice Create Invoice

Note: Provide customer_id to associate with an existing customer. If customer_id is omitted, include a customer object to create a new customer.

Create Invoice Body
{
  "x_login": "...",
  "x_tran_key": "...",
  "invoice": {
    "invoice_number": "INV-2024-001",
    "due_date": "2024-12-31",
    "notes": "Thank you for your business",
    "discount": 0,
    "tax": 10.50,
    "shipping": 5.00,
    "amount": 635.50,
    "customer_id": 123,
    "items": [
      {
        "title": "Web Design",
        "description": "Homepage design",
        "quantity": 1,
        "unit_price": 500.00
      },
      {
        "title": "Hosting",
        "quantity": 12,
        "unit_price": 10.00
      }
    ]
  }
}
PUT /query/invoice/{id} Update Invoice
Update Invoice Body
{
  "x_login": "...",
  "x_tran_key": "...",
  "_method": "PUT",
  "invoice": {
    "uniqueID": 456,
    "notes": "Updated notes",
    "status": "Sent"
  }
}
DELETE /query/invoice/{id} Delete Invoice
Delete Example
DELETE /query/invoice/456

Products

Manage products and services.

GET /query/product Get All Products

Returns a list of products. If none exist, returns an empty list: { "products": [] } with status 200.

Optional query parameters for GET /query/product:

  • page: page number (1-based). When provided, results are paginated.
  • pageSize: records per page. Optional; defaults to 50.
List Query Parameters
Field Type Required Description
pageintegerNoOptional page number for product list results.
pageSizeintegerNoOptional page size for product list results.
filtersstringNoOptional filter expression.
sortstringNoOptional sort key (for example -uniqueID).
modifiersstringNoOptional comma-separated response field projection.
List Products Example
GET /query/product?page=1&pageSize=25&sort=-uniqueID
GET /query/product/{id} Get Single Product
POST /query/product Create Product
Body Parameters
Field Type Required Description
namestringYesProduct name.
descriptionstringNoProduct description.
pricenumberNoProduct price.
isBookablebooleanNoMarks product as bookable.
durationintegerNoDuration in minutes (for bookable products).
is_recurringbooleanNoEnable recurring schedule; provide recurring_rule when true.
recurring_rule object Conditional Recurring schedule config; required when is_recurring is true.

Format: {"interval":"1","interval_number":"1","run_limit":"7"}.

interval: 1=Day, 2=Week, 3=Month, 4=Year.

interval_number: how many intervals between charges (e.g., 2 with interval=Week means every 2 weeks).

run_limit: number of times to run; omit or use 0 for unlimited.
Create Product Body
{
  "x_login": "...",
  "x_tran_key": "...",
  "product": {
    "name": "Premium Service",
    "description": "One hour consultation",
    "price": 99.99,
    "isBookable": true,
    "duration": 60,
    "is_recurring": true,
    "recurring_rule": {
      "interval": "1",
      "interval_number": "1",
      "run_limit": "7"
    }
  }
}
PUT /query/product/{id} Update Product
Body Parameters
Field Type Required Description
uniqueIDintegerNoOptional when calling /query/product/{id}; otherwise required.
namestringNoProduct name.
descriptionstringNoProduct description.
pricenumberNoProduct price.
isBookablebooleanNoMarks product as bookable.
durationintegerNoDuration in minutes (for bookable products).
is_recurringbooleanNoEnable recurring schedule; provide recurring_rule when true.
recurring_rule object Conditional Recurring schedule config; required when is_recurring is true.

Format: {"interval":"1","interval_number":"1","run_limit":"7"}.

interval: 1=Day, 2=Week, 3=Month, 4=Year.

interval_number: how many intervals between charges (e.g., 2 with interval=Week means every 2 weeks).

run_limit: number of times to run; omit or use 0 for unlimited.

Notes:

- Omit fields you do not want to change.

- When setting is_recurring to false, the recurring schedule is cleared.

Update Product Body
{
  "x_login": "...",
  "x_tran_key": "...",
  "_method": "PUT",
  "product": {
    "name": "Updated Service Name",
    "price": 149.99,
    "isBookable": true,
    "duration": 60,
    "is_recurring": false,
    "recurring_rule": {
      "interval": "1",
      "interval_number": "1",
      "run_limit": "7"
    }
  }
}

Coupons

Manage discount coupons.

GET /query/coupon Get All Coupons

Returns a list of coupons. If none exist, returns an empty list: { "coupons": [] } with status 200.

Optional query parameters for GET /query/coupon:

  • page: page number (1-based). When provided, results are paginated.
  • pageSize: records per page. Optional; defaults to 50.
List Query Parameters
Field Type Required Description
pageintegerNoOptional page number for coupon list results.
pageSizeintegerNoOptional page size for coupon list results.
filtersstringNoOptional filter expression.
sortstringNoOptional sort key (for example -uniqueID).
modifiersstringNoOptional comma-separated response field projection.
List Coupons Example
GET /query/coupon?page=1&pageSize=25&sort=-uniqueID
GET /query/coupon/{id} Get Single Coupon
GET /query/coupon?code={code} Get Coupon By Code
POST /query/coupon Create Coupon

Create accepts either a nested coupon object or a flat top-level payload. name is required and cannot be blank.

Body Parameters
Field Type Required Description
namestringYesCoupon name.
descriptionstringNoCoupon description.
codestringNoCoupon code customers enter.
percent_offnumberNoPercent discount (e.g., 10 for 10% off).
duration_typestringNoDiscount duration (e.g., once).
first_purchase_onlybooleanNoOnly apply to the first purchase.
max_redemptionsintegerNoMaximum number of redemptions allowed.
enabledbooleanNoEnable/disable coupon.
Create Coupon Body
{
  "x_login": "...",
  "x_tran_key": "...",
  "coupon": {
    "name": "New Customer Discount",
    "description": "10% off first purchase",
    "code": "WELCOME10",
    "percent_off": 10,
    "duration_type": "once",
    "first_purchase_only": true,
    "max_redemptions": 100,
    "enabled": true
  }
}
Create Coupon Body (Flat Payload)
{
  "x_login": "...",
  "x_tran_key": "...",
  "name": "New Customer Discount",
  "code": "WELCOME10",
  "percent_off": 10,
  "duration_type": "once",
  "first_purchase_only": true,
  "max_redemptions": 100,
  "enabled": true
}
PUT /query/coupon/{id} Update Coupon

Update accepts either a nested coupon object or a flat top-level payload. uniqueID is optional when calling /query/coupon/{id}, and required for non-path updates.

Body Parameters
Field Type Required Description
uniqueIDintegerNoOptional when calling /query/coupon/{id}; otherwise required.
namestringNoCoupon name.
descriptionstringNoCoupon description.
codestringNoCoupon code customers enter.
percent_offnumberNoPercent discount.
duration_typestringNoDiscount duration.
first_purchase_onlybooleanNoOnly apply to the first purchase.
max_redemptionsintegerNoMaximum number of redemptions allowed.
enabledbooleanNoEnable/disable coupon.
Update Coupon Body
{
  "x_login": "...",
  "x_tran_key": "...",
  "_method": "PUT",
  "coupon": {
    "name": "Updated Coupon Name",
    "percent_off": 15,
    "enabled": true
  }
}
DELETE /query/coupon/{id} Delete Coupon
Delete Coupon Example
DELETE /query/coupon/123

Card Issuing

Issue and manage cards via the central query handler. Primary-account endpoints require merchant authentication; the cardholder list-cards endpoint uses cardholder credentials in the body.

Two request sections:

  • Primary Account: Operates on subaccounts using Primary Account API credentials.
  • User: Cardholder actions using Primary Account API credentials, plus cardholder username/password in body.
Primary Account Endpoints
GET /query/expicard List Cards (Primary account)

Optional filters: search, type (virtual|physical), status.

List Cards Example
GET /query/expicard
GET /query/expicard?uniqueID={CARD_ID} Get Card Details (Primary account)

Returns full details (including PAN/CVC) for authorized merchant/enhanced users. The response includes card.id (the requested card ID) and card.token (partner token).

Get Card Details Example
GET /query/expicard?uniqueID=CARD-12345
GET /query/expicard?subaction=summary&uniqueID={CARD_ID} Get Card Summary (Primary account)

Lightweight, cached card summary without sensitive details; falls back to full read if unavailable. Includes card.id (requested card ID) and card.token (partner token).

Get Card Summary Example
GET /query/expicard?subaction=summary&uniqueID=CARD-12345
POST /query Issue Card (Primary account)

Body fields: first_name, last_name, email, amount, address_line1, city, state, zip, type (virtual|physical), cardholder_type (team_member|vendor|contractor), optional external_id.

Issue Card Body
{
  "action": "expicard",
  "subaction": "create",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane@example.com",
  "password": "TempPassword123",
  "amount": 200.00,
  "address_line1": "123 Main St",
  "city": "Austin",
  "state": "TX",
  "zip": "78701",
  "type": "virtual",
  "cardholder_type": "team_member",
  "external_id": "CARD-EXT-001"
}
POST /query Fund Card (Primary account)
Fund Card Body
{
  "action": "expicard",
  "subaction": "fund",
  "uniqueID": "CARD-67890",
  "amount": 50.00
}
GET /query/expicard?subaction=transactions&uniqueID={CARD_ID} Get Transactions (Primary account)

Optional filters supported: from, to, status.

Transactions Example
GET /query/expicard?subaction=transactions&uniqueID=CARD-12345&from=2025-10-01&to=2025-10-31&status=approved
POST /query Create Funding Bank (Subaccount)

Creates a funding bank (bank account) for a specific subaccount.

Body fields: subaccountId, bankAccountNumber, bankRoutingNumber. Additional fields may be included per partner requirements.

Note: The query handler lowercases top-level JSON keys. To avoid casing issues, you can send snake_case keys (bank_account_number, bank_routing_number) or nest fields under a bank object.

Create Funding Bank Body
{
  "action": "expicard",
  "subaction": "subaccount_bank_create",
  "subaccountId": "SUB-123456",
  "bank_account_number": "1234567890",
  "bank_routing_number": "021000021"
}

Note: Sensitive card detail fields are only returned to authorized merchant/enhanced users; summaries are optimized for portal views.

User Endpoints

These endpoints do not require merchant authentication. They use merchant API credentials for partner access internally, but require cardholder username and password in the request body.

GET /query/expicard?role=user&subaction=user_cards List Cards (User)

Response: Returns full card details for the authenticated cardholder, including sensitive fields such as full card number (PAN), CVC, and expiration. Handle this response securely.

Authentication: You can provide the cardholder username/password either in the body or via HTTP Basic Auth (recommended). When using Basic Auth, the body credentials are optional.

User Auth Header
Authorization: Basic <base64(cardholder_username:cardholder_password)>
User Body
{
  "action": "expicard",
  "role": "user",
  "subaction": "user_cards",
  "username": "cardholder@example.com",
  "password": "cardholderPassword"
}

Note: User endpoints restrict access to cards linked to the authenticated cardholder; sensitive fields are not returned.