Authentication
Finix uses two authentication schemes. Use the right one depending on which endpoint group you are calling.
Project API Key X-API-Key
Used for server-to-server integration: payment sessions, wallet creation, transaction queries, reports. Create keys from your dashboard → API Keys.
# Recommended X-API-Key: fp_live_your_key # Also accepted Authorization: Bearer fp_live_your_key
Customer Bearer Token Bearer
Used for the customer-facing dashboard: account info, API key management, data views. Obtained via POST /customer/login.
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI...
Rate Limits
Exceeded limits return 429 Too Many Requests with a Retry-After header. API-key-authenticated routes are keyed per API key, not per IP.
| Scope | Key | Limit | Window |
|---|---|---|---|
| All /api/* routes | API key or IP | 200 requests | 15 min |
| GET/POST /payments/* | API key | 300 requests | 15 min |
| POST /payments/create | API key | 60 requests | 15 min |
| POST/DELETE /customer/api-keys | Customer email | 20 operations | 60 min |
| POST /customer/login | IP | 20 attempts | 15 min |
| POST /customer/register | IP | 20 attempts | 15 min |
Error Responses
All errors share a consistent JSON envelope:
{
"error": "Unauthorized", // machine-readable type
"message": "API key is required" // human-readable detail
}| Status | error value | Typical cause |
|---|---|---|
| 400 | Bad request · Validation failed | Missing or invalid request fields |
| 401 | Unauthorized | Missing, expired, or invalid API key / bearer token |
| 403 | Forbidden | Authenticated but not allowed to access the resource |
| 404 | Not found | Resource does not exist or does not belong to this project |
| 409 | Conflict | Duplicate order_id with an already-active payment session |
| 429 | Too many requests | Rate limit exceeded (see Retry-After header) |
| 502 | Bad gateway | Upstream Identity service unreachable or returned an error |
| 500 | Internal server error | Unexpected server-side failure |
Customer — Auth
Public endpoints. No authentication required. Rate-limited to 20 req / 15 min per IP.
/api/v1/customer/registerCreate a new customer account. Proxies to the Identity service and returns an access token.
| Field | Type | Description | |
|---|---|---|---|
| name | string | required | Full name |
| string | required | Email address (unique) | |
| password | string | required | Minimum 8 characters |
Request
curl -X POST "/api/v1/customer/register" \
-H "Content-Type: application/json" \
-d '{
"name": "Alice Smith",
"email": "alice@example.com",
"password": "SecurePass123"
}'Response 201
{
"success": true,
"message": "Registration successful",
"token": "eyJhbGci...",
"user": {
"email": "alice@example.com",
"name": "Alice Smith",
"status": "active"
}
}/api/v1/customer/loginAuthenticate and receive a Bearer token for subsequent dashboard API calls.
| Field | Type | Description | |
|---|---|---|---|
| string | required | Registered email | |
| password | string | required | Account password |
Request
curl -X POST "/api/v1/customer/login" \
-H "Content-Type: application/json" \
-d '{"email":"alice@example.com","password":"SecurePass123"}'Response 200
{
"success": true,
"token": "eyJhbGci...",
"user": {
"email": "alice@example.com",
"name": "Alice Smith",
"status": "active"
}
}Customer — Account & Profile
All endpoints require Authorization: Bearer <token>.
/api/v1/customer/meReturns the authenticated customer's basic identity (email, name, profile object).
/api/v1/customer/profileReturns the full Identity-service profile object.
/api/v1/customer/profileUpdate profile fields. All fields are optional.
| Field | Type | Description |
|---|---|---|
| firstName | string | First name |
| lastName | string | Last name |
| phoneNumber | string | Phone number |
| company | string | Company / organization name |
| position | string | Job title |
| country | string | Country code (e.g. IR) |
| city | string | City |
| bio | string | Short biography |
| dateOfBirth | ISO date | Date of birth |
| profileImage | string (URL) | Avatar image URL |
/api/v1/customer/projectReturns (or auto-provisions) the Finix project linked to this account. Created automatically on first access.
// Response 200
{
"project": {
"id": "65f1a2b3c4d5e6f7a8b9c0d1",
"slug": "customer-alice",
"name": "alice@example.com",
"status": "active",
"has_legacy_api_key": false,
"api_keys_count": 2,
"created_at": "2026-03-01T10:00:00.000Z"
}
}Customer — API Keys
Create and manage project API keys used for server-to-server payment integration. All require Authorization: Bearer <token>. Create/revoke: limited to 20 per hour per account.
/api/v1/customer/api-keysList all API keys for the customer's project (active and revoked).
// Response 200
{
"project": { "id": "...", "slug": "customer-alice", "name": "Alice Smith" },
"api_keys": [
{
"id": "65f1a2b3...",
"name": "Production Server",
"key_prefix": "fp_live_prod",
"status": "active",
"created_at": "2026-03-01T10:00:00.000Z",
"last_used_at": "2026-03-11T08:30:00.000Z",
"revoked_at": null
}
]
}/api/v1/customer/api-keysCreate a new API key. The full plaintext key is returned once — copy it immediately.
| Field | Type | Description | |
|---|---|---|---|
| name | string | required | Descriptive label (2–100 chars), e.g. "Production Server" |
Request
curl -X POST "/api/v1/customer/api-keys" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"name":"Production Server"}'Response 201
{
"success": true,
"message": "API key created successfully",
"api_key": "fp_live_abc123xyz...", // save this!
"key": {
"id": "65f1a2b3...",
"name": "Production Server",
"key_prefix": "fp_live_abc1",
"status": "active",
"created_at": "2026-03-11T10:00:00.000Z"
}
}/api/v1/customer/api-keys/:keyIdPermanently revoke an API key. Invalidated immediately with no grace period.
// Response 200
{ "success": true, "message": "API key revoked successfully" }Customer — Dashboard & Data
All require Authorization: Bearer <token>. Data is scoped to the authenticated customer's project.
/api/v1/customer/dashboardOverview stats and the 10 most recent transactions.
// Response 200
{
"stats": {
"wallets": 5, "active_wallets": 4,
"total_transactions": 128, "confirmed_transactions": 120
},
"recent_transactions": [ { "tx_hash": "abc...", "amount": "100000000", "status": "confirmed" } ]
}/api/v1/customer/walletsReturns up to 100 wallets assigned to the project (newest first). Fields: address, status, balance_snapshot, created_at, metadata.
/api/v1/customer/transactionsPaginated transaction list.
| Query param | Type | Default | Description |
|---|---|---|---|
| page | integer | 1 | Page number |
| limit | integer | 20 | Items per page (max 100) |
| status | string | — | pending · confirmed · failed |
/api/v1/customer/reportsAggregated transaction counts grouped by status and type.
// Response 200
{
"by_status": [ { "_id": "confirmed", "count": 120 }, { "_id": "pending", "count": 8 } ],
"by_type": [ { "_id": "receive", "count": 95 }, { "_id": "settlement", "count": 33 } ]
}Customer — Payments (Bearer)
Inspect payment sessions from the dashboard. For server-to-server creation, use the Project API Key endpoints instead. All require Authorization: Bearer <token>.
/api/v1/customer/payments/createCreate a payment session on the customer's project. Accepts the same body as POST /payments/create. Rate-limited to 60 per 15 min.
/api/v1/customer/paymentsList payment sessions. Accepts order_id, user_id, status, limit, offset query params.
/api/v1/customer/payments/:paymentIdRetrieve a single payment session by its Finix ID or order_id.
Customer — Webhook Settings & Logs
Manage webhook URL/secret and inspect delivery attempts. All require Authorization: Bearer <token>.
/api/v1/customer/settings/webhookRead current webhook settings for the authenticated customer's project.
// Response 200
{
"webhook_url": "https://example.com/finix/webhooks",
"has_secret": true
}/api/v1/customer/settings/webhookSet webhook URL and optionally rotate or clear webhook secret.
| Field | Type | Description | |
|---|---|---|---|
| webhook_url | string (URL) | optional | HTTP/HTTPS destination URL. Empty string disables webhook URL. |
| webhook_secret | string | optional | New signing secret (16-128 chars). Provide only when rotating. |
| clear_secret | boolean | optional | When true and webhook_secret is omitted, remove stored secret. |
// Response 200
{
"success": true,
"message": "Webhook settings updated successfully",
"webhook_url": "https://example.com/finix/webhooks",
"has_secret": true
}/api/v1/customer/settings/webhook/testSend a test webhook to the configured URL. Returns delivery status and latency.
// Response 200
{
"success": true,
"message": "Test webhook delivered",
"delivery": {
"url": "https://example.com/finix/webhooks",
"status": 200,
"latency_ms": 124,
"test_id": "2f8b5d89-8a1d-4a16-8917-4fa6eb6a9c29",
"signed": true
}
}/api/v1/customer/settings/webhook/deliveriesPaginated webhook delivery logs including attempts, response status, retry schedule, and dead-letter reason.
| Query param | Type | Default | Description |
|---|---|---|---|
| status | string | — | pending · failed · delivered · dead_letter |
| event | string | — | Filter by webhook event name (e.g. payment_confirmed) |
| page | integer | 1 | Page number |
| limit | integer | 20 | Items per page (max 100) |
// Response 200
{
"deliveries": [
{
"_id": "67f1a2b3c4d5e6f7a8b9c0d1",
"event": "payment_confirmed",
"tx_hash": "a1b2c3...",
"status": "dead_letter",
"attempts_count": 5,
"max_attempts": 5,
"next_retry_at": null,
"last_status_code": 500,
"last_error": "HTTP 500",
"dead_letter_reason": "Max attempts reached (5)",
"attempts": []
}
],
"pagination": { "page": 1, "limit": 20, "total": 1, "totalPages": 1 }
}/api/v1/customer/settings/webhook/deliveries/:id/retryQueue an immediate retry for a failed or dead-letter delivery. Useful after fixing endpoint or firewall issues.
// Response 200
{
"success": true,
"message": "Webhook delivery queued for retry",
"delivery": {
"id": "67f1a2b3c4d5e6f7a8b9c0d1",
"status": "failed",
"next_retry_at": "2026-04-07T10:12:35.000Z"
}
}Payments API — X-API-Key
Server-to-server payment session management. Authenticate with X-API-Key. Rate limit: 300 req/15min (60 for create).
/api/v1/payments/createAssign a wallet to an order and open a payment session. Idempotent on order_id — returns existing active session with "existing": true if called again.
| Field | Type | Description | |
|---|---|---|---|
| order_id | string | required | Your unique order identifier (max 128 chars) |
| user_id | string | required | Your end-user identifier |
| amount | number | required | Amount for selected network (e.g. 100.50). Must be > 0 |
| network | string | required | One of TRC20 or BTC |
| expires_in_minutes | integer | optional | Session TTL in minutes (5–1440). Default: 360 |
| metadata | object | optional | Arbitrary key-value data stored on the session and included in webhooks |
Request
curl -X POST "/api/v1/payments/create" \
-H "X-API-Key: fp_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"order_id": "order_98765",
"user_id": "user_123",
"amount": 100,
"network": "BTC",
"expires_in_minutes": 30,
"metadata": { "plan": "pro" }
}'Response 201
{
"id": "65f1a2b3c4d5e6f7...",
"order_id": "order_98765",
"user_id": "user_123",
"project": "your-project-slug",
"wallet_address": "TRxAbcDef123...",
"network": "BTC",
"currency": "BTC",
"amount": 100,
"amount_raw": "100000000",
"status": "assigned",
"assigned_at": "2026-03-11T10:00:00.000Z",
"expires_at": "2026-03-11T10:30:00.000Z",
"existing": false
}assigned → pending_onchain → paid_unconfirmed → confirmed
| failure paths: expired · underpaid · overpaid · failed
/api/v1/payments/:payment_idRetrieve a payment session. :payment_id can be the Finix session ObjectId or the original order_id.
# By session ID: curl "/api/v1/payments/65f1a2b3c4d5e6f7" -H "X-API-Key: fp_live_your_key" # By order_id: curl "/api/v1/payments/order_98765" -H "X-API-Key: fp_live_your_key"
/api/v1/paymentsPaginated list of payment sessions for the authenticated project.
| Query param | Type | Description |
|---|---|---|
| order_id | string | Filter by order ID |
| user_id | string | Filter by user ID |
| status | string | assigned · pending_onchain · paid_unconfirmed · confirmed · expired · underpaid · overpaid · failed |
| limit | integer | Max 100 (default 20) |
| offset | integer | Pagination offset (default 0) |
Wallets API — X-API-Key
Create and query TRON TRC20 deposit wallets. Each wallet is BIP44-derived from the project HD seed and permanently linked to one (project, user email) pair.
/api/v1/wallets/createCreate (or return existing) deposit wallet for a user. Idempotent — safe to call multiple times.
| Field | Type | Description | |
|---|---|---|---|
| project | string | required | Project slug |
| string | required | End-user email address | |
| display_name | string | optional | Human-readable user label |
Request
curl -X POST "/api/v1/wallets/create" \
-H "X-API-Key: fp_live_your_key" \
-H "Content-Type: application/json" \
-d '{"project":"your-slug","email":"bob@example.com"}'Response 201
{
"address": "TRxAbcDef123...",
"project": "your-slug",
"email": "bob@example.com",
"derivation_path": "m/44'/195'/0'/0/5",
"created_at": "2026-03-11T10:00:00.000Z",
"existing": false
}/api/v1/wallets/:project/:emailLook up a specific user's wallet within a project. Returns 404 if no wallet exists for this user.
/api/v1/wallets/project/:projectList all wallets in a project. Supports ?limit (max 100, default 50) and ?offset.
Transactions API — X-API-Key
Query on-chain transactions detected and confirmed by the Finix blockchain watcher. Amounts are returned as both raw smallest-unit strings and formatted display values.
/api/v1/transactionsPaginated and filterable transaction list. Scoped to the authenticated project.
| Query param | Type | Description |
|---|---|---|
| string | Filter by user email | |
| address | string | Filter by wallet address (from or to) |
| type | string | receive · settlement |
| status | string | pending · confirmed · failed |
| date_from | ISO 8601 | Start of date range (inclusive) |
| date_to | ISO 8601 | End of date range (inclusive) |
| limit | integer | Max 100 (default 50) |
| offset | integer | Pagination offset |
/api/v1/transactions/:tx_hashLook up a transaction by its TRON blockchain hash. Returns 404 if not recorded in Finix.
/api/v1/transactions/reconcile/submit-txManually submit a transaction hash for reconciliation if the watcher missed it.
| Field | Type | Description | |
|---|---|---|---|
| tx_hash | string | required | 64-character TRON transaction hash |
Reports API — X-API-Key
Aggregated analytics for financial reporting and reconciliation.
/api/v1/reports/dailyDaily transaction volume and counts. Defaults to today (UTC).
| Query param | Type | Description |
|---|---|---|
| date | ISO 8601 date | Target date (e.g. 2026-03-11). Defaults to today. |
/api/v1/reports/monthlyMonthly rollup of transaction volume and counts.
| Query param | Type | Description |
|---|---|---|
| year | integer | 4-digit year (default: current year) |
| month | integer | Month 1–12 (default: current month) |
System
/health
(no auth required)
Liveness / readiness probe. Safe to poll from load balancers.
// Response 200
{
"status": "OK",
"timestamp": "2026-03-11T10:00:00.000Z",
"uptime": 84200.5,
"environment": "production"
}/api/v1/testConfirms routes are loaded. Returns a JSON timestamp.
Webhooks
When transactions are detected or confirmed, Finix POSTs a JSON event to the webhook_url configured on the project. Deliveries use retries with exponential backoff and become dead_letter after max attempts.
Events
-
payment_detectedTransfer seen on-chain, awaiting confirmations. Session moves to
paid_unconfirmed. -
payment_confirmedTransfer fully confirmed. Session moves to
confirmed. Safe to release goods/services.
Payload
{
"event": "payment_confirmed",
"project": "your-project-slug",
"transaction": {
"tx_hash": "abc123...",
"amount": "100000000",
"amount_formatted": "100.0",
"token": "USDT",
"status": "confirmed",
"confirmations": 20
},
"payment_session": {
"id": "65f1a2b3...",
"order_id": "order_98765",
"user_id": "user_123",
"status": "confirmed",
"metadata": { "plan": "pro" }
}
}X-Finix-Signature HMAC header and matching the project field to your known project slug before releasing goods or services.
dead_letter. Use customer endpoints under Webhook Settings & Logs for visibility and manual retries.