Account and balance
Your account, how you fund it, what you can spend, and what you are charged.
How your balance works#
You send us funds and we credit your balance, charging one load fee at that point. Everything after that draws on the balance: a top-up moves value onto a card at 1:1 with no further fee, and closing a card sweeps what is left back. GET /me reports it under float.
Two figures constrain a top-up and available_usd is the smaller of them. balance_usd is what you have funded, less everything drawn down. limit_usd is a ceiling we may set on how much card value you can have outstanding at once, and it is null when no ceiling applies. Fees reduce your balance but never consume limit headroom, because the limit is measured against card value alone.
available_usd, do not derive itThe figure the limit arm subtracts is not returned by this endpoint, so you cannot recompute available_usd from the payload. A top-up above it returns 402 rather than clamping.
Your rates are the ones on your agreement. Read them from GET /fees rather than hardcoding them, so a change reaches you without a deploy. The transaction rates there are a published rate card: reconcile against the fee each purchase actually carried: exactly on its card.authorized event, or to the cent on its row in GET /cards/{id}/transactions. Its settlement event does not repeat the fee.
Fund your balance#
- Before your first transfer, tell us through your contact or the support channel which wallet or wallets you will send from. We register them to your account, and the same address counts on every network. A wallet can belong to one account only, so never name an exchange's hot wallet or a wallet that relays or solves bridge transfers; our own wallets and card deposit addresses cannot be registered either. Registration is handled by us and is not visible through the API.
- Read your funding address from GET /funding/addresses just before you send. It lists each network you can fund on (Polygon, BNB Chain and Base) with the tokens accepted there (USDC and USDT), and is refreshed at least every 10 minutes. Never copy an address from these pages or send to a card address.
- Send a listed token from a registered wallet, directly to the address listed for the network you send on, at least 10 USD per transfer. Credit is automatic only when exactly one wallet paid into your funding address in that transaction, that wallet is registered to your account (or, if your account is set to accept any wallet, from any wallet, such as an exchange), and it paid directly: the wallet itself sent the transaction straight to the token contract, or it is a smart wallet, such as a multisig, executing its own transfer. A gasless, bundled (ERC-4337) or relayed transfer, or a payment routed through another contract such as a router, batcher, bridge or solver, is not credited automatically. A transfer under 10 USD is never picked up, so it cannot be credited: it is rejected with reason
below_minimum. - Submit the transaction hash and its network to POST /funding as soon as the transaction is broadcast. We verify it on-chain immediately.
- We credit your balance once the funds arrive: the amount sent on-chain, minus the load fee on your agreement. On Polygon this is usually within minutes. On BNB Chain and Base the funds are routed first and we credit only once your transaction is final on its network, so it can take several hours. Follow it with GET /funding/{fundingId} or the `float.credited` webhook.
| Status | Meaning |
|---|---|
pending | Received. Either not yet found on its network, and re-checked every couple of minutes for 24 hours, or verified and waiting for the funds to arrive |
credited | Added to your balance and announced with float.credited. GET /me reflects it, and GET /ledger has a funding row referenced funding-<NETWORK>-<tx_hash> plus its load fee row with :fee appended. With reason credited_separately, it was credited to your balance by other means after a review: fee_usd and credited_usd are null, amount_usd is still the amount sent, and there is no webhook for it |
rejected | Cannot be credited as submitted, or a credit we reversed. reason says why. Only not_found can be corrected, by submitting the hash again with the right network |
review | Verified, but not credited automatically: a person decides. reason says why. We resolve it: it then becomes credited, with the same webhook and ledger rows (for the amount sent, or no more than arrived when the two differ), credited with reason credited_separately, or rejected with reason rejected_by_operator. There is nothing to resubmit |
| Reason | Status | Meaning |
|---|---|---|
transaction_failed | rejected | The transaction failed on-chain |
not_a_funding_transfer | rejected | Nothing was transferred to your funding address in that transaction on that network |
unsupported_token | rejected | A transfer reached your funding address, but in a token not accepted on that network |
mixed_tokens | rejected | The transaction sent both USDC and USDT to your funding address |
below_minimum | rejected | Less than 10 USD. It is never picked up, so it cannot be credited |
unregistered_sender | rejected | The only wallet that paid is registered to another account, so it is that account's money. Wallets registered to other accounts are rejected whether or not your account is set to accept any wallet |
bridge_fill | rejected | On any network: the transaction delivered bridged funds into the funding address, the arrival of a deposit made elsewhere. The depositor claims their own transaction on the network they sent from. If you bridged the funds yourself, contact us with both hashes |
before_automatic_funding | rejected | Sent before automatic funding started. Those transfers were settled separately |
before_account_opened | rejected | The transaction predates your account |
not_found | rejected | Not found on that network within 24 hours of your first submission, or still unreadable a day later. Submit the hash again, with the right network if it was wrong: it is looked up again |
rejected_by_operator | rejected | We reviewed it and it cannot be credited |
reversed_by_operator | rejected | It was credited, and we reversed the credit because it was not your money. See below |
unregistered_sender | review | The wallet that sent it is registered to no account. Tell us if it is yours. This does not arise if your account is set to accept any wallet, unless the wallet is registered to another account (which is rejected instead) |
operator_sender | review | One of our own wallets paid into the funding address in that transaction |
multiple_senders | review | More than one wallet paid into the funding address in that transaction, even when one of them is registered to another account |
routed_transfer | review | The wallet did not pay directly: the transfer was gasless, bundled (ERC-4337) or relayed, or routed through another contract such as a router, batcher, bridge or solver |
precision | review | The amount has more than 6 decimal places |
unlisted_token | review | That token is not listed on that network at the moment |
not_arrived | review | Verified, but no matching arrival within 72 hours of the transaction. Reviewed shortly after that window |
ambiguous_match | review | On Polygon: more than one arrival was reported for the same transaction |
amount_mismatch | review | The arrival reported for it differs from what the chain shows in token, amount or sending wallet |
receipt_changed | review | On BNB Chain or Base: the transaction is no longer on its chain as it was verified, or has been missing from it for over 2 hours |
not_final | review | On BNB Chain or Base: an arrival matched, but the transaction did not become final on its network within 6 hours |
check_failed | review | The chain could not be read for this submission long after its window |
already_credited | review | The same funds were already credited to a balance by other means |
held_by_operator | review | We held it, your account is suspended, or your account was credited for the same transaction before and that credit was reversed |
credited_separately | credited | After a review: the funds were credited to your balance by other means |
Whose money it is is decided first, then the amount. A transaction that one of our own wallets paid into goes to review with reason operator_sender, and one that more than one wallet paid into goes to review with reason multiple_senders. Otherwise, when the only wallet that paid is registered to another account, it is rejected with reason unregistered_sender: it is that account's money. One from a wallet registered to nobody, or not paid directly, goes to review, and only then are the decimals and the token checked. Chain facts are read only from sources we trust, or confirmed by independent sources that agree, before anything is credited.
Each transaction can be credited once. POST /funding needs no Idempotency-Key: submitting the same hash with the same network returns the same record, so a retry is always safe. If you named the wrong network, submit the hash again with the right one while it is still unverified (pending with a null amount_usd, or rejected with reason not_found): the same submission, under the same id, is looked up on that network. Resubmitting a hash rejected as not_found with the same network looks it up again too. The 24 hours run from your first submission. Once the transaction is verified, its network is fixed and a resubmission returns the same record. At most 5 of your submissions can be unverified at once: past that, a new submission answers 429 TOO_MANY_PENDING, which carries no Retry-After, so wait until some are found or rejected as not_found. A correction of your own is still accepted.
A network GET /funding/addresses does not list at the moment answers 400, and nothing is stored. When the BNB Chain and Base addresses cannot be read, GET /funding/addresses answers 503, and so does a submission on BNB Chain or Base; Polygon submissions keep working.
A hash belongs to the account whose registered wallet sent the money, when it is the only wallet that paid and it was registered before any other account claimed the hash. That account's submission replaces any other account's claim on the same hash that has not been paid, whether pending, in review or rejected, including one we rejected. Failing that, the first account to submit the hash on the right network keeps it, and another account's claim that named another network and never verified there is replaced by one that verifies. A replaced claim disappears: it no longer appears in GET /funding, and GET /funding/{fundingId} answers 404 for it. A paid claim is never displaced. When another account's claim on the hash could still give way to yours (it is still being looked up, or is verified on your network but not paid) and yours cannot be read on its network yet, you get 503 UNAVAILABLE: retry shortly. Otherwise you get 409 ALREADY_SUBMITTED, and retrying does not help: if the transaction is yours, check the network and that your sending wallet is registered to your account, then contact us. A transaction already credited to a balance by other means answers 409 ALREADY_CREDITED. Funding on any network other than Polygon, BNB Chain and Base is settled by arrangement with us.
If a credited submission turns out not to be your money, we can reverse it. Its status becomes rejected with reason reversed_by_operator, and fee_usd and credited_usd keep their original figures. GET /ledger gains a negative funding row referenced funding-reversal-<NETWORK>-<tx_hash> and a positive fee row with :fee appended, which returns the load fee, so your balance drops by credited_usd and can go below zero. No webhook is sent for a reversal.
Returns the account behind the key, the scopes the key carries, your lifetime card counts, your float broken down, a summary of your load rate, and the commission you have earned. This is the call to make first when wiring up an integration, and again whenever you need a current spendable balance. Everything it returns is scoped to your own account.
idstringnamestring | nullcontact_emailstring | nullcreated_atstring | nullnamestringprefixstringscopesarray of stringmodestringrate_limit_per_minuteintegertotalintegeractiveintegerlimitinteger | nullfunded_usdnumberspent_usdnumberbalance_usdnumberlimit_usdnumber | nullavailable_usdnumberktap_pctnumberyour_markup_pctnumbertotal_pctnumberktap_fee_usdnumberyour_fee_usdnumberlands_on_card_usdnumberaccrued_usdnumberpaid_out_usdnumberowed_usdnumberlast_payout_atstring | nullUNAUTHORIZEDFORBIDDENBAD_REQUESTRATE_LIMITEDUNAVAILABLEfloat.available_usdis the only figure a top-up is checked against. It is the smaller of your balance and any spending limit we have set, floored at zero.- You cannot recompute
available_usdfrom this payload, because the figure it subtracts is not returned here. Read it, do not derive it. Whenfloat.limit_usdisnullit equalsbalance_usd. cards.totalcounts every card you have ever ordered. Closing a card does not return capacity, so your remaining allowance iscards.limitminuscards.total.
curl -sS -X GET 'https://virtual.ktap.io/api/partner/v1/me' \
-H 'X-API-Key: ktap_live_...'{
"data": {
"partner": {
"id": "7c1f4b2e-9a63-4d18-b0f5-2ea84c9d1367",
"name": "Acme Ltd",
"contact_email": "ops@acme.example",
"created_at": "2026-03-14T09:22:41.518Z"
},
"key": {
"name": "Production server",
"prefix": "ktap_live_ef27ebea",
"scopes": [
"users:read",
"users:write",
"cards:read",
"cards:write"
],
"mode": "live",
"rate_limit_per_minute": 120
},
"cards": {
"total": 128,
"active": 121,
"limit": 250
},
"float": {
"funded_usd": 50000,
"spent_usd": 18495.55,
"balance_usd": 31504.45,
"limit_usd": 20000,
"available_usd": 1854.45
},
"fees": {
"ktap_pct": 0.01,
"your_markup_pct": 0.02,
"total_pct": 0.03,
"example_on_100_usd": {
"ktap_fee_usd": 1,
"your_fee_usd": 2,
"lands_on_card_usd": 97
}
},
"earnings": {
"accrued_usd": 412.5,
"paid_out_usd": 300,
"owed_usd": 112.5,
"last_payout_at": "2026-08-01T10:00:00.000Z"
}
}
}Returns the funding address for each network you can fund your balance on, with the tokens it accepts there, refreshed at least every 10 minutes. Only networks whose transaction hashes POST /funding can verify and credit are listed, and only addresses that are currently enabled. Send only a token listed here, from a wallet you have registered with us, to the address listed for the network you send on, and at least 10 USD per transfer.
addressesarraynetworkstringaddressstringtokensarrayUNAUTHORIZEDFORBIDDENBAD_REQUESTRATE_LIMITEDUNAVAILABLE- Read the addresses before each transfer rather than storing them. They are refreshed at least every 10 minutes, and a network or token that is not listed at that moment cannot be credited through
POST /funding. - Send at least 10 USD per transfer, from a wallet you have registered with us. A smaller transfer is never picked up, so it cannot be credited:
POST /fundingrejects it with reasonbelow_minimum. - A
503returns no address at all: wait and retry, and do not send until it answers. It never falls back to a guessed address, and it also answers503when only the BNB Chain and Base addresses cannot be read. The address in the example is illustrative: never send funds to an address copied from this documentation.
curl -sS -X GET 'https://virtual.ktap.io/api/partner/v1/funding/addresses' \
-H 'X-API-Key: ktap_live_...'{
"data": {
"addresses": [
{
"network": "POLYGON",
"address": "0x5c1E8A3D7f24B690e1a4C8d3F7B25e906A1D4c8E",
"tokens": ["USDC", "USDT"]
},
{
"network": "BNB",
"address": "0x5c1E8A3D7f24B690e1a4C8d3F7B25e906A1D4c8E",
"tokens": ["USDC", "USDT"]
},
{
"network": "BASE",
"address": "0x5c1E8A3D7f24B690e1a4C8d3F7B25e906A1D4c8E",
"tokens": ["USDC", "USDT"]
}
]
}
}Send USDC or USDT to the funding address GET /funding/addresses returns for the network you send on, then submit the transaction hash here. We verify it on-chain immediately, then credit your balance once the funds arrive: the amount sent on-chain, minus the load fee on your agreement. On Polygon this is usually within minutes. On BNB Chain and Base the funds are routed first and we credit only once your transaction is final on its network, so it can take several hours. Before your first transfer, tell us through your contact or the support channel which wallet or wallets you send from. A transfer is credited automatically only when exactly one wallet paid into your funding address in that transaction, that wallet is registered to your account (or, if your account is set to accept any wallet, from any wallet, such as an exchange), and it paid directly: the wallet itself sent the transaction straight to the token contract, or it is a smart wallet, such as a multisig, executing its own transfer. A gasless, bundled (ERC-4337) or relayed transfer goes to review. Anything else goes to review or is rejected. Accepted: USDC and USDT on Polygon, BNB Chain and Base, as GET /funding/addresses lists them, at least 10 USD per transfer, always sent to your funding address and never to a card address. No Idempotency-Key is needed: the call is idempotent on the transaction hash. Each transaction can be credited once.
Content-Typestringtx_hashstringrequirednetworkstringrequiredidstringnetworkstringtx_hashstringstatusstringreasonstring | nulltokenstring | nullamount_usdnumber | nullfee_usdnumber | nullcredited_usdnumber | nullcreated_atstringcredited_atstring | nullBAD_REQUESTUNAUTHORIZEDFORBIDDENBAD_REQUESTALREADY_SUBMITTEDALREADY_CREDITEDRATE_LIMITEDTOO_MANY_PENDINGUNAVAILABLEUNAVAILABLE- A
200means the hash is recorded, not that it is credited. Readstatus, then poll GET /funding/{fundingId} or listen for `float.credited`. Tell us which wallets you send from before your first transfer: credit is automatic only when exactly one wallet paid into your funding address, it is registered to your account (or, if your account is set to accept any wallet, from any wallet, such as an exchange), and it paid directly: it sent the transaction straight to the token contract itself or, as a smart wallet such as a multisig, executed its own transfer. When the only wallet that paid is another account's registered wallet, it isrejectedwith reasonunregistered_sender; one from an unregistered wallet, or gasless, bundled (ERC-4337), relayed or routed through another contract (routed_transfer), goes toreview. - No
Idempotency-Keyis needed: submitting is idempotent on the hash, so retry a timeout or a5xxwith the same hash and network. Named the wrong network? While your submission is unverified (pendingwith a nullamount_usd, orrejectedwith reasonnot_found), submit the same hash with the right network: the same submission, sameid, is looked up there. The 24 hours run from your first submission, so correct it early. Once the transaction is verified its network is fixed. At most 5 of your submissions can be unverified at once: past that, a new submission answers429 TOO_MANY_PENDING, with noRetry-After; a correction is still accepted. - Send only a token GET /funding/addresses lists for the network, only to the address it lists, at least 10 USD per transfer, and never to a card address, then submit as soon as the transaction is broadcast. A hash belongs to the account whose registered wallet alone sent the money (registered before any other account claimed the hash), and its submission replaces another account's unpaid claim; failing that, the first account to submit it on the right network keeps it. A paid claim is never displaced.
503 UNAVAILABLEmeans another account's claim on the hash could still give way to yours (it is still being looked up, or is verified on your network but not paid) and yours could not be verified yet: retry shortly. Retrying409 ALREADY_SUBMITTEDdoes not help: check the network and that your sending wallet is registered, then contact us. A transaction that delivered bridged funds into the funding address, on any network, isrejectedwith reasonbridge_fill: if you bridged them yourself, contact us with both hashes.
curl -sS -X POST 'https://virtual.ktap.io/api/partner/v1/funding' \
-H 'X-API-Key: ktap_live_...' \
-H 'Content-Type: application/json' \
-d '{"tx_hash":"0x4a7e2c9d1b8f3e6a5c0d7b2e9f4a1c8d3e6b0f5a2d9c7e4b1a8f6d3c0e5b2a91","network":"POLYGON"}'{
"data": {
"id": "3b9e6f1a-7c42-4d85-a1e0-5f2c8d9b4e63",
"network": "POLYGON",
"tx_hash": "0x4a7e2c9d1b8f3e6a5c0d7b2e9f4a1c8d3e6b0f5a2d9c7e4b1a8f6d3c0e5b2a91",
"status": "pending",
"reason": null,
"token": "USDC",
"amount_usd": 2500.25,
"fee_usd": null,
"credited_usd": null,
"created_at": "2026-09-23T10:15:02.114Z",
"credited_at": null
}
}Returns one submission to POST /funding and where it stands. Poll it until status is credited or rejected, or listen for the float.credited webhook instead. A submission in review is resolved by us and then becomes one of those two. A credited submission that was not your money can later be reversed by us, and then reads rejected with reason reversed_by_operator.
fundingIdstringidstringnetworkstringtx_hashstringstatusstringreasonstring | nulltokenstring | nullamount_usdnumber | nullfee_usdnumber | nullcredited_usdnumber | nullcreated_atstringcredited_atstring | nullUNAUTHORIZEDFORBIDDENNOT_FOUNDBAD_REQUESTRATE_LIMITED- Once
statusiscredited,credited_usdis what reached your balance andGET /mealready reflects it.amount_usdhere is always the amount sent on-chain, whilefloat.creditedcarries the amount credited, which after a review can be lower;fee_usdandcredited_usdmatch the webhook. - A
reviewstatus is ours to resolve: the submission verified but could not be credited automatically, andreasonsays why. It then becomescredited, with afloat.creditedwebhook;creditedwith reasoncredited_separatelyif the funds were credited to your balance by other means (no webhook, nullfee_usdandcredited_usd,amount_usdstill the amount sent); orrejectedwith reasonrejected_by_operator. Do not resubmit it. - A
creditedsubmission that was not your money can later becomerejectedwith reasonreversed_by_operator.fee_usdandcredited_usdkeep their figures,GET /ledgergains a negativefundingrow referencedfunding-reversal-<NETWORK>-<tx_hash>and a positive:feerow, and your balance drops bycredited_usd. No webhook is sent.
curl -sS -X GET 'https://virtual.ktap.io/api/partner/v1/funding/3b9e6f1a-7c42-4d85-a1e0-5f2c8d9b4e63' \
-H 'X-API-Key: ktap_live_...'{
"data": {
"id": "3b9e6f1a-7c42-4d85-a1e0-5f2c8d9b4e63",
"network": "POLYGON",
"tx_hash": "0x4a7e2c9d1b8f3e6a5c0d7b2e9f4a1c8d3e6b0f5a2d9c7e4b1a8f6d3c0e5b2a91",
"status": "credited",
"reason": null,
"token": "USDC",
"amount_usd": 2500.25,
"fee_usd": 25.0025,
"credited_usd": 2475.2475,
"created_at": "2026-09-23T10:15:02.114Z",
"credited_at": "2026-09-23T10:17:40.502Z"
}
}Returns your 50 most recent submissions to POST /funding, newest first, each with its status. There is no paging.
fundingsarrayidstringnetworkstringtx_hashstringstatusstringreasonstring | nulltokenstring | nullamount_usdnumber | nullfee_usdnumber | nullcredited_usdnumber | nullcreated_atstringcredited_atstring | nullcountintegerUNAUTHORIZEDFORBIDDENRATE_LIMITEDUNAVAILABLE- Returns your 50 most recent submissions and does not page. Keep the
ideachPOST /fundingreturns and read older submissions back by id. - A submission replaced by another account's claim, because that account's registered wallet sent the money or its claim verified on the right network, disappears from this list, and reading it by id answers
404.
curl -sS -X GET 'https://virtual.ktap.io/api/partner/v1/funding' \
-H 'X-API-Key: ktap_live_...'{
"data": {
"fundings": [
{
"id": "3b9e6f1a-7c42-4d85-a1e0-5f2c8d9b4e63",
"network": "POLYGON",
"tx_hash": "0x4a7e2c9d1b8f3e6a5c0d7b2e9f4a1c8d3e6b0f5a2d9c7e4b1a8f6d3c0e5b2a91",
"status": "credited",
"reason": null,
"token": "USDC",
"amount_usd": 2500.25,
"fee_usd": 25.0025,
"credited_usd": 2475.2475,
"created_at": "2026-09-23T10:15:02.114Z",
"credited_at": "2026-09-23T10:17:40.502Z"
},
{
"id": "8d4a2c7e-1f93-4b6d-9e05-c3a7b1f8d240",
"network": "BNB",
"tx_hash": "0x1f8c3e5a7d2b9046c1e8a3f5d7b2c9e4a6f1d8b3c5e7a2f9d4b6c1e8a3f50246",
"status": "rejected",
"reason": "not_a_funding_transfer",
"token": null,
"amount_usd": null,
"fee_usd": null,
"credited_usd": null,
"created_at": "2026-09-22T16:40:11.308Z",
"credited_at": null
}
],
"count": 2
}
}Returns your load rates, your own markup, and the card usage rates. Read your rates from here rather than hardcoding them, so a change on our side reaches you without a deploy. GET and PUT return the identical payload shape.
ktap_pctnumberload_from_float_pctnumberload_from_user_deposit_pctnumberyour_markup_pctnumbertotal_pctnumberktap_fee_usdnumberyour_fee_usdnumberlands_on_card_usdnumberusd_purchase_pctnumberfx_purchase_pctnumberhigh_risk_surcharge_pctnumberatm_pctnumbervisa_direct_pctnumbermonthly_per_card_usdnumberyour_markup_pctnumberUNAUTHORIZEDFORBIDDENBAD_REQUESTRATE_LIMITEDUNAVAILABLE- Rates are fractions, not percentages. A value of
0.02means 2%. - The rates under
transactionare a published rate card, not the figures any one movement is charged at. What a purchase was actually charged is on itscard.authorizedevent, not on its settlement event. Its row in GET /cards/{id}/transactions shows the card processor's figures rounded to the cent. Reconcile against those, not against this response.
curl -sS -X GET 'https://virtual.ktap.io/api/partner/v1/fees' \
-H 'X-API-Key: ktap_live_...'{
"data": {
"ktap_pct": 0.01,
"load_from_float_pct": 0.01,
"load_from_user_deposit_pct": 0.02,
"your_markup_pct": 0.02,
"total_pct": 0.03,
"example_on_100_usd": {
"ktap_fee_usd": 1,
"your_fee_usd": 2,
"lands_on_card_usd": 97
},
"transaction": {
"usd_purchase_pct": 0.01,
"fx_purchase_pct": 0.02,
"high_risk_surcharge_pct": 0.01,
"atm_pct": 0.04,
"visa_direct_pct": 0.02,
"monthly_per_card_usd": 1,
"your_markup_pct": 0.02
}
}
}Sets the rate you add on top of the KTAP load fee, as a fraction. The change takes effect on the next deposit quoted, and the response is the full GET /fees payload with the new rate applied. Any key holding users:write can change this rate for the whole account, with no approval step.
Content-Typestringmarkup_pctnumberrequiredktap_pctnumberload_from_float_pctnumberload_from_user_deposit_pctnumberyour_markup_pctnumbertotal_pctnumberktap_fee_usdnumberyour_fee_usdnumberlands_on_card_usdnumberusd_purchase_pctnumberfx_purchase_pctnumberhigh_risk_surcharge_pctnumberatm_pctnumbervisa_direct_pctnumbermonthly_per_card_usdnumberyour_markup_pctnumberBAD_REQUESTBAD_REQUESTBAD_REQUESTBAD_REQUESTUNAUTHORIZEDFORBIDDENBAD_REQUESTRATE_LIMITEDUNAVAILABLE- Send
markup_pctas a fraction.0.025is 2.5%. Sending2.5returns400. - The accepted range is
0to0.5inclusive, stored to five decimal places. A value with more precision is rounded on write and the response echoes the rounded figure. - This rate applies to direct card funding only. On a prepaid balance it changes nothing you are billed.
curl -sS -X PUT 'https://virtual.ktap.io/api/partner/v1/fees' \
-H 'X-API-Key: ktap_live_...' \
-H 'Content-Type: application/json' \
-d '{"markup_pct":0.025}'{
"data": {
"ktap_pct": 0.01,
"load_from_float_pct": 0.01,
"load_from_user_deposit_pct": 0.02,
"your_markup_pct": 0.02,
"total_pct": 0.03,
"example_on_100_usd": {
"ktap_fee_usd": 1,
"your_fee_usd": 2,
"lands_on_card_usd": 97
},
"transaction": {
"usd_purchase_pct": 0.01,
"fx_purchase_pct": 0.02,
"high_risk_surcharge_pct": 0.01,
"atm_pct": 0.04,
"visa_direct_pct": 0.02,
"monthly_per_card_usd": 1,
"your_markup_pct": 0.02
}
}
}