API Sandbox
Sandbox API is used for partner test integrations. It lets you walk through the full loan journey: calculate terms, receive a test BTC collateral address, confirm collateral, complete a payout simulation, accept USDT repayment, and return collateral. Sandbox does not perform real blockchain transfers: addresses are test addresses, and credits are confirmed by API actions such as confirm_btc and confirm_usdt.
Base URL: https://partner.fundora.capital. Authorization: Authorization: Bearer sk_sandbox_YOUR_KEY. All POST requests require Idempotency-Key. Rate limit: 120 requests per 60 seconds per Sandbox API key.
Sandbox OpenAPI
Use Sandbox OpenAPI for the full generated API catalog with request parameters, request bodies, schemas, and response blocks by HTTP status code (200, 400, 401, 404, 409, 429, and 500 where applicable).
The machine-readable OpenAPI file is available as fundora-sandbox-api.openapi.json.
How Sandbox Works
Sandbox mirrors the main Fundora borrower dashboard flow without real transfers. The partner calls API methods step by step and receives state that can be shown in the partner interface.
- Get configuration: rates, FX, limits, fees, and risk parameters.
- Create a test loan application and receive addresses needed for the flow.
- Instead of waiting for a blockchain event, send a confirming API action.
- After payout, read the loan state and start repayment.
- After full repayment, the API shows the collateral return step.
Steps cannot be executed in arbitrary order. If an action is sent too early, the API returns 409 FLOW_CONFLICT. In that case, call GET State, inspect the current step, and continue from there.
Quick Start
- Get a Sandbox API key in the Fundora partner dashboard.
- Call GET Config to load rates, FX, fees, and calculator limits.
- Call GET State to check whether the key already has an active application or loan.
- Create an application through POST Loans with
action=start_collateral_transfer. - Continue the flow through POST Loans, changing
actionto the next allowed step. - After payout, read the loan through GET Loans or GET State.
- Start repayment through POST Repayments.
- Configure Webhooks if your backend needs push events instead of polling.
curl https://partner.fundora.capital/api/sandbox/config \
-H "Authorization: Bearer sk_sandbox_YOUR_KEY"
Environment and Rules
| Parameter | Value |
|---|---|
| Base URL | https://partner.fundora.capital |
| Partner Dashboard | partner.fundora.capital |
| Environment | Sandbox, no real blockchain transfers |
| API description version | 0.3.0 |
| Authorization | Authorization: Bearer sk_sandbox_YOUR_KEY |
| POST requests | Always send Idempotency-Key |
| Rate limit | 120 requests per 60 seconds per Sandbox API key |
| Request log | request_id, error_code, and Idempotency-Key are visible in the partner dashboard |
Breaking changes will be released as a new API description version and announced separately to partners. During testing, the URL remains /api/sandbox/*.
Test Wallets
The API returns wallet data in sandboxFlow. These are not real custody wallets: isRealWallet=false, network is sandbox, and confirmation is done through the API.
For a loan application, wallets are located in sandboxFlow.loanApplications[].wallets.
| Field | Asset | Purpose |
|---|---|---|
collateralDeposit | BTC | Address shown to the client for the test collateral transfer. |
loanPayout | USDT | Test wallet for the USDT payout scenario. |
collateralReturn | BTC | Address used in the future collateral return scenario. |
For repayment, wallets are located in sandboxFlow.repaymentOperations[].wallets.
| Field | Asset | Purpose |
|---|---|---|
repayment | USDT | Address for test interest, partial principal, or full principal repayment. |
collateralReturn | BTC | Collateral return address after full repayment. It can be null for interest-only or partial repayments. |
Each wallet contains asset, chainCode, address, requiredConfirmations, isRealWallet, and confirmationMode.
Loan Scenario from Application to Payout
| Step | What to call | What happens |
|---|---|---|
| 1 | GET Config | Load rates, LTV, liquidation threshold, fees, and FX for the calculator. |
| 2 | GET State | Check whether the current API key already has an active application or loan. |
| 3 | POST Loans with action=start_collateral_transfer | Create an application draft, calculate loan parameters, and receive test wallets. |
| 4 | POST Loans with action=confirm_btc | Simulate BTC collateral credit. In production, this is blockchain verification. |
| 5 | POST Loans with action=run_kyt | Simulate collateral KYT checks. |
| 6 | POST Loans with action=complete_payout | Complete the application and convert it into an active loan. |
| 7 | GET State or GET Loans | Read loan ID, status, debt, collateral, LTV, and history. |
Repayment and Collateral Return Scenario
| Step | What to call | What happens |
|---|---|---|
| 1 | GET Loans or GET State | Select an active loan and check the debt amount. |
| 2 | POST Repayments with action=start_payment | Create a repayment operation. The API returns operation_id and the test USDT wallet repayment. Full repayment also returns collateralReturn. |
| 3 | POST Repayments with action=confirm_usdt | Simulate USDT payment credit. Send operation_id on this and following steps. |
| 4 | POST Repayments with action=run_kyt | Simulate payment KYT checks. |
| 5 | POST Repayments with action=complete_settlement | Interest or principal is settled in the test loan state. |
| 6 | POST Repayments with action=complete_collateral_return | On full repayment, complete the BTC collateral return. |
| 7 | GET State | Confirm that the loan is closed, repayment is settled, and collateral return is shown in history. |
If the repayment is interest-only or partial principal, the collateral return step is not required.
Webhooks
Sandbox webhooks send push events to the partner HTTPS endpoint when the loan flow, repayment flow, or sandbox partner profile changes. The same delivery model is planned for LIVE API: the endpoint is configured per API key, delivery is signed with HMAC SHA-256, attempts are logged, and failed attempts can be retried.
Configure the endpoint through POST Webhooks. The first response and every response with rotate_secret=true returns signingSecret; store it on your side. Later responses show only secretPreview. To test delivery, call POST Webhook Test.
Webhook requests are sent as POST with JSON body and these headers:
| Header | Value |
|---|---|
x-fundora-webhook-id | Event ID. |
x-fundora-webhook-event | Event type, for example sandbox.loan.issued. |
x-fundora-webhook-timestamp | Unix timestamp in seconds. |
x-fundora-webhook-signature | v1= + HMAC SHA-256 of ${timestamp}.${rawBody} using signing_secret. |
The endpoint should return any 2xx status. Non-2xx responses, timeouts, or network errors move delivery to retry or failed state. Retry delivery through POST Webhook Retry.
Sandbox events:
| Event | When it is sent |
|---|---|
sandbox.loan_application.updated | Application is created, BTC collateral is confirmed, or KYT is completed. |
sandbox.loan.issued | Sandbox application is completed and becomes an active loan. |
sandbox.loan.updated | Active loan is changed directly through an action endpoint. |
sandbox.repayment.updated | Repayment operation is created or advanced toward settlement. |
sandbox.repayment.settled | Interest or principal is settled in sandbox state. |
sandbox.collateral.returned | Collateral is returned or released through a sandbox action. |
sandbox.partner.updated | Sandbox partner profile is created or updated. |
sandbox.webhook.test | Test event from the API. |
Errors
All errors return the same format: request_id, error_code, and error. Use error_code for integration logic and show error to humans.
| HTTP | Error code | When it happens | What to do |
|---|---|---|---|
| 401 | SANDBOX_API_KEY_REQUIRED | Authorization header is missing. | Send Authorization: Bearer sk_sandbox_.... |
| 401 | SANDBOX_API_KEY_INVALID | The key is invalid, revoked, or expired. | Check the key or create a new Sandbox API key. |
| 500 | SANDBOX_API_KEY_DATABASE_REQUIRED | Sandbox API is not configured in the environment. | Send request_id to Fundora support. |
| 401 | SANDBOX_SESSION_REQUIRED | The sandbox session could not be resolved. | Retry with a valid key or send request_id to support. |
| 429 | SANDBOX_RATE_LIMIT_EXCEEDED | The 120 requests per 60 seconds limit was exceeded. | Wait for the next window and retry. |
| 400 | INVALID_JSON | Request body is not valid JSON. | Check Content-Type: application/json and the body. |
| 400 | INVALID_ACTION | The action is unknown or not valid for the method. | Compare action with the method documentation. |
| 400 | INVALID_AMOUNT | Amount, collateral, or repayment parameters are invalid. | Check limits from GET Config. |
| 404 | LOAN_NOT_FOUND | Loan was not found for the current API key. | Refresh state through GET State or GET Loans. |
| 409 | FLOW_CONFLICT | A step was called too early or from the wrong status. | Call GET State and continue from the current step. |
| 400 | IDEMPOTENCY_KEY_REQUIRED | POST request has no Idempotency-Key. | Send a new UUID in Idempotency-Key. |
| 409 | IDEMPOTENCY_KEY_CONFLICT | This key was already used with another body or API method. | Use a new UUID for a new operation; retry with the same request for a repeat. |
| 409 | IDEMPOTENCY_KEY_IN_PROGRESS | The same key is already being processed. | Retry later with the same key and same body. |
| 400 | WEBHOOK_URL_REQUIRED | Webhook endpoint was not sent. | Send a public HTTPS URL. |
| 400 | WEBHOOK_URL_INVALID | Endpoint is not HTTPS or points to local/private host. | Use a public HTTPS URL without credentials. |
| 400 | WEBHOOK_EVENTS_INVALID | Event list is empty or contains an unknown event. | Send supported events from the Webhooks section. |
| 409 | WEBHOOK_ENDPOINT_REQUIRED | Test event was sent before webhook setup. | Call POST Webhooks first. |
| 404 | WEBHOOK_DELIVERY_NOT_FOUND | Delivery was not found or was already delivered. | Check deliveries through GET Webhooks. |
Retries and request_id
- All POST requests require
Idempotency-Key, usually a UUID. - Use a new key for every new operation.
- After a network error, retry with the same key, same API method, and same request body.
- If the same key is sent with another body, the API returns
IDEMPOTENCY_KEY_CONFLICT. - Every response contains
request_id. It is visible in the partner dashboard request log and helps support investigate issues quickly.
Where to Find Fields
- GET Config: rates, FX, fees, payment terms, and risk parameters.
- GET State: full snapshot with loans, current flows, wallets, history, and partner block.
- POST Loans: loan creation and payout flow steps.
- POST Repayments: repayment and collateral return flow steps.
- GET Partner: partner profile, links, levels, and rewards.
- GET Webhooks: webhook endpoint, signing secret preview, and recent delivery attempts.