Skip to main content

Overview

This guide provides a comprehensive walkthrough for implementing the Stable Sea Terminal API in production. It covers the complete order flow from authentication to settlement, including security, monitoring, error handling, and best practices.

Step-by-Step Integration

Follow these steps to implement the complete order flow from organization creation to settlement:
1

Authentication

All API requests require Bearer token authentication. Your API key serves as the bearer token.
# Test authentication
curl -X GET "https://api-sandbox.stablesea.com/v1/liquidity-providers" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
Replace YOUR_API_KEY with your actual API key. Store this securely and never expose it in client-side code.
2

Create Organization

Create an organization entity to associate with your orders and payment instruments.
curl -X POST "https://api-sandbox.stablesea.com/v1/organizations" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Test Organization Corp",
    "contact": {
      "email": "[email protected]",
      "first_name": "John",
      "last_name": "Doe"
    }
  }'
Response:
{
  "data": {
    "id": "org_01k2cm4r59e5z8k5ggrbbxjcwy",
    "name": "Test Organization Corp",
    "contact": {
      "email": "[email protected]",
      "first_name": "John",
      "last_name": "Doe"
    },
    "status": {
      "current_status": "COMPLIANCE_HOLD",
      "status_history": [
        {
          "status": "COMPLIANCE_HOLD",
          "created_at": "2025-09-09T12:18:40-04:00"
        }
      ]
    },
    "created_at": "2025-09-09T12:18:40-04:00",
    "updated_at": "2025-09-09T12:18:40-04:00"
  }
}
Save the organization id (starts with org_) as you’ll need it for subsequent API calls. Note that new organizations typically start in COMPLIANCE_HOLD status and may need approval before becoming ACTIVE.
3

Create External Payment Instruments

Set up both payin and payout payment methods for your organization.Create Payin Payment Instrument (USDC Solana Address):
curl -X POST "https://api-sandbox.stablesea.com/v1/organizations/ORGANIZATION_ID/external_payment_instruments" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "alias": "Test Solana Address",
    "currency": "USDC",
    "method": "SOLANA_ADDRESS",
    "details": {
      "address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
    }
  }'
Create Payout Payment Instrument (COP Bank Account):
curl -X POST "https://api-sandbox.stablesea.com/v1/organizations/ORGANIZATION_ID/external_payment_instruments" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "alias": "Test COP Bank Account",
    "currency": "COP",
    "method": "COP_BANK_ACCOUNT",
    "details": {
      "bank_account_number": "1234567890",
      "bank_code": "001",
      "account_holder_first_name": "Juan",
      "account_holder_last_name": "Perez",
      "legal_entity_name": "Juan Perez Empresa",
      "doc_type": "CC",
      "doc_id": "901458.6527",
      "physical_address": "Calle 123 #45-67, Bogotá, Colombia",
      "account_type": "CHECKING"
    }
  }'
USDC Solana Address Response:
{
  "data": {
    "id": "mnyacct_01k4qmv28kefk8mgxje22f360y",
    "alias": "Test Solana Address",
    "currency": "USDC",
    "method": "SOLANA_ADDRESS",
    "status": {
      "current_status": "COMPLIANCE_HOLD",
      "status_history": [
        {
          "status": "COMPLIANCE_HOLD",
          "created_at": "2025-09-09T12:27:14-04:00"
        }
      ]
    },
    "details": {
      "address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
    }
  }
}
COP Bank Account Response:
{
  "data": {
    "id": "mnyacctcop_01k4r01nkxf41vpxc3nekphrx8",
    "alias": "Test COP Bank Account",
    "currency": "COP",
    "method": "COP_BANK_ACCOUNT",
    "status": {
      "current_status": "COMPLIANCE_HOLD",
      "status_history": [
        {
          "status": "COMPLIANCE_HOLD",
          "created_at": "2025-09-09T12:28:21-04:00"
        }
      ]
    },
    "details": {
      "bank_account_number": "1234567890",
      "bank_code": "001",
      "account_holder_first_name": "Juan",
      "account_holder_last_name": "Perez",
      "legal_entity_name": "Juan Perez Empresa",
      "doc_type": "CC",
      "doc_id": "901458.6527",
      "physical_address": "Calle 123 #45-67, Bogotá, Colombia",
      "account_type": "CHECKING"
    }
  }
}
Payment instruments start in COMPLIANCE_HOLD status and may need approval before becoming ACTIVE. Store the returned IDs (starting with mnyacct_ or mnyacctcop_) for creating offerings.
4

Check Liquidity Providers

Get available liquidity providers with their trading pairs and operating hours.
curl -X GET "https://api-sandbox.stablesea.com/v1/liquidity-providers" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
Response:
{
  "data": [
    {
      "name": "ALPHA",
      "trading_pairs": [
        {
          "payin_currency": "USDC",
          "payout_currency": "COP",
          "hours_of_operation": [
        {
          "open_time_utc": "2025-09-09T13:30:00Z",
          "close_time_utc": "2025-09-09T20:00:00Z"
        },
        {
          "open_time_utc": "2025-09-10T13:30:00Z",
          "close_time_utc": "2025-09-10T20:00:00Z"
        },
        {
          "open_time_utc": "2025-09-11T13:30:00Z",
          "close_time_utc": "2025-09-11T20:00:00Z"
        },
        {
          "open_time_utc": "2025-09-12T13:30:00Z",
          "close_time_utc": "2025-09-12T20:00:00Z"
        }
      ]
        }
      ]
    }
  ]
}
Only create offerings when liquidity providers are within their operating hours for optimal execution. You can also use the exchange rate endpoint to display current rates to users.
5

Get Current Exchange Rate (Optional)

Optionally fetch current exchange rates to display to end users. This is useful for showing indicative rates before creating formal quotes.
curl -X GET "https://api-sandbox.stablesea.com/v1/liquidity-providers/ALPHA/exchange-rate" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
Response:
{
  "data": {
    "payin_currency": "USDC",
    "payout_currency": "COP",
    "exchange_rate": "3921.8"
  }
}
Exchange rates are indicative and may change frequently. For guaranteed rates, use the quote endpoint to lock in a rate for order execution.
6

Create Offerings

Generate available payment corridors and rates for your organization.
curl -X POST "https://api-sandbox.stablesea.com/v1/organizations/ORGANIZATION_ID/offerings" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
Response:
{
  "data": [
    {
      "id": "off_01k4r0qt0mf41v68zh6w7de845",
      "order_type": "QUOTED",
      "payin": {
        "external_payment_instrument": {
          "id": "mnyacctcm_01k4r01nm4f41tcsws4sr9k8nn",
          "alias": "Test Solana Address",
          "currency": "USDC",
          "method": "SOLANA_ADDRESS",
          "status": {
            "current_status": "COMPLIANCE_HOLD",
            "status_history": [
              {
                "status": "COMPLIANCE_HOLD",
                "created_at": "2025-09-09T12:27:14-04:00"
              }
            ]
          },
          "details": {
            "address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
          }
        },
        "limits": {
          "min": "0.01",
          "max": "100"
        },
        "indicative_cost_tiers": [
          {
            "min": "0.01",
            "max": "1",
            "bps": "75"
          },
          {
            "min": "1.01",
            "max": "25",
            "bps": "70"
          },
          {
            "min": "25.01",
            "max": "100",
            "bps": "60"
          }
        ]
      },
      "payout": {
        "external_payment_instrument": {
          "id": "mnyacctcop_01k4r01nkxf41vpxc3nekphrx8",
          "alias": "Test COP Bank Account",
          "currency": "COP",
          "method": "COP_BANK_ACCOUNT",
          "status": {
            "current_status": "COMPLIANCE_HOLD",
            "status_history": [
              {
                "status": "COMPLIANCE_HOLD",
                "created_at": "2025-09-09T12:28:21-04:00"
              }
            ]
          },
          "details": {
            "bank_account_number": "1234567890",
            "bank_code": "001",
            "account_holder_first_name": "Juan",
            "account_holder_last_name": "Perez",
            "legal_entity_name": "Juan Perez Empresa",
            "doc_type": "CC",
            "doc_id": "901458.6527",
            "physical_address": "Calle 123 #45-67, Bogotá, Colombia",
            "account_type": "CHECKING"
          }
        }
      },
      "indicative_exchange_rate": "3290.5",
      "liquidity_provider": "DLOCAL",
      "estimated_settlement_time": "T+0",
      "created_at": "2025-09-09T12:29:01-04:00"
    }
  ]
}
Offerings contain indicative rates and fees. Final rates are locked when creating quotes.
In order to create offerings you must have compatible External Payment Instruments set up where compatibility is determined by the currency. For example, to create USDC→COP offerings, you need both a USDC payin instrument (like SOLANA_ADDRESS) and a COP payout instrument (like COP_BANK_ACCOUNT).
7

Create Quote

Get firm pricing with locked exchange rates and expiration times.
curl -X POST "https://api-sandbox.stablesea.com/v1/organizations/ORGANIZATION_ID/quotes" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "offering_id": "off_01k4qph5ezfsga7fkvbygsqq93",
    "payin_amount": "0.01"
  }'
Response:
{
  "data": {
    "id": "qt_01k4qpmvgxfsg9db9mjrtq9tk2",
    "offering_id": "off_01k4qph5ezfsga7fkvbygsqq93",
    "exchange_rate": "3290.5",
    "payin": {
      "total": "0.01",
      "fee": "0.00",
      "tax": "0.00"
    },
    "payout": {
      "total": "32.91"
    },
    "submission_expires_at": "2025-09-09T16:59:48Z",
    "funding_expires_at": "2025-09-09T16:59:48Z",
    "created_at": "2025-09-09T16:58:48Z"
  }
}
Quotes have two expiration times:
  • submission_expires_at: Deadline to create an order
  • funding_expires_at: Deadline to fund the order after creation
8

Create Order

Convert your quote into an executable order before expiration.
curl -X POST "https://api-sandbox.stablesea.com/v1/organizations/ORGANIZATION_ID/orders" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "quote_id": "qt_01k4qpmvgxfsg9db9mjrtq9tk2"
  }'
Response:
{
  "data": {
    "id": "ord_01k4qn3cxdefkargtccm4ycxsf",
    "quote_id": "qt_01k4qpmvgxfsg9db9mjrtq9tk2",
    "offering_id": "off_01k4qph5ezfsga7fkvbygsqq93",
    "reference_number": "SS240115-001",
    "external_reference_id": null,
    "exchange_rate": "3290.5",
    "effective_exchange_rate": "3290.5",
    "payin": {
      "external_payment_instrument": {
        "id": "mnyacctcm_01k4r01nm4f41tcsws4sr9k8nn",
        "alias": "Test Solana Address",
        "currency": "USDC",
        "method": "SOLANA_ADDRESS",
        "status": {
          "current_status": "ACTIVE",
          "status_history": [
            {
              "status": "ACTIVE",
              "created_at": "2024-01-15T10:00:00Z"
            }
          ]
        },
        "details": {
          "address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
        },
        "created_at": "2024-01-15T10:00:00Z",
        "updated_at": "2024-01-15T10:00:00Z"
      },
      "total": "0.01",
      "fee": "0.00",
      "tax": "0.00"
    },
    "payout": {
      "external_payment_instrument": {
        "id": "mnyacctcop_01k4r01nkxf41vpxc3nekphrx8",
        "alias": "Test COP Bank Account",
        "currency": "COP",
        "method": "COP_BANK_ACCOUNT",
        "status": {
          "current_status": "ACTIVE",
          "status_history": [
            {
              "status": "ACTIVE",
              "created_at": "2024-01-15T11:00:00Z"
            }
          ]
        },
        "details": {
          "bank_account_number": "1234567890",
          "bank_code": "001",
          "account_holder_first_name": "Juan",
          "account_holder_last_name": "Perez",
          "legal_entity_name": "Juan Perez Empresa",
          "doc_type": "CC",
          "doc_id": "901458.6527",
          "physical_address": "Calle 123 #45-67, Bogotá, Colombia",
          "account_type": "CHECKING"
        },
        "created_at": "2024-01-15T11:00:00Z",
        "updated_at": "2024-01-15T11:00:00Z"
      },
      "total": "32.91"
    },
    "status": {
      "current_status": "STEP_1_AWAITING_FUNDING",
      "status_history": [
        {
          "status": "STEP_1_AWAITING_FUNDING",
          "created_at": "2024-01-15T10:50:00Z"
        }
      ]
    },
    "funding_instructions": {
      "currency": "USDC",
      "method": "SOLANA_ADDRESS",
      "details": {
        "address": "B2C3D4E5F6G7H8I9J0K1L2M3N4O5P6Q7R8S9T0U1V2W3X4Y5Z6A1"
      }
    },
    "retry_order_id": null,
    "created_at": "2024-01-15T10:50:00Z",
    "updated_at": "2024-01-15T10:50:00Z"
  }
}
Use the Idempotency-Key header to safely retry order creation without creating duplicates.
9

Monitor Order Status

Track your order through the complete settlement lifecycle.
curl -X GET "https://api-sandbox.stablesea.com/v1/organizations/ORGANIZATION_ID/orders/ORDER_ID" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
Order Status Progression:
  • STEP_1_AWAITING_FUNDING - Waiting for payin funds
  • STEP_2_FILLING_FX - Executing foreign exchange
  • STEP_3_SETTLING_PAYOUT - Processing payout settlement
  • STEP_4_COMPLETED - Order successfully completed
Poll the order status endpoint periodically to monitor order progress. Consider implementing exponential backoff between polling requests.

Production Considerations

API Key Security

  • Store API keys in environment variables, not code
  • Use different keys for sandbox and production
  • Rotate keys regularly for security
  • Use secret management services (AWS Secrets Manager, HashiCorp Vault)
  • Always use HTTPS/TLS 1.3 for API communications
  • Implement proper access controls and audit logging

Error Handling

// Simple retry with exponential backoff
async function apiCallWithRetry(requestFn, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await requestFn();
    } catch (error) {
      if (attempt === maxRetries || error.status < 500) {
        throw error;
      }
      await new Promise((resolve) =>
        setTimeout(resolve, 1000 * Math.pow(2, attempt))
      );
    }
  }
}

Monitoring

  • Track order success rates and settlement times
  • Monitor API response times and error rates
  • Set up alerts for high error rates or slow responses
  • Log all API interactions with correlation IDs
  • Use structured logging with JSON format
  • Monitor quote-to-order conversion rates
  • Track performance by payment method and currency pair
  • Set up dashboards for real-time order flow visibility