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.

1

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.

2

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.

3

Quick Start

This quick start shows the basic path from access to your first operation.

4

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
5

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.

6

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.

7

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.

8

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.

9

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.

10

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.

1

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
2

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.

3

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
4

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
5

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.

6

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
7

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.

8

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.

1

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.

2

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"
  }
}
3

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.

4

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.
5

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
6

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.

7

**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.

8

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.

9

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.

10

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.

11

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.

12

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.

1

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.

2

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
3

Operations endpoints

Operations are the main object in Floint.

Use operation endpoints to create operations, retrieve status, search operation history, and inspect logs.

4

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 PendingWaitingForActionSucceeded, 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.

5

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.

6

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.

7

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.
8

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.

9

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.

10

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.

11

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.

12

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.

13

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.

14

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.
15

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"
}
16

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.

17

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 PendingPending is an internal processing state.

1

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
2

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.

3

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: operationIdtypestatus, and timestamps.

4

Webhook statuses

Floint sends webhook events for operation statuses that require your system to react.

5

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.

6

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.

7

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.

8

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.
9

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.

10

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.

11

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
12

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.

13

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);
});
14

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.

15

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
16

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.

17

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
18

Example payloads for all statuses

19

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"
}
20

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.

21

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.

1

Security best practices

2

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.

3

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.

4

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.

5

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.

6

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
}
7

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.

8

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.

9

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.

10

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.

11

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.

12

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
13

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
14

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.

15

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.

1

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.

2

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.

3

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.

4

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.

5

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.

6

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.

7

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 WaitingForActionSucceeded, or Failed, a webhook should be delivered to your configured endpoint.

8

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.

9

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 statusCoderesponseBody, 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
10

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.

11

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.

12

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.

13

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.

14

Operation failed

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.

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.

15

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.

16

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.

17

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.

18

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.

19

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.

20

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.

1

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.

2

Release stages

3

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.

4

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.

5

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.

6

Stable MVP releases

Example:

0.1.0
0.1.1
0.2.0

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.

7

Version 1.0.0

Version 1.0.0 marks the first stable public API.

At this stage, Floint takes stronger responsibility for backward compatibility.

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
8

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
9

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.

10

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.

11

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.
12

Current release

13

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
14

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
15