StableX Complete API Reference
Use the On this page menu on the right to jump to any section.1. API Overview
1.1 GraphQL Endpoint
1.2 Headers
1.3 Request Format
2. Authentication
2.1 Unified Login (Recommended)
Automatically detects if user is a Merchant or Staff member. Permissions: None (public) Request:2.2 Merchant Login (Legacy)
Permissions: None (public) Request:2.3 Staff Login (Legacy)
Permissions: None (public) Request:2.4 Refresh Token
Get a new access token without re-entering credentials. Permissions: None (public, but requires valid refresh token) Request:2.5 Request Password Reset
Permissions: None (public) Request:2.6 Reset Password
Permissions: None (public, but requires valid token) Request:2.7 Get Current User (Me)
Permissions: Requires authentication Request:3. Merchant Operations
3.1 Create Merchant (Sign Up)
Permissions: None (public) Request:3.2 Update Merchant Profile
Permissions:merchant.profile.manage (Merchant only)
Request:
3.3 Merchant Account Number
Every merchant is automatically assigned a unique 16-digit account number upon creation. Format:9891 + 12 random digits
Example: 9891123456789012
Features:
- Automatically Generated: Created when a merchant signs up
- Unique: Enforced by database constraint
- Immutable: Cannot be changed after creation
- Format Validation: Checked via database constraint (
^9891[0-9]{12}$)
- Merchant identification
- Account reconciliation
- Integration with external systems
- Customer invoicing
4. Staff Management
4.1 Create Staff
Permissions:staff.manage (Merchant or Manager with staff.manage permission)
Request:
Note: ThemerchantIdparameter is optional:
- If omitted, the merchant ID is automatically inferred from the authenticated user (works for both Merchant and Staff users)
- If provided, it must match the authenticated user’s merchant ID (staff cannot create users for other merchants)
- Can be passed as either a string (
"1") or number (1) - both are accepted
4.2 List Staff
Permissions:staff.list
Request:
4.3 Update Staff
Permissions:staff.manage
Request:
4.4 Deactivate Staff
Permissions:staff.manage
Request:
4.5 Assign Role to Staff
Permissions:staff.manage
Request:
4.6 Get Merchant Info for Staff
Permissions: Requires authentication Request:5. Payment Operations
5.1 Create Payment
Permissions:payment.create
Request:
5.2 Regenerate Payment
Permissions:payment.create
Request:
5.3 Create Payment Link
Creates a shareable payment link: a pending transaction, invoice, and a unique slug. The returnedurl is the public checkout URL (e.g. https://your-domain.com/pay/<slug>). No authentication is required for customers to open that URL and pay.
Permissions: payment.create
Request:
- url: Public URL to share with the customer. Opening it returns checkout JSON (see 5.4).
- slug: Unique identifier for the link (also used in
url). - expiresInHours: Optional. If set, the link is considered expired after that many hours.
5.4 Get Payment Link Checkout (Public)
Authentication: None (public endpoint for customers). Returns JSON for the checkout UI: merchant name, amount, token, network, payment URL (for QR / Solana Pay), and transaction reference. Used when a customer opens a payment link (e.g.https://your-domain.com/pay/<slug>).
Endpoint:
- payment_url: Use this for QR code or “Pay with Solana” / wallet deep link.
- transaction_reference: Use with
transactionStatus(reference: ...)to poll for confirmation.
- 404: Payment link not found, expired, or already used (transaction confirmed).
6. Transaction & Reporting
6.1 List Transactions
Permissions:transaction.view
Request:
6.2 Transaction Status
Permissions:transaction.view
Request:
6.3 Daily Summary
Permissions:report.view
Request:
6.4 Sales Summary Report
Permissions:report.view
Request:
6.5 Sales Analytics
Permissions:report.view
Request:
6.6 Sales By Hour
Permissions:report.view
Request:
6.7 PDF Downloads (Invoices & Receipts)
StableX provides two types of PDF documents:- Invoices: For pending/unpaid transactions (blue header, red “PAYMENT PENDING” stamp)
- Receipts: For confirmed/paid transactions (green header, green “PAID” stamp)
6.7.1 Get Invoice Info (GraphQL)
Get the download URL and QR code for an invoice PDF. Permissions: Authenticated (merchant or staff) Request:6.7.2 Get Receipt Info (GraphQL)
Get the download URL and QR code for a receipt PDF. Permissions: Authenticated (merchant or staff) Request:6.7.3 Download Invoice PDF (REST API)
Download the invoice PDF directly. Endpoint:GET /invoices/{transaction_reference}/download
Authentication: Bearer token required
Request:
200 OK: PDF generated successfully404 Not Found: Transaction not found401 Unauthorized: Invalid or missing token500 Internal Server Error: PDF generation failed
6.7.4 Download Receipt PDF (REST API)
Download the receipt PDF directly (only for confirmed transactions). Endpoint:GET /receipts/{transaction_reference}/download
Authentication: Bearer token required
Request:
200 OK: PDF generated successfully404 Not Found: Transaction not found or not confirmed401 Unauthorized: Invalid or missing token500 Internal Server Error: PDF generation failed
confirmed. For pending transactions, use the invoice endpoint instead.
6.7.5 Invoice Query with Transaction Reference
When querying invoices, include the transaction relationship to get the reference needed for PDF downloads. Invoices can be in lifecycle states:draft, sent, pending, paid, overdue, or void. Draft and sent invoices may have transaction_id: null until the customer pays.
Request:
transaction.reference to construct the download URL:
6.8 Invoice Lifecycle (Draft, Send, Remind)
Invoices support a full lifecycle: create as draft, send to the customer (email + payment link), then paid when the customer pays. Optional overdue status and reminders are supported. Invoice statuses:draft | sent | pending | paid | overdue | void
- draft: Created without a transaction; can be updated.
- sent: Payment link created and (optionally) email sent;
transaction_idandsent_atset. - pending: Legacy: invoice tied to a transaction not yet confirmed.
- paid: Payment confirmed;
payment_dateset. - overdue:
due_datehas passed and status wassent. - void: Cancelled.
6.8.1 Create Invoice (Draft)
Create an invoice in draft state with no transaction. Optionally include line items, due date, and customer email (required later for sending). Permissions: Authenticated (merchant or staff) Request:InvoiceLineItemInput:
| Field | Type | Required | Description |
|---|---|---|---|
| description | String! | Yes | Line item description |
| quantity | Decimal! | Yes | Quantity |
| unit_amount | Decimal! | Yes | Price per unit |
| amount | Decimal! | Yes | Total (e.g. quantity × unit) |
| productId | ID | No | Optional link to product |
6.8.2 Update Invoice (Draft Only)
Update a draft invoice: amount, tax, description, due date, customer email, and/or line items. ReplacinglineItems overwrites all existing line items.
Permissions: Authenticated (merchant or staff)
Request:
Invoice object. If the invoice is not in draft status, an error is returned.
6.8.3 Send Invoice
Moves an invoice from draft to sent: creates a pending transaction and payment link, setssent_at, and optionally sends an email to customer_email with the payment URL. The customer can open the link to pay; when payment is confirmed, the invoice is marked paid.
Permissions: Authenticated (merchant or staff)
Requirements: Invoice must be draft and have customer_email set. You must have a wallet for the given blockchain.
Request:
urlis the public payment link; share it or rely on the email sent tocustomer_email.- If the email fails, the invoice is still marked sent and the mutation succeeds; the
urlcan be shared manually.
6.8.4 Send Invoice Reminder
Sends a reminder email for an invoice in sent or overdue status and setslast_reminder_at. The email includes the same payment link as when the invoice was sent.
Permissions: Authenticated (merchant or staff)
Request:
sent or overdue and have customer_email; the invoice must have an associated payment link (transaction).
6.8.5 Sync Invoice Status
Manually sync an invoice’s status with its linked transaction (e.g. after payment confirmation). Useful if automatic status updates did not run. The invoice must already have atransaction_id (e.g. created via sendInvoice or a payment link).
Permissions: Authenticated (merchant or staff)
Request:
Invoice. If the linked transaction is confirmed on-chain, the invoice is updated to paid and payment_date is set.
7. Wallet Management
7.1 Add or Update Wallet
Permissions:wallet.manage
Request:
7.2 Remove Wallet
Permissions:wallet.manage
Request:
7.3 Wallet Balances
Permissions:wallet.view
Request:
7.4 Token Balances
Permissions:wallet.view
Request:
8. Customer Management
8.1 List Customers
Permissions:customer.view
Request:
8.2 Upsert Customer
Permissions:customer.manage
Request:
9. Error Handling
9.1 Error Response Format
9.2 Standard Error Codes
| Code | HTTP Status | Description | Action |
|---|---|---|---|
NOT_AUTHENTICATED | 401 | Missing or invalid token | Redirect to login |
PERMISSION_DENIED | 403 | User lacks required permission | Show access denied message |
INVALID_CREDENTIALS | 401 | Wrong email/password | Show login error |
TOKEN_EXPIRED | 401 | Access token expired | Call refreshToken |
TOKEN_REVOKED | 401 | Refresh token revoked | Redirect to login |
RECORD_NOT_FOUND | 404 | Resource doesn’t exist | Show 404 state |
VALIDATION_ERROR | 400 | Invalid input data | Show validation errors |
INTERNAL_ERROR | 500 | Server error | Show generic error |
9.3 Common Error Scenarios
1. Expired TokenrefreshToken mutation or redirect to login
2. Permission Denied
10. Refund Operations
10.1 Create Refund Request
Permissions:refund.create (Staff Manager)
Request:
10.2 Approve Refund
Permissions:refund.approve (Staff Manager)
Request:
10.3 Reject Refund
Permissions:refund.reject (Staff Manager)
Request:
10.4 Complete Refund
Permissions:refund.complete (Merchant)
Request:
10.5 List Refunds
Permissions:refund.view (Staff Manager)
Request:
10.6 Get Refund by Reference
Permissions:refund.view (Staff Manager)
Request:
10.7 Get Refund Summary
Permissions:refund.view (Staff Manager)
Request:
11. Product & Price Management
11.1 List Products
Permissions:product.view
Request:
Note: Theactivefilter can be used to show only active or inactive products. Thecategoryfilter allows filtering by product category. Pagination is supported vialimitandoffsetparameters.
11.2 Get Product by ID
Permissions:product.view
Request:
11.3 Get Product by SKU
Permissions:product.view
Request:
Note: SKU must be unique per merchant. If a product with the given SKU is not found, an error will be returned.
11.4 Get Product Prices
Permissions:product.view
Request:
11.5 Create Product
Permissions:product.manage
Request:
Note: Thenamefield is required. All other fields are optional. Theskumust be unique per merchant. If a product with the same SKU already exists, an error will be returned.
11.6 Update Product
Permissions:product.manage
Request:
Note: Only theidfield is required. All other fields are optional and will only be updated if provided. If updating thesku, it must remain unique per merchant.
11.7 Delete Product
Permissions:product.manage
Request:
Note: This performs a soft delete by setting active=false. The product record remains in the database but is marked as inactive.
11.8 Archive Product
Permissions:product.manage
Request:
Note: Archiving a product sets the archivedAt timestamp. Archived products can be filtered out in queries and can be unarchived later.
11.9 Unarchive Product
Permissions:product.manage
Request:
Note: Unarchiving a product clears the archivedAt timestamp, making the product available again.
11.10 Create Price
Permissions:product.manage
Request:
Note:
- Required fields:
productId,amount,currency,type- For
RECURRINGprices,billingPeriodis required (e.g., “month”, “year”)- For
PAY_WHAT_YOU_WANTpricing,minAmountand/ormaxAmountmust be providedtrialPeriodDaysis only allowed forRECURRINGprices- For usage-based pricing (
usageType: METERED),unitLabelis requiredamountmust be greater than 0currencymust be a 3-character code (e.g., “USD”, “EUR”)
11.11 Update Price
Permissions:product.manage
Request:
Note: Only the id field is required. All other fields are optional and will only be updated if provided. The same validation rules apply as for creating prices (e.g., trial period only for recurring prices).
11.12 Delete Price
Permissions:product.manage
Request:
Note: This performs a hard delete, permanently removing the price from the database.
Permission Matrix
| Endpoint | Merchant | Manager (Staff) | Cashier (Staff) |
|---|---|---|---|
login | ✅ | ✅ | ✅ |
createMerchant | ✅ | ❌ | ❌ |
createPayment | ✅ | ✅ | ✅ |
transactions | ✅ | ✅ | ✅ |
salesSummaryReport | ✅ | ✅ | ❌ |
addOrUpdateWallet | ✅ | ❌ | ❌ |
createStaff | ✅ | ❌ | ❌ |
customers | ✅ | ✅ | ❌ |
upsertCustomer | ✅ | ✅ | ❌ |
createRefundRequest | ❌ | ✅ | ❌ |
approveRefund | ❌ | ✅ | ❌ |
rejectRefund | ❌ | ✅ | ❌ |
completeRefund | ✅ | ❌ | ❌ |
refunds | ❌ | ✅ | ❌ |
refundByReference | ❌ | ✅ | ❌ |
refundSummary | ❌ | ✅ | ❌ |
products | ✅ | ✅ | ✅ |
product | ✅ | ✅ | ✅ |
productBySku | ✅ | ✅ | ✅ |
productPrices | ✅ | ✅ | ✅ |
createProduct | ✅ | ❌ | ❌ |
updateProduct | ✅ | ❌ | ❌ |
deleteProduct | ✅ | ❌ | ❌ |
archiveProduct | ✅ | ❌ | ❌ |
unarchiveProduct | ✅ | ❌ | ❌ |
createPrice | ✅ | ❌ | ❌ |
updatePrice | ✅ | ❌ | ❌ |
deletePrice | ✅ | ❌ | ❌ |
Quick Start Example (cURL)
This API reference covers all available endpoints in the StableX platform. For any questions or issues, please contact the development team.
