Docs
Floint Development Documentation
Floint is an orchestration layer that helps products run payments and compliance workflows through one integration surface. It standardizes routing, retries, unified statuses, webhooks, and delivery logs across multiple providers.
These docs explain the core building blocks: how workspaces and API keys work, how to create an Operation, how statuses stay consistent across providers, and how to consume events via signed webhooks.
Docs Home
Start here to understand what Floint is, how operations work, and how the API fits together. Use this page as the entry point before creating your first operation.
Welcome to Floint
Floint is an operations orchestration layer for crypto-fiat payment flows.
It gives your product one consistent way to create, track, and receive updates for payment operations across different providers. Instead of integrating directly with every on-ramp, off-ramp, or payout provider, you work with a unified operation model through the Floint API.
Floint handles provider-specific complexity underneath, including different request formats, status models, webhook behaviour, routing logic, and operational logs.
The goal is simple: your team sends one operation, Floint manages the provider layer, and your system receives clear status updates through signed webhooks.
What is Floint?
Floint is a unified API layer for payment operations.
Most payment provider integrations start simple, but become harder to maintain over time. Each provider has its own API structure, status vocabulary, webhook format, error handling, and operational behaviour. If your product integrates with multiple providers directly, your backend quickly becomes filled with provider-specific logic.
Floint is built to reduce that complexity.
With Floint, your application creates an operation. An operation represents a single payment-related workflow, such as an on-ramp, off-ramp, or payout. Floint accepts the operation, stores it, routes it through the configured provider layer, tracks its lifecycle, and sends updates back to your system.
You do not need to build separate logic for every provider response or webhook event. Floint normalizes the operation lifecycle into one consistent model.
In short:
one API, one operation model, one status lifecycle, one webhook format.
How Floint works
Every flow starts with an operation.
Your application sends a request to Floint with the operation type and payload. Floint accepts the request and begins processing it asynchronously. Depending on the operation type, configuration, and provider availability, Floint routes the operation through the provider layer.
As the operation moves through its lifecycle, Floint keeps your system updated through consistent statuses and signed webhook events.
A typical flow looks like this:
Your application
↓
Create an operation through Floint API
↓
Floint stores and processes the operation
↓
Floint routes it through the provider layer
↓
The provider executes the flow
↓
Floint normalizes the status and result
↓
Your system receives webhook updates
This keeps your product logic cleaner. Your team works with Floint’s operation model instead of maintaining separate integrations for every provider.
Quick Start
This quick start shows the basic path from access to your first operation.
1. Get sandbox access
To start using Floint, you need a workspace and an API key.
During the early sandbox stage, access is provided manually by the Floint team. Once your workspace is created, you will receive credentials and an API key for testing.
All API requests must include your API key in the X-API-KEY header.
X-API-KEY: your_api_key_here
2. Configure your webhook endpoint
Floint uses webhooks to send operation updates back to your system.
Before creating operations, configure an HTTPS endpoint where Floint can deliver webhook events.
Example:
https://yourapp.com/webhooks/floint
Your webhook endpoint should accept POST requests with a JSON body and respond with a 2xx status code after receiving the event.
Floint signs webhook events so your system can verify that the payload was sent by Floint.
3. Create your first operation
Create an operation by sending a request to the Operations API.
Every operation request must include an Idempotency-Key. This prevents duplicate operations if you retry the same request after a timeout or network issue.
POST /operations
X-API-KEY: your_api_key_here
Idempotency-Key: 7f3c2a1b-4e8d-4f9a-b2c1-0e8f7a6b5d4c
Content-Type: application/json
{
"type": "onramp",
"payload": {
"cryptoCurrencyCode": "USDT",
"fiatCurrency": "EUR",
"defaultCryptoAmount": "25"
}
}
Floint accepts the operation and begins processing it asynchronously.
You can track the operation through the API or wait for webhook updates.
4. Receive webhook updates
When an operation requires action, succeeds, or fails, Floint sends an event to your configured webhook endpoint.
Example webhook payload:
{
"operationId": "550e8400-e29b-41d4-a716-446655440000",
"type": "onramp",
"status": "Succeeded",
"completedAtUtc": "2026-04-14T10:30:40Z"
}
Your system should verify the webhook signature, process the event idempotently, and return a 2xx response.
5. Check operation status
You can retrieve an operation at any time using its operation ID.
GET /operations/{operationId}
X-API-KEY: your_api_key_here
This is useful for dashboards, support tools, reconciliation, and debugging.
Next steps
After completing the quick start, continue with these sections:
Get Started
Set up your workspace, API key, sandbox environment, first operation, and go-live checklist.
Core Concepts
Learn how operations, statuses, idempotency, routing, fallback, providers, and nextAction work.
API Reference
Review available endpoints, request formats, response objects, authentication, and error handling.
Webhooks
Understand webhook delivery, signature verification, retries, and example payloads.
Troubleshooting
Debug common errors, missing webhooks, and operation issues.
Get Started
Set up your workspace, get your API key, configure webhooks, and send your first request in the sandbox. This section walks you through the first working integration.
This section walks you through the first steps required to start building with Floint.
You will learn how to get access, set up your workspace, use your API key, configure the sandbox environment, create your first operation, and prepare for production access.
How to get access
Floint is currently available through private sandbox access.
To start testing, contact the Floint team and request a sandbox workspace. Once approved, you will receive workspace credentials and an API key that allows you to make requests to the Floint API.
During the early sandbox stage, access is provided manually so we can support each integration closely and collect feedback from early partners.
You will receive:
Workspace credentials
Sandbox API key
Sandbox API base URL
Documentation link
Webhook setup instructions
Creating your first workspace
A workspace represents your organization or project inside Floint.
All API keys, webhook settings, operations, and logs are linked to a workspace. This keeps your integration environment separated from other partners and allows your team to test flows safely in sandbox.
During the early sandbox stage, the Floint team creates your workspace for you.
Once your workspace is ready, you will receive test credentials that allow you to access the sandbox dashboard and manage your integration settings.
Example workspace details:
Workspace name: Test Partner
Environment: Sandbox
In future versions, workspace creation may become self-serve through the Floint dashboard.
Obtaining and managing API keys
Your API key is used to authenticate requests to the Floint API.
Include your API key in the X-API-KEY header on every API request.
X-API-KEY: your_api_key_here
Keep your API key secure. Do not expose it in frontend code, public repositories, mobile apps, or client-side environments.
Your API key should only be used from your backend.
If you believe an API key has been exposed, rotate it from the Floint dashboard or contact the Floint team.
A typical backend request should look like this:
POST /operations
X-API-KEY: your_api_key_here
Idempotency-Key: 7f3c2a1b-4e8d-4f9a-b2c1-0e8f7a6b5d4c
Content-Type: application/json
Sandbox environment setup
Use the sandbox environment to test your integration before production access.
The sandbox allows you to create test operations, configure webhooks, inspect statuses, and validate how your system handles operation updates.
Sandbox base URL:
https://sandbox.api.floint.xyz
All examples in this documentation use the sandbox environment unless stated otherwise.
Before creating your first operation, make sure you have:
A sandbox workspace
A valid API key
A backend service that can make API requests
An HTTPS webhook endpoint
A way to store webhook events and operation IDs
Configure your webhook endpoint
Floint uses webhooks to send operation updates to your system.
Before testing real operation flows, configure an HTTPS endpoint where Floint can deliver events.
Example webhook URL:
https://yourapp.com/webhooks/floint
Your endpoint should:
Accept POST requests
Read the raw request body
Verify the Floint webhook signature
Respond with a 2xx status code
Process events idempotently
Webhook events are signed, so your backend can verify that the request came from Floint.
You can send a test webhook from the dashboard to confirm that your endpoint is reachable before creating operations.
Your first operation
After your workspace, API key, and webhook endpoint are ready, you can create your first operation.
An operation is the main unit of work in Floint. It represents a payment-related flow such as an on-ramp, off-ramp, or payout.
Example request:
POST /operations
X-API-KEY: your_api_key_here
Idempotency-Key: 7f3c2a1b-4e8d-4f9a-b2c1-0e8f7a6b5d4c
Content-Type: application/json
{
"type": "onramp",
"payload": {
"cryptoCurrencyCode": "USDT",
"fiatCurrency": "EUR",
"defaultCryptoAmount": "25"
}
}
Floint accepts the operation and starts processing it asynchronously.
The operation then moves through its lifecycle. Depending on the provider flow, it may require user action, succeed, or fail.
You can track the operation in two ways:
Receive webhook events from Floint
Fetch the operation status through the API
Example status check:
GET /operations/{operationId}
X-API-KEY: your_api_key_here
Go Live checklist
Before moving from sandbox to production, make sure your integration is ready.
Your team should confirm that:
API keys are stored securely on your backend
No API keys are exposed in frontend code
Webhook signature verification is implemented
Webhook events are processed idempotently
Your system handles duplicate webhook delivery
Your system handles failed and action-required operations
Operation IDs are stored for reconciliation and support
Errors are logged and monitored
Sandbox tests have been completed successfully
You should also test the full operation flow end-to-end:
Create an operation
Receive webhook updates
Handle required user actions
Process succeeded operations
Process failed operations
Check operation status through the API
Review operation logs for debugging
Once these steps are complete, contact the Floint team to discuss production access.
Production access may require additional review, provider configuration, compliance checks, and environment setup.
Core concepts
Learn the main ideas behind Floint: operations, statuses, idempotency, routing, fallback, and provider logic. These concepts explain how Floint keeps payment flows consistent.
This section explains the core ideas behind Floint.
Before working with the API, it is important to understand how Floint models payment flows, how operation statuses work, how user actions are handled, and how Floint keeps provider-specific complexity away from your product logic.
Floint is built around one main idea:
your application works with operations, while Floint handles the provider layer underneath.
Unified Operation Model
An operation is the core unit of work in Floint.
Every payment-related flow starts as an operation. This can be an on-ramp, off-ramp, payout, or another supported flow type.
Instead of calling different providers directly, your application creates an operation through the Floint API. Floint accepts the operation, stores it, processes it asynchronously, and routes it through the configured provider layer.
A typical operation includes:
Operation ID
Operation type
Status
Payload
Idempotency key
Provider information
Timestamps
Webhook delivery state
Audit logs
The operation model gives your backend one consistent object to work with, regardless of which provider handles the flow underneath.
This means your application does not need to build separate state machines, webhook handlers, or provider-specific logic for every integration.
The basic flow is:
Create operation
↓
Floint accepts and stores it
↓
Floint routes it through the provider layer
↓
Floint tracks the lifecycle
↓
Your system receives webhook updates
The operation is the source of truth for the flow. You can retrieve it through the API, listen for webhook updates, and inspect logs when debugging.
Operation Types
Each operation has a type.
The operation type defines what kind of flow Floint should process.
Example operation types:
onramp
offramp
payout
The supported types available to your workspace may depend on your environment, provider configuration, and access level.
You can check supported operation types through the API:
GET /operations/types/supported
X-API-KEY: your_api_key_here
Example response:
["onramp", "offramp"]
When creating an operation, include the type in the request body.
{
"type": "onramp",
"payload": {
"cryptoCurrencyCode": "USDT",
"fiatCurrency": "EUR",
"defaultCryptoAmount": "25"
}
}
Statuses & Lifecycle
Every provider has its own internal status vocabulary.
One provider may return pending_kyc, another may return processing, another may return transaction_failed_risk, and another may require a redirect or hosted checkout interaction.
If your application integrated directly with each provider, your backend would need to understand and map all of these provider-specific states.
Floint normalizes this into one unified status model.
No matter which provider handles the operation, your application works with the same four statuses.
The four statuses
| Status | Meaning |
|---|---|
| Pending | The operation has been accepted and Floint is routing or processing it. No action is needed from your application. |
| WaitingForAction | The flow has paused and is waiting for the user to complete an interaction, such as a provider-hosted redirect or widget step. |
| Succeeded | The operation completed successfully. |
| Failed | The operation failed after retries or encountered an unrecoverable error. |
Lifecycle
An operation always starts as Pending.
Most operations follow one of these simple paths:
Pending → Succeeded
Pending → Failed
Some provider flows require user interaction. In that case, the operation may move to WaitingForAction.
Pending → WaitingForAction → Pending → Succeeded
Pending → WaitingForAction → Pending → Failed
For multi-step flows, an operation may enter WaitingForAction more than once.
The important point is that your application does not need to understand provider-specific status codes. Floint keeps the external status lifecycle consistent.
A simplified lifecycle looks like this:
Pending ─────────────────────────→ Succeeded
│
├──→ WaitingForAction ──→ Pending ──→ Succeeded
│ │
│ └──→ Failed
│
└────────────────────────────→ Failed
Why statuses matter
Unified statuses make your integration easier to maintain.
Your backend does not need separate logic for every provider. Your UI can depend on one lifecycle. Your webhook handler can process the same event structure regardless of which provider handled the operation.
This is one of the main reasons Floint exists.
Instead of building provider-specific state handling yourself, you work with Floint’s operation lifecycle.
**nextAction**field
Some operations require the user to complete an additional step before processing can continue.
For example, an on-ramp flow may require the user to open a provider-hosted page, complete a checkout, verify details, or finish an external interaction.
When this happens, the operation moves to WaitingForAction.
The nextAction field is used to tell your application what should happen next.
A typical nextAction may include a redirect URL or action type that your frontend can use to guide the user.
Example structure:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "onramp",
"status": "WaitingForAction",
"nextAction": {
"type": "redirect",
"url": "https://provider.example/checkout/session_123"
}
}
In this example, your application should redirect the user to the provided URL.
After the user completes the required step, Floint continues processing the operation. The operation may return to Pending, then eventually move to Succeeded or Failed.
Your application does not need to manually move the operation forward through the API. It only needs to present the required action to the user when nextAction is present.
Idempotency
Idempotency prevents duplicate operations.
Network failures, timeouts, retries, and client-side uncertainty are common in payment systems. Your application may send the same request more than once if it does not know whether the first request succeeded.
To prevent duplicates, all mutating operation requests require an Idempotency-Key.
Idempotency-Key: 7f3c2a1b-4e8d-4f9a-b2c1-0e8f7a6b5d4c
Use a unique idempotency key for every new operation.
If you retry the same operation request after a timeout or network issue, reuse the same key.
Floint uses the key to recognize that the retry belongs to the same original request and avoids creating a duplicate operation.
Example:
POST /operations
X-API-KEY: your_api_key_here
Idempotency-Key: 7f3c2a1b-4e8d-4f9a-b2c1-0e8f7a6b5d4c
Content-Type: application/json
{
"type": "onramp",
"payload": {
"cryptoCurrencyCode": "USDT",
"fiatCurrency": "EUR",
"defaultCryptoAmount": "25"
}
}
If your system retries this exact request, it should use the same Idempotency-Key.
Do not generate a new key when retrying the same request. A new key means a new operation.
Routing & Automatic Fallback
Floint is designed to route operations through a provider layer instead of requiring your application to call providers directly.
This means your product can create an operation without hardcoding provider-specific request handling into your backend.
At a high level, Floint can use factors such as operation type, provider availability, workspace configuration, and supported capabilities to decide how an operation should be processed.
The goal is to keep provider logic underneath Floint, while your application continues to work with the same operation model.
Your application
↓
Floint operation
↓
Provider routing layer
↓
Provider execution
↓
Unified status + webhook update
Automatic fallback is part of Floint’s intended orchestration model.
When supported by the environment and configuration, fallback can allow Floint to retry or continue processing through another provider if the first route cannot complete the operation.
This should reduce the amount of provider-specific failure handling your team needs to build directly.
During the current sandbox stage, routing and fallback behaviour may depend on available providers and workspace configuration.
Providers & Multi-provider logic
Providers are the external services that execute payment-related flows.
Examples may include on-ramp providers, off-ramp providers, payout providers, or other infrastructure services connected to Floint.
Your application does not call providers directly through Floint’s public API. Instead, you create an operation, and Floint handles the provider layer underneath.
This keeps your application insulated from provider-specific differences such as:
Different request formats
Different status names
Different webhook payloads
Different error codes
Different hosted flow behaviour
Different retry behaviour
You can inspect available providers through the API:
GET /providers/available
X-API-KEY: your_api_key_here
Example response:
[
{
"name": "example_provider",
"supportedOperationTypes": ["onramp", "offramp"]
}
]
Provider availability may vary by environment, workspace configuration, and supported operation type.
The main benefit is that adding or changing providers should not require your application to rebuild its integration logic. Your system continues to work with operations, statuses, and webhooks in the same format.
Why these concepts matter
Floint is built to reduce the operational complexity of provider-based payment flows.
Without Floint, your team may need to build and maintain separate logic for every provider integration. This includes status mapping, webhook parsing, retry handling, error interpretation, redirect flows, and debugging tools.
With Floint, your application works with one model:
One operation object
One status lifecycle
One webhook format
One authentication pattern
One place to debug flows
That consistency is the foundation of the Floint API.
The provider layer can change underneath, but your application logic stays focused on the operation lifecycle.
API Reference
Explore every available endpoint, request format, response object, header, and error structure. Use this section when you need exact technical details.
The Floint API lets you create operations, retrieve operation status, inspect supported providers, configure webhooks, and debug operation behaviour through logs.
All examples in this section use the sandbox environment.
https://sandbox.api.floint.xyz
Floint is built around a single core object: the operation.
Your application creates an operation through the API. Floint accepts it, processes it asynchronously, routes it through the configured provider layer, and sends status updates to your webhook endpoint.
Authentication
All API requests must be authenticated with your API key.
Include your API key in the X-API-KEY header on every request.
X-API-KEY: your_api_key_here
API keys are linked to your workspace.
Your API key should only be used from your backend. Do not expose it in frontend code, public repositories, mobile apps, browser environments, or client-side applications.
Example authenticated request:
GET /operations/search?pageNumber=1&pageSize=20
X-API-KEY: your_api_key_here
If the API key is missing, invalid, or does not have access to the requested resource, Floint returns an authentication or forbidden error.
Request headers
Floint uses a small set of headers across the API.
| Header | Required | Description |
|---|---|---|
| X-API-KEY | Yes | Authenticates your request. |
| Idempotency-Key | Required for mutating operation requests | Prevents duplicate operations when retrying the same request. |
| Content-Type: application/json | Required for POST requests | Indicates that the request body is JSON. |
Example:
POST /operations
X-API-KEY: your_api_key_here
Idempotency-Key: 7f3c2a1b-4e8d-4f9a-b2c1-0e8f7a6b5d4c
Content-Type: application/json
Operations endpoints
Operations are the main object in Floint.
Use operation endpoints to create operations, retrieve status, search operation history, and inspect logs.
Create operation
POST /operations
Creates a new operation.
Every create operation request must include an Idempotency-Key.
POST /operations
X-API-KEY: your_api_key_here
Idempotency-Key: 7f3c2a1b-4e8d-4f9a-b2c1-0e8f7a6b5d4c
Content-Type: application/json
Example request:
{
"type": "onramp",
"payload": {
"cryptoCurrencyCode": "USDT",
"fiatCurrency": "EUR",
"defaultCryptoAmount": "25"
}
}
The type field defines the operation type.
The payload field contains the operation-specific data required for that flow.
Floint accepts the operation and begins processing it asynchronously. Depending on the operation type and provider flow, the operation may move through Pending, WaitingForAction, Succeeded, or Failed.
Example response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "onramp",
"status": "Pending",
"createdAtUtc": "2026-04-14T10:00:00Z"
}
If the operation requires user interaction, the operation may later move to WaitingForAction and include a nextAction object.
Get operation by ID
GET /operations/{operationId}
Retrieves the current state of an operation.
GET /operations/550e8400-e29b-41d4-a716-446655440000
X-API-KEY: your_api_key_here
Example response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "onramp",
"status": "Succeeded",
"idempotencyKey": "7f3c2a1b-4e8d-4f9a-b2c1-0e8f7a6b5d4c",
"createdAtUtc": "2026-04-14T10:00:00Z",
"completedAtUtc": "2026-04-14T10:00:30Z",
"currentProviderName": "example_provider",
"providerExternalId": "provider_1234567890",
"providerErrorMessage": null,
"providerErrorCode": null,
"clientDeliveryAttemptCount": 1
}
Use this endpoint when you need to check the latest operation state, support a customer, reconcile internal records, or debug an integration issue.
Search operations
GET /operations/search
Searches and filters operations in your workspace.
Example request:
GET /operations/search?pageNumber=1&pageSize=20&status=Succeeded&type=onramp&sortBy=createdAtUtc&isDescending=true
X-API-KEY: your_api_key_here
Example response:
{
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "onramp",
"status": "Succeeded",
"createdAtUtc": "2026-04-14T10:00:00Z",
"completedAtUtc": "2026-04-14T10:00:30Z",
"currentProviderName": "example_provider"
}
],
"pageNumber": 1,
"pageSize": 20,
"totalCount": 84
}
Available query parameters:
| Parameter | Type | Description |
|---|---|---|
| pageNumber | integer | Page number. Starts from 1. |
| pageSize | integer | Number of results per page. |
| id | string | Filter by operation ID. |
| type | string | Filter by operation type. |
| status | string | Filter by operation status. |
| providerName | string | Filter by provider name. |
| createdAtFrom | datetime | Filter by creation date start. |
| createdAtTo | datetime | Filter by creation date end. |
| sortBy | string | Field used for sorting. |
| isDescending | boolean | Sort direction. Default is false. |
Search is useful for dashboards, support tooling, reporting, and reconciliation.
Get operation logs
GET /operations/{operationId}/logs
Returns the audit log for an operation.
GET /operations/550e8400-e29b-41d4-a716-446655440000/logs
X-API-KEY: your_api_key_here
Example response:
[
{
"type": "OperationAccepted",
"createdAtUtc": "2026-04-14T10:00:00Z",
"metadataJson": null,
"providerName": null,
"statusCode": null,
"isError": false,
"requestBodyJson": "{\"amount\":100.00}",
"responseBodyJson": null
},
{
"type": "RoutedToAdapter",
"createdAtUtc": "2026-04-14T10:00:05Z",
"providerName": "example_provider",
"isError": false,
"requestBodyJson": null,
"responseBodyJson": null
},
{
"type": "ProviderResponseReceived",
"createdAtUtc": "2026-04-14T10:00:25Z",
"providerName": "example_provider",
"statusCode": 200,
"isError": false,
"responseBodyJson": "{\"id\":\"provider_1234567890\"}"
}
]
Operation logs help you understand what happened during processing.
Use logs for debugging, support, webhook delivery investigation, and operational visibility.
Common log event types include:
| Type | Meaning |
|---|---|
| OperationAccepted | Operation received and stored. |
| RoutedToAdapter | Operation assigned to a provider adapter. |
| ProcessedByAdapter | Provider adapter processed the request. |
| ProviderResponseReceived | Response or event received from the provider. |
| ProviderDeliverySucceed | Provider delivery succeeded. |
| ProviderDeliveryFailed | Provider delivery failed. |
| ClientDeliverySucceed | Webhook delivery to your endpoint succeeded. |
| ClientDeliveryFailed | Webhook delivery to your endpoint failed. |
| MovedToDls | Operation or event moved to dead-letter storage after retries were exhausted. |
Providers endpoints
Provider endpoints show which providers and operation types are currently available in your workspace.
You do not need to select a provider when creating an operation. Floint handles provider routing through the configured provider layer.
List available providers
GET /providers/available
Returns the providers available for your workspace and the operation types they support.
GET /providers/available
X-API-KEY: your_api_key_here
Example response:
[
{
"name": "example_provider",
"supportedOperationTypes": ["onramp", "offramp"]
}
]
Provider availability may depend on environment, workspace configuration, and supported operation types.
List supported operation types
GET /operations/types/supported
Returns operation types currently supported for your workspace.
GET /operations/types/supported
X-API-KEY: your_api_key_here
Example response:
["onramp", "offramp"]
Use this endpoint to check which operation types your workspace can create.
Webhooks endpoints
Webhook endpoints let you configure and test how Floint sends operation updates to your system.
During the current sandbox stage, webhook settings may be managed through the Floint dashboard or manually during onboarding.
Configure webhook endpoint
Webhook configuration is linked to your workspace.
Your webhook URL must be a publicly reachable HTTPS endpoint that accepts POST requests with a JSON body.
Example webhook URL:
https://yourapp.com/webhooks/floint
When a webhook endpoint is created, Floint generates a webhook secret. Store this secret securely. You will use it to verify webhook signatures.
The webhook secret is shown only once.
Send test webhook
POST /workspaces/{workspaceId}/webhooks/test
Sends a test webhook event to your configured webhook URL.
Use this endpoint to confirm that your endpoint is reachable and that your backend can receive Floint webhook events.
Example response:
{
"isDelivered": true,
"statusCode": 200,
"responseBody": "OK",
"error": null,
"attemptedAtUtc": "2026-04-14T10:30:45Z"
}
If test delivery fails, check that your endpoint is public, accepts POST requests, responds quickly, and returns a 2xx status code.
Error codes and handling
Floint returns errors in a consistent structure.
Example error:
{
"code": "Operations.NotFound",
"description": "The requested operation could not be found.",
"type": "NotFound"
}
Each error contains:
| Field | Description |
|---|---|
| code | Machine-readable error code. |
| description | Human-readable explanation. |
| type | General error category. |
Error types:
| Type | HTTP status | Meaning |
|---|---|---|
| Validation | 400 | The request payload or headers are invalid. |
| Problem | 400 | The request is valid, but cannot be completed because of a business rule. |
| Authentication | 401 | API key is missing or invalid. |
| Forbidden | 403 | API key does not have access to the resource. |
| NotFound | 404 | Resource does not exist. |
| Failure | 500 | Unexpected server error. |
Common errors
Missing API key:
{
"code": "Authentication.MissingApiKey",
"description": "API key is required.",
"type": "Authentication"
}
Invalid API key:
{
"code": "Authentication.InvalidApiKey",
"description": "API key is invalid.",
"type": "Authentication"
}
Missing idempotency key:
{
"code": "Operations.MissingIdempotencyKey",
"description": "Idempotency-Key header is required.",
"type": "Validation"
}
Operation not found:
{
"code": "Operations.NotFound",
"description": "The requested operation could not be found.",
"type": "NotFound"
}
Unsupported operation type:
{
"code": "Operations.UnsupportedType",
"description": "The requested operation type is not supported for this workspace.",
"type": "Validation"
}
Error handling recommendations
For Validation errors, fix the request before retrying.
For Authentication errors, check that the X-API-KEY header is present and valid.
For Forbidden errors, confirm that the API key belongs to the correct workspace and has access to the requested resource.
For NotFound errors, confirm that the resource ID is correct.
For Failure errors, retry safely. If you are retrying a mutating operation request, reuse the same Idempotency-Key.
Do not generate a new idempotency key when retrying the same operation. A new key creates a new request identity and may create a duplicate operation.
Webhooks
Understand how Floint sends operation updates to your system. Learn how to configure endpoints, verify signatures, handle retries, and process event payloads safely.
Webhooks are how Floint sends operation updates to your system.
Instead of constantly polling the API, your backend receives an HTTP POST request whenever an operation reaches a state that requires your attention.
Floint sends webhooks when an operation moves to:
WaitingForAction
Succeeded
Failed
You will not receive webhooks for Pending. Pending is an internal processing state.
How webhooks work
When your application creates an operation, Floint processes it asynchronously.
As the operation moves through its lifecycle, Floint sends webhook events to your configured endpoint. This keeps your backend in sync with the latest operation state.
A typical webhook flow looks like this:
Your application creates an operation
↓
Floint accepts and processes the operation
↓
The operation status changes
↓
Floint sends a signed webhook event
↓
Your backend verifies the signature
↓
Your backend processes the event
↓
Your backend responds with 2xx
Your webhook endpoint must be publicly reachable and must accept POST requests with a JSON body.
Example webhook endpoint:
https://yourapp.com/webhooks/floint
Setting up your webhook endpoint
To receive webhook events, register your webhook URL in the Floint dashboard.
During the sandbox stage, webhook configuration may also be handled during onboarding.
Your endpoint should:
Accept POST requests
Use HTTPS
Read the raw request body
Verify the Floint signature
Respond with a 2xx status code
Process events idempotently
When you create a webhook endpoint, Floint generates a webhook secret.
Store this secret securely. You will use it to verify webhook signatures.
The webhook secret is shown only once.
Webhook event structure
Floint sends webhook events as JSON.
Example payload:
{
"operationId": "550e8400-e29b-41d4-a716-446655440000",
"type": "onramp",
"status": "Succeeded",
"providerName": "example_provider",
"providerExternalId": "provider_1234567890",
"completedAtUtc": "2026-04-14T10:30:40Z"
}
Fields
| Field | Type | Description |
|---|---|---|
| operationId | string | The Floint operation ID. |
| type | string | Operation type, such as onramp or offramp. |
| status | string | The status that triggered the webhook. |
| providerName | string | The provider that handled the operation, if available. |
| providerExternalId | string | Provider-side reference ID, if available. |
| completedAtUtc | string | ISO 8601 timestamp for completion, when applicable. |
Some sandbox payloads may include additional debug fields such as provider response data or delivery metadata. These fields are useful during testing, but your production integration should rely mainly on the stable operation fields: operationId, type, status, and timestamps.
Webhook statuses
Floint sends webhook events for operation statuses that require your system to react.
WaitingForAction
The operation is waiting for the user to complete an external step.
This may happen when a provider requires the user to open a hosted checkout, complete a redirect flow, or finish another interaction outside your application.
Example:
{
"operationId": "550e8400-e29b-41d4-a716-446655440000",
"type": "onramp",
"status": "WaitingForAction",
"nextAction": {
"type": "redirect",
"url": "https://provider.example/checkout/session_123"
}
}
Your application should use nextAction to guide the user through the required step.
After the user completes the action, Floint continues processing the operation.
Succeeded
The operation completed successfully.
Example:
{
"operationId": "550e8400-e29b-41d4-a716-446655440000",
"type": "onramp",
"status": "Succeeded",
"providerName": "example_provider",
"providerExternalId": "provider_1234567890",
"completedAtUtc": "2026-04-14T10:30:40Z"
}
Your application can now treat the operation as complete.
Failed
The operation failed.
This may happen because the provider rejected the flow, the user did not complete the required step, retries were exhausted, or an unrecoverable error occurred.
Example:
{
"operationId": "550e8400-e29b-41d4-a716-446655440000",
"type": "onramp",
"status": "Failed",
"providerName": "example_provider",
"providerErrorCode": "provider_error",
"providerErrorMessage": "The provider could not complete the operation.",
"completedAtUtc": "2026-04-14T10:30:40Z"
}
Your application should treat Failed as a terminal state.
If needed, you can retrieve the operation and logs through the API for debugging.
Webhook signature verification
Every webhook from Floint is signed.
You should always verify the signature before processing the webhook payload. This protects your system from forged requests.
Floint includes two signature headers:
| Header | Format | Description |
|---|---|---|
| X-Floint-Signature | v1= |
HMAC-SHA256 signature of the webhook payload. |
| X-Floint-Timestamp | ISO 8601 | Timestamp of the delivery attempt. |
Signature format
Floint creates the signature using the timestamp, the raw request body, and your webhook secret.
canonical_message = "{timestamp}.{raw_request_body}"
signature = HMAC-SHA256(webhook_secret, canonical_message)
header = "v1=" + hex(signature)
Important: verify the signature using the raw request body, not the parsed JSON body.
If your framework parses the body before verification, the signature may fail because the raw payload has changed.
Verification steps
To verify a webhook:
1. Read the raw request body as bytes.
2. Extract X-Floint-Timestamp.
3. Extract X-Floint-Signature.
4. Build the canonical message: {timestamp}.{raw_body}.
5. Compute HMAC-SHA256 using your webhook secret.
6. Compare your computed signature with the received signature.
7. Reject the request if the signatures do not match.
8. Optionally reject old timestamps to protect against replay attacks.
Use a constant-time comparison when comparing signatures.
Node.js example
const crypto = require('crypto');
function verifyWebhook(rawBody, headers, secret) {
const timestamp = headers['x-floint-timestamp'];
const receivedSignature = headers['x-floint-signature']?.replace('v1=', '');
if (!timestamp || !receivedSignature) return false;
const message = `${timestamp}.${rawBody}`;
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(message)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expectedSignature, 'hex'),
Buffer.from(receivedSignature, 'hex')
);
}
Express example:
app.post('/webhooks/floint', express.raw({ type: 'application/json' }), (req, res) => {
const isValid = verifyWebhook(
req.body,
req.headers,
process.env.FLOINT_WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(req.body);
// Process event here
res.sendStatus(200);
});
Python example
import hmac
import hashlib
def verify_webhook(raw_body: bytes, headers: dict, secret: str) -> bool:
timestamp = headers.get("x-floint-timestamp", "")
received = headers.get("x-floint-signature", "").removeprefix("v1=")
if not timestamp or not received:
return False
message = f"{timestamp}.{raw_body.decode()}".encode()
expected = hmac.new(secret.encode(), message, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, received)
Flask example:
@app.route("/webhooks/floint", methods=["POST"])
def floint_webhook():
raw_body = request.get_data()
is_valid = verify_webhook(
raw_body,
request.headers,
os.environ["FLOINT_WEBHOOK_SECRET"]
)
if not is_valid:
return "Invalid signature", 401
event = request.get_json(force=True)
# Process event here
return "", 200
Responding to webhooks
Your endpoint must return a 2xx HTTP status code to acknowledge that the event was received.
Floint treats any non-2xx response as a failed delivery.
This includes:
3xx redirects
4xx client errors
5xx server errors
Timeouts
Connection failures
Your webhook handler should respond quickly.
A good pattern is:
Verify signature
Store or enqueue the event
Return 200 OK
Process the event asynchronously
Do not perform long-running business logic before responding to the webhook.
Fast acknowledgement example
app.post('/webhooks/floint', express.raw({ type: 'application/json' }), async (req, res) => {
const isValid = verifyWebhook(
req.body,
req.headers,
process.env.FLOINT_WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(req.body);
// Store or enqueue first
await queue.enqueue(event);
// Acknowledge delivery
res.sendStatus(200);
});
Retry policy and delivery guarantees
Floint uses at-least-once webhook delivery.
This means your endpoint may receive the same event more than once.
A duplicate can happen if:
Your endpoint responds slowly
A network issue occurs
Floint does not receive a 2xx response
A retry is triggered after your system already processed the event
Your webhook handler must be idempotent.
The safest approach is to store processed event identifiers or operation IDs and ignore duplicates.
Retry behaviour
If your endpoint returns a non-2xx response or times out, Floint retries delivery automatically using exponential backoff.
Each delivery attempt is recorded in the operation audit log.
Webhook delivery results may appear as log entries such as:
ClientDeliverySucceed
ClientDeliveryFailed
MovedToDls
If retries are exhausted, the event may be moved to dead-letter storage.
You can still retrieve operation data directly through the API:
GET /operations/{operationId}
X-API-KEY: your_api_key_here
Idempotent webhook handling
Because webhooks are delivered at least once, your backend must handle duplicate events safely.
Example pattern:
async function handleWebhook(event) {
const alreadyProcessed = await db.processedEvents.exists(event.operationId);
if (alreadyProcessed) {
return;
}
await db.processedEvents.insert(event.operationId);
switch (event.status) {
case 'WaitingForAction':
await handleUserActionRequired(event);
break;
case 'Succeeded':
await handleOperationSucceeded(event);
break;
case 'Failed':
await handleOperationFailed(event);
break;
}
}
For production systems, you may want to store a dedicated event ID if your webhook payload includes one. If not, use a combination of operationId and status.
Test webhook endpoint
Use the test webhook endpoint to confirm that your webhook URL is reachable before creating real operations.
POST /workspaces/{workspaceId}/webhooks/test
Example response:
{
"isDelivered": true,
"statusCode": 200,
"responseBody": "OK",
"error": null,
"attemptedAtUtc": "2026-04-14T10:30:45Z"
}
If the test fails, check that:
Your endpoint is publicly reachable
Your endpoint uses HTTPS
Your endpoint accepts POST requests
Your server returns a 2xx response
Your firewall or hosting provider is not blocking requests
Your handler does not timeout
Example payloads for all statuses
WaitingForAction
{
"operationId": "550e8400-e29b-41d4-a716-446655440000",
"type": "onramp",
"status": "WaitingForAction",
"nextAction": {
"type": "redirect",
"url": "https://provider.example/checkout/session_123"
}
}
Succeeded
{
"operationId": "550e8400-e29b-41d4-a716-446655440000",
"type": "onramp",
"status": "Succeeded",
"providerName": "example_provider",
"providerExternalId": "provider_1234567890",
"completedAtUtc": "2026-04-14T10:30:40Z"
}
Failed
{
"operationId": "550e8400-e29b-41d4-a716-446655440000",
"type": "onramp",
"status": "Failed",
"providerName": "example_provider",
"providerErrorCode": "provider_error",
"providerErrorMessage": "The provider could not complete the operation.",
"completedAtUtc": "2026-04-14T10:30:40Z"
}
Best practices
Verify every webhook signature before processing the event.
Use the raw request body for signature verification.
Respond with 2xx quickly and process events asynchronously.
Make your webhook handler idempotent.
Store operation IDs and webhook events for debugging and reconciliation.
Do not rely only on webhooks for support tooling. Use GET /operations/{operationId} when you need to inspect the latest state.
Do not expose webhook secrets in frontend code, public repositories, or client-side environments.
Rotate your webhook secret if you believe it has been exposed.
Security & Compliance
Review API key handling, webhook verification, data privacy, rate limits, and compliance notes. Use this section to prepare your integration for production.
Security is critical for any integration that touches payment-related flows.
Floint is designed so your application can work with one operation layer while provider-specific execution, statuses, and webhook delivery are handled underneath. To keep your integration safe, you should follow the practices in this section when storing API keys, verifying webhooks, handling user data, and preparing for production.
Security best practices
Keep API keys server-side
Your Floint API key authenticates requests from your workspace.
Do not expose API keys in frontend code, mobile apps, browser environments, public repositories, logs, screenshots, or client-side configuration.
Your API key should only be used from your backend.
X-API-KEY: your_api_key_here
If your API key is exposed, rotate it as soon as possible or contact the Floint team.
Use HTTPS everywhere
All production integrations should use HTTPS.
This applies to:
API requests to Floint
Webhook endpoints receiving Floint events
Redirect URLs used in user-facing flows
Internal services handling operation data
Webhook endpoints must be publicly reachable and should only accept secure HTTPS traffic.
Verify webhook signatures
Every webhook from Floint is signed.
Your backend should verify the webhook signature before processing the payload. This helps confirm that the request was sent by Floint and was not forged by a third party.
Floint includes signature headers with every webhook:
| Header | Description |
|---|---|
| X-Floint-Signature | HMAC-SHA256 signature of the webhook payload. |
| X-Floint-Timestamp | Timestamp of the webhook delivery attempt. |
Always verify the signature using the raw request body before parsing the JSON payload.
If verification fails, reject the request.
Store secrets securely
Store API keys, webhook secrets, and provider credentials in a secure environment.
Use environment variables, secret managers, or your hosting provider’s encrypted secret storage.
Do not store secrets in:
Frontend code
Git repositories
Local config files committed to source control
Public logs
Shared screenshots
Unencrypted documents
If a secret is exposed, rotate it.
Make webhook handling idempotent
Floint uses at-least-once webhook delivery.
This means your endpoint may receive the same event more than once.
Your webhook handler must be idempotent. Processing the same webhook twice should not create duplicate actions in your system.
A common pattern is to store processed operation IDs or event identifiers and ignore duplicates.
async function handleWebhook(event) {
const alreadyProcessed = await db.processedEvents.exists(event.operationId);
if (alreadyProcessed) {
return;
}
await db.processedEvents.insert(event.operationId);
// process event
}
Respond quickly to webhooks
Your webhook endpoint should acknowledge receipt as quickly as possible.
A recommended pattern:
Verify signature
Store or enqueue the event
Return 2xx response
Process the event asynchronously
Do not run long business logic before returning a response. Slow responses may trigger retries.
Rate limits and quotas
Floint may apply rate limits to protect platform stability and prevent abuse.
Rate limits can apply to:
API requests
Operation creation
Operation search
Webhook test requests
Dashboard actions
During the sandbox stage, limits may be adjusted based on workspace configuration and testing needs.
If your integration expects high volume, contact the Floint team before production access so limits and throughput requirements can be reviewed.
When a rate limit is exceeded, Floint may return an error response. Your system should handle this safely by backing off and retrying later.
A good retry strategy should use:
Exponential backoff
Idempotency keys for mutating requests
Timeout handling
Logging for failed attempts
Do not aggressively retry failed requests without delay.
Compliance & KYC notes
Floint is an orchestration layer for provider-backed payment operations.
Depending on the operation type and provider used, compliance checks such as KYC, KYB, sanctions screening, transaction monitoring, or user verification may be handled by the underlying provider or required as part of the provider flow.
Floint does not remove the need to comply with applicable laws, regulations, or provider requirements.
Your team is responsible for understanding the regulatory requirements that apply to your product, users, jurisdiction, and use case.
In some flows, an operation may move to WaitingForAction because the user needs to complete a provider-hosted step, such as identity verification, checkout confirmation, or another required interaction.
Example:
{
"operationId": "550e8400-e29b-41d4-a716-446655440000",
"type": "onramp",
"status": "WaitingForAction",
"nextAction": {
"type": "redirect",
"url": "https://provider.example/checkout/session_123"
}
}
Your application should present the required action to the user and wait for Floint webhook updates as the operation continues.
Data privacy
Floint may process and store data related to operations, webhook delivery, provider responses, request metadata, logs, and integration activity.
This data may be used for:
Operation processing
Status tracking
Webhook delivery
Debugging
Support
Audit logs
Security monitoring
Platform reliability
Your application should avoid sending unnecessary sensitive data in operation payloads.
Only include the data required to process the operation.
Do not send secrets, private keys, seed phrases, passwords, or unnecessary personal information in operation payloads or metadata.
Logging and sensitive data
Operation logs are useful for debugging and support, but logs should not be treated as a place to store sensitive information.
Avoid including sensitive data in:
Operation payloads
Request metadata
Webhook URLs
Error messages
Client-side logs
Support screenshots
If your system stores Floint operation IDs, webhook events, or API responses, protect them according to your internal security policies.
Production readiness
Before moving to production, your integration should be reviewed for security and operational readiness.
Your team should confirm that:
API keys are stored only on the backend
Webhook signatures are verified
Webhook events are handled idempotently
Duplicate webhook delivery is safe
Operation IDs are stored for support and reconciliation
Errors are logged and monitored
Secrets are not exposed in frontend code
HTTPS is used for all public endpoints
Rate limit and retry behaviour is handled correctly
You should also test the full operation lifecycle in sandbox:
Create operation
Handle WaitingForAction
Receive Succeeded webhook
Receive Failed webhook
Verify webhook signatures
Retry failed API requests safely
Search operations
Inspect operation logs
Test webhook delivery failures
Security checklist
Before going live, review this checklist:
Store API keys securely
Do not expose API keys client-side
Use HTTPS for webhook endpoints
Verify every webhook signature
Use raw request body for signature verification
Reject invalid signatures
Handle duplicate webhooks safely
Return 2xx quickly from webhook endpoints
Process webhook events asynchronously
Store operation IDs for reconciliation
Log errors without exposing sensitive data
Rotate secrets if exposed
Contact Floint before high-volume production usage
Compliance disclaimer
Floint provides infrastructure for operation orchestration across payment providers.
Floint does not provide legal, tax, regulatory, or compliance advice.
Your team is responsible for ensuring that your product, user flows, jurisdictions, and use cases comply with applicable laws, regulations, provider terms, and internal compliance requirements.
For production access, additional provider review, compliance checks, KYB/KYC configuration, or approval steps may be required depending on the flow and provider.
Troubleshooting
Find common errors, webhook delivery issues, operation debugging steps, and support guidance. Use this section when something does not behave as expected.
This section helps you debug common issues when integrating with Floint.
Most integration problems fall into one of these areas:
Authentication
Operation creation
Idempotency
Webhook delivery
Status handling
Provider processing
Logs and debugging
When something does not behave as expected, start with the operation ID. The operation ID is the best reference for checking status, reviewing logs, and contacting support.
Common errors
Floint returns errors in a consistent structure.
Example:
{
"code": "Operations.NotFound",
"description": "The requested operation could not be found.",
"type": "NotFound"
}
Each error includes:
code
description
type
The code is machine-readable.
The description explains the issue.
The type gives the general error category.
Missing or invalid API key
If your request is missing an API key or the key is invalid, Floint returns an authentication error.
Example:
{
"code": "Authentication.InvalidApiKey",
"description": "API key is missing or invalid.",
"type": "Authentication"
}
Check that your request includes the X-API-KEY header.
X-API-KEY: your_api_key_here
Make sure the key belongs to the correct workspace and environment.
A sandbox API key should be used only with the sandbox API base URL.
Missing Idempotency-Key
All mutating operation requests require an Idempotency-Key.
If the header is missing, Floint returns a validation error.
Example:
{
"code": "Operations.MissingIdempotencyKey",
"description": "Idempotency-Key header is required.",
"type": "Validation"
}
Include a unique idempotency key when creating an operation.
POST /operations
X-API-KEY: your_api_key_here
Idempotency-Key: 7f3c2a1b-4e8d-4f9a-b2c1-0e8f7a6b5d4c
Content-Type: application/json
Use a new key for each new operation.
Reuse the same key only when retrying the same request after a timeout or network issue.
Operation not found
If you request an operation that does not exist or does not belong to your workspace, Floint returns a not found error.
Example:
{
"code": "Operations.NotFound",
"description": "The requested operation could not be found.",
"type": "NotFound"
}
Check that:
The operation ID is correct
The operation belongs to your workspace
You are using the correct API key
You are using the correct environment
If you created the operation in sandbox, make sure you are checking it through the sandbox API.
Unsupported operation type
If your workspace does not support the requested operation type, Floint returns a validation error.
Example:
{
"code": "Operations.UnsupportedType",
"description": "The requested operation type is not supported for this workspace.",
"type": "Validation"
}
Check supported operation types:
GET /operations/types/supported
X-API-KEY: your_api_key_here
Example response:
["onramp", "offramp"]
If the operation type you need is not listed, contact the Floint team.
Webhook not received
If your system does not receive a webhook, first check whether the operation reached a webhook-triggering status.
Floint sends webhooks for:
WaitingForAction
Succeeded
Failed
Floint does not send webhooks for Pending.
If the operation is still Pending, your system should wait or check the operation status later.
Check operation status
Use the operation ID to check the current state.
GET /operations/{operationId}
X-API-KEY: your_api_key_here
If the status is Pending, the operation is still being processed.
If the status is WaitingForAction, Succeeded, or Failed, a webhook should be delivered to your configured endpoint.
Check webhook configuration
Make sure your webhook URL is configured correctly.
Your webhook endpoint must:
Use HTTPS
Be publicly reachable
Accept POST requests
Accept JSON payloads
Return a 2xx response
Respond before timeout
Example webhook URL:
https://yourapp.com/webhooks/floint
Avoid using local URLs such as:
http://localhost:3000/webhooks/floint
For local testing, use a tunneling tool or a public test endpoint.
Send a test webhook
Use the test webhook endpoint to confirm delivery.
POST /workspaces/{workspaceId}/webhooks/test
Example response:
{
"isDelivered": true,
"statusCode": 200,
"responseBody": "OK",
"error": null,
"attemptedAtUtc": "2026-04-14T10:30:45Z"
}
If isDelivered is false, check the returned statusCode, responseBody, and error.
Common causes include:
Webhook URL is not reachable
Endpoint does not accept POST
Endpoint returns 401, 403, 404, or 500
Endpoint redirects instead of returning 2xx
Signature verification fails
Server times out before responding
Firewall blocks the request
Webhook signature verification fails
If your webhook signature verification fails, check that you are using the raw request body.
Do not parse the JSON body before verifying the signature.
Floint signs this message:
{timestamp}.{raw_request_body}
The signature is sent in:
X-Floint-Signature: v1=<hex>
X-Floint-Timestamp: 2026-04-14T10:30:45Z
Check that:
You are using the correct webhook secret
You are reading the raw body before parsing JSON
You are including the timestamp in the signed message
You are removing the v1= prefix before comparing
You are using HMAC-SHA256
Your server is not modifying the request body
If the webhook secret was lost or exposed, rotate it and update your backend configuration.
Duplicate webhooks
Floint uses at-least-once webhook delivery.
This means your endpoint may receive the same webhook more than once.
Duplicate delivery can happen when:
Your endpoint responds slowly
A network issue occurs
Floint does not receive a 2xx response
A retry is triggered after your system already processed the event
Your webhook handler must be idempotent.
Store processed operation IDs or event identifiers and ignore duplicates.
Example:
async function handleWebhook(event) {
const alreadyProcessed = await db.processedEvents.exists(event.operationId);
if (alreadyProcessed) {
return;
}
await db.processedEvents.insert(event.operationId);
// process event
}
If your webhook payload includes a dedicated event ID in the future, use that instead of only operationId.
Operation stuck in Pending
An operation in Pending means Floint has accepted the operation and is processing or routing it.
This may happen while:
Floint is routing the operation
A provider is processing the request
Floint is waiting for a provider response
A provider webhook has not been received yet
The operation is being retried
Check the operation logs:
GET /operations/{operationId}/logs
X-API-KEY: your_api_key_here
Look for log entries such as:
OperationAccepted
RoutedToAdapter
ProcessedByAdapter
ProviderResponseReceived
ProviderDeliveryFailed
If the operation stays in Pending longer than expected, contact support with the operation ID.
Operation is WaitingForAction
WaitingForAction means the user needs to complete an external step.
This may include:
Opening a provider-hosted checkout
Completing a redirect flow
Confirming payment details
Completing a verification step
The operation may include a nextAction object.
Example:
{
"operationId": "550e8400-e29b-41d4-a716-446655440000",
"type": "onramp",
"status": "WaitingForAction",
"nextAction": {
"type": "redirect",
"url": "https://provider.example/checkout/session_123"
}
}
Your application should present the required action to the user.
After the user completes the step, Floint continues processing the operation. It may return to Pending, then move to Succeeded or Failed.
If the user does not complete the action, the operation may eventually fail depending on provider behaviour and timeout rules.
Operation failed
A Failed status means the operation reached a terminal failure state.
This can happen because:
The provider rejected the operation
The user did not complete the required action
A provider-side error occurred
Retries were exhausted
The operation could not be routed
An unrecoverable error occurred
Retrieve the operation:
GET /operations/{operationId}
X-API-KEY: your_api_key_here
Check fields such as:
providerErrorCode
providerErrorMessage
completedAtUtc
currentProviderName
clientDeliveryAttemptCount
Then inspect logs:
GET /operations/{operationId}/logs
X-API-KEY: your_api_key_here
The logs can help identify where the failure happened.
A Failed operation should be treated as final unless Floint support advises otherwise.
To start a new flow, create a new operation with a new Idempotency-Key.
Debugging operations
When debugging an operation, use this flow.
First, retrieve the operation:
GET /operations/{operationId}
X-API-KEY: your_api_key_here
Check:
status
type
createdAtUtc
completedAtUtc
currentProviderName
providerExternalId
providerErrorCode
providerErrorMessage
clientDeliveryAttemptCount
Then retrieve the logs:
GET /operations/{operationId}/logs
X-API-KEY: your_api_key_here
Review the sequence of events.
A normal successful flow may look like:
OperationAccepted
RoutedToAdapter
ProcessedByAdapter
ProviderResponseReceived
ClientDeliverySucceed
A failed webhook delivery flow may include:
ClientDeliveryFailed
ClientDeliveryFailed
MovedToDls
A provider-side failure may include:
RoutedToAdapter
ProcessedByAdapter
ProviderDeliveryFailed
Failed
Use the logs to understand whether the issue happened before provider execution, during provider processing, or during webhook delivery to your system.
Search operations
Use search when you do not have a specific operation ID or want to inspect multiple operations.
GET /operations/search?pageNumber=1&pageSize=20
X-API-KEY: your_api_key_here
You can filter by status, type, provider, creation date, and other fields.
Examples:
GET /operations/search?status=Failed&pageNumber=1&pageSize=20
GET /operations/search?type=onramp&pageNumber=1&pageSize=20
GET /operations/search?createdAtFrom=2026-04-14T00:00:00Z&pageNumber=1&pageSize=20
Search is useful for dashboards, support, reconciliation, and operational review.
Environment mismatch
If something cannot be found or behaves unexpectedly, check that you are using the correct environment.
Sandbox and production data are separate.
A sandbox operation cannot be retrieved from a production endpoint, and a production API key should not be used against the sandbox API.
Sandbox base URL:
https://sandbox.api.floint.xyz
If you are testing, make sure your API key, workspace, webhook URL, and operation IDs all belong to the sandbox environment.
Before contacting support
Before contacting support, collect the relevant details.
Include:
Workspace name
Environment
Operation ID
Request timestamp
Endpoint called
Request payload if safe to share
Error response
Webhook delivery timestamp
Webhook response status code
Relevant log entries
Do not send API keys, webhook secrets, private keys, passwords, or sensitive customer data through unsecured channels.
Support contact
If you cannot resolve the issue, contact Floint support.
hello@floint.xyz
When contacting support, include the operation ID and a short description of what happened.
Example:
Environment: Sandbox
Operation ID: 550e8400-e29b-41d4-a716-446655440000
Issue: Webhook not received after operation reached Succeeded
Expected: Webhook delivered to https://yourapp.com/webhooks/floint
Actual: No request received by our server
The more specific the report, the faster the issue can be investigated.
Changelog
Track API updates, version changes, fixes, and breaking changes. Use this section to stay aligned with the latest Floint releases.
This changelog tracks updates to the Floint API, sandbox environment, documentation, and integration behaviour.
Floint is currently in an early release stage. API behaviour may change as we test the platform with early partners, improve the operation model, and refine provider orchestration.
Use this section to understand what changed between versions, whether an update is breaking or non-breaking, and what stage the API is currently in.
Versioning
Floint uses semantic versioning with pre-release labels during early development.
Version format:
MAJOR.MINOR.PATCH-prerelease.N
Examples:
0.0.1-alpha.1
0.0.1-alpha.2
0.0.2-alpha.1
0.1.0-beta.1
0.1.0
1.0.0
The version number communicates both the release stage and the compatibility expectations.
Release stages
Alpha increment
Example:
0.0.1-alpha.1 → 0.0.1-alpha.2
An alpha increment means the product stage and API contract are mostly the same, but something has been fixed, adjusted, or improved internally.
This type of release may include:
Pipeline or infrastructure fixes
Hotfixes for broken endpoints
Environment configuration changes
Small bug fixes
Documentation corrections
Internal sandbox adjustments
This is used when the same alpha version continues, but a small fix or internal improvement is shipped.
Compatibility is not guaranteed during alpha.
Alpha patch release
Example:
0.0.1-alpha.2 → 0.0.2-alpha.1
An alpha patch release means something changed in the product, but the change is expected to be small and backward-compatible.
This type of release may include:
New endpoints
Small API improvements
Non-breaking logic changes
Feedback-based fixes
New sandbox behaviour
Developer experience improvements
The API is still considered unstable while the alpha label is present, even if the change is intended to be non-breaking.
Beta release
Example:
0.0.X-alpha.N → 0.1.0-beta.1
A beta release means Floint is ready to be tested by selected external partners.
At this stage, the basic flow should work end-to-end, and the team has tested the main integration path internally.
A beta release may include:
Working sandbox flow
Operation creation
Operation status retrieval
Webhook delivery
Basic provider execution
Operation logs
Initial partner testing
Improved documentation
Beta is more stable than alpha, but the API may still change before a stable release.
Compatibility is not guaranteed while the beta suffix is present.
Stable MVP releases
Example:
0.1.0
0.1.1
0.2.0
A 0.x release without an alpha or beta suffix means the release is more stable and suitable for active MVP usage.
The API may be used by selected partners, but it is still below 1.0.0, which means the product can continue to evolve before the first stable public API.
Patch releases may include fixes and small backward-compatible improvements.
Minor releases may include new features, new endpoints, expanded provider support, or improvements to operation handling.
While the API is below 1.0.0, breaking changes are still possible, but they should be documented clearly.
Version 1.0.0
Version 1.0.0 marks the first stable public API.
At this stage, Floint takes stronger responsibility for backward compatibility.
A 1.0.0 release means:
The API is documented and stable
Core contracts are defined
Real customers are using the product in production
Breaking changes are handled through major versions
After 1.0.0, breaking changes should only be introduced in a new major version.
Example:
1.0.0 → stable public API
2.0.0 → breaking changes
Compatibility policy
While a version includes an alpha or beta suffix, compatibility is not guaranteed.
This means endpoints, fields, response objects, status behaviour, webhook payloads, dashboard behaviour, and sandbox configuration may change as the product is improved.
Once the pre-release suffix is removed, semantic versioning applies more strictly.
General rule:
PATCH = bug fixes and small backward-compatible changes
MINOR = new backward-compatible features
MAJOR = breaking changes
The main rule:
alpha / beta = no compatibility guarantee
no suffix = stronger semantic versioning expectations
1.0.0+ = stable public API with major-version breaking changes
Breaking changes
A breaking change is any update that may require changes in your integration.
Examples include:
Removing an endpoint
Renaming a field
Changing required request fields
Changing webhook payload structure
Changing status names
Changing lifecycle behaviour
Changing authentication requirements
Changing idempotency behaviour
Changing error response structure
Changing signature verification logic
When possible, Floint will document breaking changes clearly and provide migration guidance.
During alpha and beta stages, breaking changes may happen more frequently as the API is refined.
Non-breaking changes
A non-breaking change should not require changes in your integration.
Examples include:
Adding a new optional response field
Adding a new endpoint
Adding a new supported provider
Adding a new supported operation type
Improving error descriptions
Improving documentation
Fixing bugs without changing API contracts
Improving internal routing behaviour
Improving sandbox reliability
Even when a change is non-breaking, avoid relying on undocumented fields or internal debug data.
Changelog entry format
Each changelog entry should include:
Version
Release date
Release stage
Summary
Added
Changed
Fixed
Breaking changes
Migration notes
Example:
## 0.1.0-beta.1 — 2026-04-14
First external beta release.
### Added
- Initial sandbox access for selected partners.
- Operation creation endpoint.
- Operation status retrieval.
- Webhook delivery for WaitingForAction, Succeeded, and Failed.
- Operation search.
- Operation logs.
- Provider availability endpoint.
- Webhook signature verification.
### Changed
- Improved operation lifecycle documentation.
- Updated webhook payload examples.
### Fixed
- Fixed operation search pagination behaviour.
### Breaking changes
- None.
### Migration notes
- No migration required.
Current release
0.0.1-alpha.1
Initial internal alpha release.
Added
Workspace setup
Sandbox API access
Operation creation
Operation status retrieval
Operation search
Operation logs
Supported operation types endpoint
Available providers endpoint
Webhook configuration
Test webhook delivery
Basic authentication through X-API-KEY
Idempotency-Key support for operation creation
Initial unified statuses
Known limitations
Production access is not public yet
Workspace creation is handled manually
Provider availability is limited by sandbox configuration
Routing and fallback behaviour may depend on environment setup
API contracts may change during alpha
Webhook payloads may evolve
Documentation is still being refined
Staying updated
Review the changelog before making integration changes or moving from sandbox to production.
If you are an early partner, the Floint team may also notify you directly about important API changes, migration steps, or breaking changes.
For questions about a release, contact:
hello@floint.xyz