Skip to main content

Accept, return, freeze

Every deposit ends with one decision. You make it with one of three calls:

CallDecisionMeaning
POST /casino/deposit/{id}/acceptacceptedCredit the player. The casino is settled for the deposit.
POST /casino/deposit/{id}/returnreturnedSend the crypto back to an address you give.
POST /casino/deposit/{id}/freezefrozenHold the funds pending regulatory guidance.

A decision can be made only while the deposit's decision is pending. Once made, it is final. The API has no call to change or undo a decision.

If two decision calls for the same deposit arrive at the same time, exactly one wins. The other gets 409 with Cannot <action>: deposit decision is no longer 'pending' (already decided by a concurrent request). Nothing is written for the losing call.

Error bodies have a detail message and, for some errors, a code plus extra fields. The format and the full list are on the Errors page.

Accept​

POST https://quinix.byteconnect.us/casino/deposit/{id}/accept

The body is optional for an ordinary deposit. A restored late deposit requires the flag below.

FieldTypeRequiredDescription
adjust_to_receivedbooleanFor a mismatch or late depositDefault false. Set true to accept at the amount actually received when it differs from the quote. Always required for a restored late deposit, even when amounts match. See Amount mismatches and Late payments.
curl -X POST https://quinix.byteconnect.us/casino/deposit/4821/accept \
-H "X-API-Key: $API_KEY"

To send the flag:

curl -X POST https://quinix.byteconnect.us/casino/deposit/4821/accept \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"adjust_to_received": true}'
warning

Do not send Content-Type: application/json with an empty body. The API rejects it with 400 Malformed JSON in request body. Either send no body and no content type, or send a JSON object. adjust_to_received must be a JSON boolean: the string "true" is rejected.

When accept is allowed​

The endpoint checks these gates. The first failing check decides the error.

  1. Decision. The deposit's decision is pending.

  2. Payment status. One of:

    • the payment has at least one confirmation (status is Confirmed, ConfirmedApproved or ConfirmedKYTReview), or
    • the deposit is a fast deposit (no_conf or instant), its no_conf_state is eligible, and it is paid but unconfirmed (Succeed, Overpaid or Underpaid).

    A fast deposit whose funding transaction was double-spent is never acceptable.

  3. OFAC. ofac_status is clear or timed_out. This applies to instant deposits too.

  4. KYT. kyt_status is passed. Exception: an instant deposit may be accepted while KYT has not finished, if the market value of what arrived is within its instant_received_max_usd. A review or failed result always blocks.

  5. Amount and repricing. The received crypto equals the quote, or you sent adjust_to_received: true. Every restored late deposit requires that flag and successful repricing at the current market rate.

The deposit's acceptable flag reports decision, payment and screening readiness. It does not check the adjustment flag or whether late-payment repricing will succeed. See The acceptable flag.

Amount mismatches​

The player may send more or less than crypto_amount. Any difference counts, down to the smallest unit (1e-8). While the deposit is unconfirmed, its status shows Overpaid or Underpaid. At any time, compare confirmed_crypto with crypto_amount.

On a mismatch, /accept without the flag fails:

{
"detail": "Amount mismatch: quoted 0.0017517 BTC, received 0.0015 BTC. Send \"adjust_to_received\": true to accept at the actual received amount, or call /return to refund."
}

You then choose:

  • Accept at the received amount. Call /accept with adjust_to_received: true.
  • Return the funds. Call /return.

With adjust_to_received: true, the deposit is re-priced from the crypto received:

  • For an ordinary deposit, the rate is the one locked when the deposit was created. A restored late deposit uses the current market rate at acceptance instead.
  • The fee and spread percents are the ones this deposit was quoted with. Changes to the casino's fee configuration since then are not applied.
  • Every charge, the player amount and the casino's net are recomputed from the crypto received at the applicable rate, using the original fee and spread percentages.

The formulas are the crypto-mode formulas in Creating deposits.

danger

After an adjusted accept, the player amount changes. Credit the player the player_amount from the accept response or the deposit.accepted webhook, never the one from the create response.

Late payments​

A restored deposit marked late_payment: true requires adjust_to_received: true, even when the received crypto equals the original quote. It is repriced at the current market rate. The original quote is preserved in ByteFederal's records. Return is unchanged and still follows its existing gates.

Without the flag, accept returns HTTP 400 with code: late_payment_requires_current_rate and this exact detail:

Late payment: this deposit was paid after its quote expired. It can only be accepted at the current market rate: send "adjust_to_received": true to accept at the received amount re-priced now, or call /return to refund.

If the rate is unavailable, accept refuses with HTTP 502 late_payment_rate_unavailable; retry later. It does not fall back to the original rate. If the received crypto cannot be represented safely at the deposit's quote precision, accept refuses with HTTP 409 late_payment_received_precision; use return or contact ByteFederal.

Response​

A 200 means the deposit is accepted. The response carries the final amounts. This example is the deposit from Creating deposits, underpaid with 0.0015 BTC instead of 0.0017517 BTC and accepted with adjust_to_received: true:

{
"deposit_id": 4821,
"decision": "accepted",
"adjusted": true,
"crypto_amount": 0.0015,
"usd_amount": 88.2,
"player_amount": 85.631068,
"entity_net_usd": 84.77475728155339,
"affiliate_net_usd": 84.77475728155339,
"charges": [
{
"beneficiary": "AFFILIATE",
"kind": "FEE",
"paid_by": "PLAYER",
"percent": 0.03,
"amount_usd": 2.568932,
"amount_crypto": 0.00004369
},
{
"beneficiary": "BF",
"kind": "FEE",
"paid_by": "ENTITY",
"percent": 0.01,
"amount_usd": 0.856311,
"amount_crypto": 0.00001456
},
{
"beneficiary": "BF",
"kind": "SPREAD",
"paid_by": "PLAYER",
"percent": 0.02,
"amount_usd": 1.8,
"amount_crypto": 0.00003
}
],
"fee": 0,
"fee_usd": 0,
"bf_fee_usd": 0,
"bf_spread_usd": 1.8,
"affiliate_fee_usd": 2.568932,
"confirmed_crypto": 0.0015,
"crypto_rate": "58800"
}
FieldTypeDescription
deposit_idintegerThe deposit.
decisionstringAlways accepted.
adjustedbooleantrue if the deposit was re-priced to the received amount.
crypto_amountnumberThe final crypto amount, at the deposit's quote precision if adjusted.
usd_amountnumberThe final total paid by the player, in USD.
player_amountnumberThe final amount to credit the player, in USD.
entity_net_usdnumberThe final amount the casino is settled.
chargesarrayEvery charge at its final amount. See Charges.
confirmed_cryptonumber or nullThe crypto received on chain.
crypto_ratestring or nullThe rate used for acceptance, including spreads, as a decimal string.
affiliate_net_usd, fee, fee_usd, bf_fee_usd, bf_spread_usd, affiliate_fee_usdnumberDeprecated aliases. Read entity_net_usd and charges.

What accepting triggers​

  • A deposit.accepted webhook with the final amounts. See the Webhook event reference.
  • A receipt for the player: an SMS with a receipt link to the player's phone, and an email when ByteFederal has an email address for the player.
  • The deposit is included in the casino's settlement for entity_net_usd.

These run after the response is sent. They never delay or fail the accept call.

Accept errors​

Statuscodedetail
400Invalid deposit ID
400Malformed JSON in request body
400Decision is already 'accepted', cannot accept (the quoted decision varies)
400Amount mismatch: quoted 0.0017517 BTC, received 0.0015 BTC. Send "adjust_to_received": true to accept at the actual received amount, or call /return to refund.
404Deposit not found
409Cannot accept: the funding transaction was double-spent before confirmation.
409Cannot accept: transaction status is 'Succeed' (not yet confirmed). Wait for confirmation. (standard deposit, paid but unconfirmed)
409Cannot accept: no-conf deposit is not eligible yet (state: pending_guards). Wait for guard evaluation or confirmation. (the state varies; pending when not yet set)
409Cannot accept: transaction status is 'Pending'. (any other status, for example unpaid or timed out)
409ofac_screen_pendingCannot accept: OFAC screening has not completed yet. Wait for the ofac_complete webhook. Extra field ofac_deadline_at when the deadline is known.
409ofac_sanctionedCannot accept: a funding address failed OFAC screening. The deposit is frozen; contact ByteFederal compliance.
400late_payment_requires_current_rateLate payment: this deposit was paid after its quote expired. It can only be accepted at the current market rate: send "adjust_to_received": true to accept at the received amount re-priced now, or call /return to refund.
409late_payment_no_received_amountLate payment has no confirmed received amount yet
502late_payment_rate_unavailableUnable to fetch <currency> rate or Unable to value <currency> at the current rate. Retry later; the currency is the deposit's ticker.
409instant_received_over_capCannot accept before KYT: received value $650.00 exceeds the instant received ceiling of $600.00. The deposit continues on the KYT-Fast path — wait for kyt_status 'passed'. Extra fields received_usd, instant_received_max_usd.
409Cannot accept: KYT screening has not completed. Try again once kyt_status is 'passed'.
409Cannot accept: kyt_status is 'review', must be 'passed'. (also pending or failed)
409late_payment_received_precisionReceived crypto cannot be represented safely at this asset's quote precision; call /return or contact ByteFederal
409Cannot accept: deposit decision is no longer 'pending' (already decided by a concurrent request)
500Deposit charge ledger is invalid; contact ByteFederal
500Transaction has no market rate; cannot re-quote to the received amount
500Failed to accept deposit

A 409 usually means "not yet". Wait for the next webhook for this deposit and check its acceptable flag before calling again. For late_payment_received_precision, use return or contact ByteFederal instead.

Return​

POST https://quinix.byteconnect.us/casino/deposit/{id}/return

Send a JSON body with Content-Type: application/json. Without that header the API does not read the body, and the return cannot be processed.

FieldTypeRequiredDescription
return_addressstringYesThe address to send the crypto to, on the deposit's own chain. Must not be empty.
reasonstringNoFree-text reason, kept with the return. If present it must not be empty.
curl -X POST https://quinix.byteconnect.us/casino/deposit/4821/return \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"return_address": "bc1qexamplereturnaddress00000000000000000",
"reason": "Player cancelled the deposit"
}'
{
"deposit_id": 4821,
"decision": "returned",
"return_id": 317
}
FieldTypeDescription
deposit_idintegerThe deposit.
decisionstringAlways returned.
return_idintegerThe id of the queued return. The deposit.returned webhook carries it too.

When return is allowed​

All of these must hold:

  1. The deposit's decision is pending.
  2. ofac_status is clear or timed_out. Sanctioned funds can never be returned.
  3. kyt_status is passed.
  4. The payment status is exactly Confirmed.
  5. confirmed_crypto is greater than zero.
  6. No other return is already in progress for this deposit.
warning

Only status: "Confirmed" qualifies. A fast deposit cannot be returned before it confirms. A deposit whose status is ConfirmedKYTReview or ConfirmedApproved cannot be returned through the API, even after its KYT review ends in passed. Such a deposit can still be accepted. To return one, contact ByteFederal.

Check the address before you call​

ByteFederal does not validate return_address when you call /return. The decision becomes returned immediately and cannot be changed. If the address is wrong for the chain or malformed, the return does not complete, and ByteFederal has to resolve it by hand.

  • Validate the address format for the deposit's currency before calling.
  • For ETH, the address must be an ordinary account, not a contract. Returns to contract addresses are not supported and fail.

What happens on chain​

  • The full amount received (confirmed_crypto) is sent to return_address. No fee or spread is deducted. ByteFederal pays the network fee.
  • ByteFederal's refund processor checks for queued returns every 5 minutes. For ETH, the return can take an extra step when the funds must first be moved from the deposit address.
  • When the return transaction is broadcast, the payment status changes to Refund and you receive a transaction.refund webhook.

What returning triggers​

  • A deposit.returned webhook right away, with return_id, return_address and reason.
  • Later, the transaction.refund webhook described above, when the crypto is sent.

Return errors​

Statuscodedetail
400Invalid deposit ID
400Decision is already 'accepted', cannot return (the quoted decision varies)
400A validation body when return_address is missing or empty, or reason is empty. See the Errors page.
404Deposit not found
409ofac_screen_pendingCannot return: OFAC screening has not completed yet. Wait for the ofac_complete webhook.
409ofac_sanctionedCannot return: a funding address failed OFAC screening. The deposit is frozen; contact ByteFederal compliance.
409Cannot return: KYT screening has not completed. Try again once kyt_status is 'passed'.
409Cannot return: kyt_status is 'review', must be 'passed'. (also pending or failed)
409Cannot return: transaction status is 'Succeed' (must be 'Confirmed') (the quoted status varies)
409Cannot return: confirmed_crypto is 0 (must be > 0)
409A return is already in progress for this transaction
409Cannot return: deposit decision is no longer 'pending' (already decided by a concurrent request)
500Failed to process return

Freeze​

POST https://quinix.byteconnect.us/casino/deposit/{id}/freeze

Freezing holds a deposit pending regulatory guidance. The deposit is neither credited nor returned. No body.

curl -X POST https://quinix.byteconnect.us/casino/deposit/4821/freeze \
-H "X-API-Key: $API_KEY"
{
"deposit_id": 4821,
"decision": "frozen"
}

When freeze is allowed​

  1. The deposit's decision is pending.
  2. kyt_status is passed.

A deposit whose KYT has not finished, or is in review, cannot be frozen through the API.

What a frozen deposit means​

  • Accept, return and freeze are all refused with 400 Decision is already 'frozen', ....
  • The deposit is not included in the casino's settlement.
  • There is no API call to unfreeze. ByteFederal compliance resolves frozen deposits outside the API. Contact ByteFederal to resolve one.

Automatic freezes​

ByteFederal freezes a pending deposit itself in two cases:

  • KYT screening returns failed.
  • OFAC screening finds a sanctioned funding address (ofac_status: "hit").

These automatic freezes do not send a deposit.frozen webhook. You learn about them from the kyt_complete or ofac_complete webhook, and the deposit's decision reads frozen.

What freezing triggers​

A deposit.frozen webhook, for freezes made through this endpoint only.

Freeze errors​

Statusdetail
400Invalid deposit ID
400Decision is already 'accepted', cannot freeze (the quoted decision varies)
404Deposit not found
409Cannot freeze: KYT screening has not completed. Try again once kyt_status is 'passed'.
409Cannot freeze: kyt_status is 'review', must be 'passed'. (also pending or failed)
409Cannot freeze: deposit decision is no longer 'pending' (already decided by a concurrent request)

Webhook delivery for decisions​

The deposit.accepted, deposit.returned and deposit.frozen webhooks are queued when the decision is recorded and retried on failure. They go to the casino's webhook URL if one is set, otherwise to your API key's webhook URL. No webhook is sent if neither is configured. The decision itself is recorded either way. Payloads, signatures and retries are described in Webhooks and the Webhook event reference.