Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.bringin.app/llms.txt

Use this file to discover all available pages before exploring further.

What is a Connection?

A connection (BringinLink) is a permanent standing order that links a crypto address to a bank account. Once active, conversions happen automatically — any amount, any time, no further API calls needed. Think of it as a bridge: one side is crypto, the other is fiat. Funds sent to either side are automatically converted and delivered to the other.

Supported Connection Types

TypeDirectionSubtypesWhat happens
FIAT_TO_CRYPTOEUR to cryptoONCHAINUser sends EUR via SEPA, receives crypto at their address
CRYPTO_TO_FIATCrypto to EURONCHAIN, LNUser sends crypto, receives EUR via SEPA to their bank

Supported Currencies & Networks

CurrencyNetworksDefault
BTCBTCBTC
ETHETHETH
USDCUSDC (Ethereum), POLYGONMust specify
USDTUSDT (Polygon), ETH (Ethereum)Must specify
POLPOL, POLYGONPOLYGON
Invalid currency/network combinations return a 400 INVALID_CURRENCY_NETWORK_COMBINATION error. For example, BTC on POLYGON or ETH on BTC are not valid.

Buy Connection (EUR to Crypto)

1

You provide a crypto address

Your app passes the user’s destination address when creating the connection.
2

Bringin returns a deposit IBAN

Once the connection is active, you receive a unique SEPA IBAN.
3

User sends EUR from their bank

Any amount, any time — regular bank transfer to the deposit IBAN.
4

Bringin converts and delivers crypto

EUR is received, converted at market rate, and sent to the linked address.
Your app stores and displays the deposit IBAN. The user sends EUR whenever they want to buy crypto — it’s as simple as a bank transfer.

Sell Connection (Crypto to EUR)

On-chain

1

You provide an IBAN + bank details

Your app passes the user’s bank account details when creating the connection.
2

Bringin returns a crypto deposit address

Once the connection is active, you receive a unique deposit address.
3

User sends crypto to the deposit address

Any amount, any time — standard on-chain transaction.
4

Bringin converts and delivers EUR

Crypto is received, converted at market rate, and sent to the linked bank account via SEPA.

Lightning Network

For BTC sell connections, you can use Lightning for instant, low-fee transactions:
1

You provide an IBAN + Lightning address username

Your app passes the bank details and a unique Lightning username (e.g., alice_wise).
2

Bringin creates a Lightning address

The username becomes {username}@bringin.xyz — a permanent receive address.
3

User sends BTC via Lightning

Any Lightning wallet can send to the address. Instant settlement.
4

Bringin converts and delivers EUR

BTC is converted at market rate and sent to the linked bank account via SEPA.
Use deterministic addresses for on-chain connections. Connections are permanent — use a fixed derivation path (e.g., m/84'/0'/0'/0/0) for Bitcoin addresses. Avoid getNewReceiveAddress() which generates a different address each time.

How to Create a Connection

Bundle everything into POST /application/connect. Bringin handles onboarding, connection creation, and SMS confirmation. You receive webhooks when it’s done.
POST /api/v0/application/connect
Request
{
  "email": "user@example.com",
  "callback": "https://yourapp.com/bringin-webhooks",
  "ref": "your-internal-user-id",
  "direction": "FIAT_TO_CRYPTO",
  "btcAddress": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
  "currency": "BTC",
  "network": "BTC"
}
Bringin handles the rest. You’ll receive:
  1. /verification-status webhook with the per-user api-key
  2. /connection-status webhook with the deposit IBAN (or deposit address / LN address)
See Onboarding API and Webhooks for details. Use this if you already have the user’s per-user api-key and want granular control over the connection lifecycle.
1

List existing connections

Always call GET /bringin-link first before creating a new connection. This prevents duplicate errors and lets you reuse pending connections.
GET /api/v0/bringin-link
Check the response:
  • ACTIVE link for same destination — Use it directly, no creation needed
  • PENDING link — Show OTP screen with the existing challengeId
  • INITIATING link — Poll for status update
  • No match — Safe to create a new connection
2

Create the connection

POST /api/v0/bringin-link
Request
{
  "name": "Blue Wallet",
  "type": "FIAT_TO_CRYPTO",
  "subtype": "ONCHAIN",
  "destinationAddress": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
  "destinationCurrency": "BTC",
  "network": "BTC"
}
Returns 202 Accepted with status: "INITIATING". Creation is asynchronous — you must poll for updates.
3

Poll for status

Poll GET /bringin-link/{id} every 2-3 seconds until the status changes from INITIATING.
StatusAction
INITIATINGKeep polling (processing takes 5-15 seconds)
PENDINGShow OTP screen — use challengeId from the response
ACTIVEConnection is ready (standing order was reused, no OTP needed)
FAILEDShow a user-friendly error (see handling failures)
If still INITIATING after 60 seconds, show a timeout message and suggest contacting support@bringin.xyz.
4

Confirm with SMS OTP

When the status is PENDING, the user receives an SMS OTP. Confirm it:
POST /api/v0/bringin-link/confirm
Request
{
  "challengeId": "abc123",
  "verificationCode": "123456"
}
On success, the connection becomes ACTIVE and auto-conversions begin.If the user needs a new code, call POST /bringin-link/resend-otp with the existing challengeId.
The OTP expires 30 minutes after creation. The resend endpoint does NOT reset this timer. If expired, create a new connection.
See Connections API Reference for full endpoint docs.

Status Lifecycle

StatusTerminal?Description
INITIATINGNoRecord created, async processing in progress
PENDINGNoStanding order created, awaiting SMS OTP confirmation
ACTIVENoOTP confirmed, auto-conversions enabled
FAILEDYesCreation failed (support can resume)
EXPIREDYesOTP not confirmed within 30 minutes
INACTIVEYesCancelled by user

Best Practices

Before calling POST /bringin-link, always call GET /bringin-link to list the user’s existing connections. This prevents:
  • 409 DUPLICATE_BRINGIN_LINK — A link already exists for this destination
  • 409 DUPLICATE_DESTINATION_ADDRESS — Address already has an active connection
  • 409 DUPLICATE_IBAN — IBAN already has an active connection
  • Unnecessary resource creation on each failed attempt
If a connection exists in PENDING status:
  1. Check if standingOrder.challengeExpiresAt is still in the future
  2. If valid — show the OTP screen with the existing challengeId
  3. If the user needs a new code — call POST /bringin-link/resend-otp
  4. If expired — wait for auto-expiry, then create a new connection
The name field must be unique across all non-terminal connections (INITIATING, PENDING, ACTIVE) for the user. Names from FAILED, EXPIRED, and INACTIVE connections are freed up for reuse.
Lightning address usernames (lnAddress field):
  • 3-30 characters, lowercase alphanumeric plus _ and -
  • Must start and end with an alphanumeric character
  • No consecutive _ or -
  • Globally unique — if taken, the API returns 409 LN_ADDRESS_EXISTS
  • The resulting address is {username}@bringin.xyz

Handling Failures

When a connection creation fails (status: FAILED):
Never show raw error messages to end users. The error field contains technical details meant for debugging. Instead, show:“Something went wrong while setting up your connection. Please contact support@bringin.xyz for help.”
Failed connections are resumable by the Bringin support team. Your app does not need to handle resume logic — direct users to support. Provide a “Try Again” button that starts a fresh creation flow (list existing connections first, then create).

Cancelling a Connection

To cancel an active connection, use the standing order cancellation flow:
1

Initiate cancellation

POST /api/v0/bringin-link/{standingOrderId}/cancel
The response depends on whether the standing order is shared with other connections:Soft cancel (Lightning connections sharing a standing order):
Response
{ "immediate": true }
Only your app’s connection is deactivated. No OTP needed. Done.Hard cancel (last/only connection for this standing order):
Response
{
  "challengeId": "cancel_challenge_123",
  "dateExpires": "2026-03-24T09:05:00.000Z"
}
An SMS OTP is sent to the user. Proceed to step 2.
2

Confirm cancellation with OTP

Only needed when the initiate response contains challengeId:
POST /api/v0/bringin-link/{standingOrderId}/cancel/confirm
Request
{
  "challengeId": "cancel_challenge_123",
  "verificationCode": "654321"
}
On success, the standing order is cancelled and all associated connections become INACTIVE.

Error Reference

HTTPError CodeWhenWhat to do
400INVALID_BTC_ADDRESSBTC address fails format checkShow “Please enter a valid Bitcoin address”
400INVALID_CURRENCY_NETWORK_COMBINATIONUnsupported currency + network pairShow valid networks for the currency
400RECENTLY_FAILED_IBANSame IBAN failed within last 10 minutesShow “Please wait before retrying this IBAN”
409DUPLICATE_NAMEName already used by active/pending connectionPrompt for a different name
409DUPLICATE_IBANActive connection already exists for this IBANUse the existing connection
409DUPLICATE_BRINGIN_LINKConnection already exists for this destinationUse the existing connection
409DUPLICATE_DESTINATION_ADDRESSActive connection for this address + currencyUse the existing connection
409LN_ADDRESS_EXISTSLightning address takenChoose a different username
409CONCURRENT_REQUESTAnother creation in progressWait 2-3 seconds and retry
429TOO_MANY_PENDING_BRINGIN_LINKS10+ pending connectionsConfirm or wait for existing to expire
Most 409 errors can be avoided by listing existing connections before creating a new one.