Funding Test Senders

Credit a sender's deposit account with simulated funds in the test environment, so you can run order flows end to end without moving real money.

Funding Test Senders

Overview

To run a fiat-funded order end to end in the test environment you need a sender that actually holds a balance. Rather than making a real bank transfer into your test virtual account and waiting for it to settle, you can credit the account directly with simulated funds.

This is a test-environment feature only. The endpoint is disabled in production and returns 403 FORBIDDEN there. The funds it creates are simulated: they exist only in the test environment's ledger and have no real-world value.

Table of Contents

  1. Prerequisites
  2. Crediting a sender
  3. Confirming the balance
  4. Limits
  5. Errors
  6. Permissions
  7. Funding stablecoin senders

1. Prerequisites

  • A sender that already has a deposit account in the currency you want to fund. If the sender has no account yet, provision one first with POST /v1/senders/{senderId}/virtual-bank-accounts/{currency}/setup-request.
  • An API key with the merchant:sender:write permission (merchant:*:* also matches).

2. Crediting a sender

curl -X POST \
  'https://api.stg.mesta.xyz/v1/senders/<SENDER_ID>/accounts/mock-deposit?amount=50&currency=USD' \
  -H 'x-api-key: <API_KEY_ID>' \
  -H 'x-api-secret: <API_KEY_SECRET>'

Both values are query parameters — there is no request body.

ParameterRequiredDescription
amountYesAmount to credit, in the deposit currency. Must be greater than 0 and no more than 200 per request.
currencyTechnically no — in practice yesCurrency of the deposit account to credit, for example USD, EUR, GBP or MXN. The sender must already have a deposit account in this currency. Omitting it makes the service guess a currency from the sender's profile, which can resolve a different deposit account than you intend and fail with NO_DEPOSIT_BANK_ACCOUNT_FOUND. Always pass it explicitly.

A successful call returns 201:

{
  "requestId": 177021679
}

That response only confirms that the simulated deposit was accepted. It does not mean the balance has moved yet — see the next section.

To fund more than 200, repeat the call:

for i in 1 2 3 4; do
  curl -X POST \
    "https://api.stg.mesta.xyz/v1/senders/<SENDER_ID>/accounts/mock-deposit?amount=200&currency=USD" \
    -H 'x-api-key: <API_KEY_ID>' \
    -H 'x-api-secret: <API_KEY_SECRET>'
done

Mind the rate limit in section 4 — that loop consumes 4 of your 10 requests.


3. Confirming the balance

The credit is applied asynchronously. The endpoint hands the deposit off to the banking provider's simulator, and the balance updates once the resulting webhook is processed — normally within a few seconds.

Poll the balances endpoint until the amount appears:

curl 'https://api.stg.mesta.xyz/v1/senders/<SENDER_ID>/balances' \
  -H 'x-api-key: <API_KEY_ID>' \
  -H 'x-api-secret: <API_KEY_SECRET>'
{
  "data": [
    { "currency": "USD", "balance": "50.00" }
  ],
  "requestId": 177021680
}

If the balance has not moved after roughly a minute, treat the deposit as failed rather than slow, and contact your Mesta representative with the requestId from the original call.


4. Limits

LimitValue
Maximum per request200, in the deposit currency
Minimum per requestGreater than 0
Requests10 per 2 hours, for this endpoint, per source IP address

Three things about the rate limit are worth knowing before you script against it:

  • The quota is keyed on your source IP, not your API key. Everything calling from behind the same network egress address — your whole CI fleet, your whole office — draws on one shared bucket of 10. Rotating API keys does not get you a fresh quota.
  • Every rejected request counts towards the quota. Not just validation failures: a 401 from a bad key, a 403 from a missing permission, a 404 from a wrong sender ID, and a 400 from a bad amount all consume one of the 10. Get a single call working by hand before putting one in a loop.
  • The window is 2 hours, not minutes. Exhausting the quota means waiting, so budget your calls. Combined with the 200 cap, one source IP can credit at most 2,000 per currency per 2 hours.

When the quota is exhausted the endpoint returns 429:

{
  "error": {
    "CODE": "REQUEST_THROTTLED",
    "MESSAGE": "You have made too many requests. Please try again later.",
    "DETAILS": {
      "retryAfterMs": 5423118
    }
  },
  "requestId": 177021681
}

DETAILS.retryAfterMs is how long to wait, in milliseconds, before the next request is accepted.


5. Errors

StatusCodeMeaning
400INVALID_MOCK_DEPOSIT_AMOUNTamount is missing, zero, negative, or not a number.
400MOCK_DEPOSIT_AMOUNT_LIMIT_EXCEEDEDamount is above the 200 per-request cap. Split it across several calls.
400NO_DEPOSIT_BANK_ACCOUNT_FOUNDThe sender has no deposit account in the requested currency. Provision one first.
400MOCK_DEPOSIT_NOT_SUPPORTED_FOR_ACCOUNTThe sender's deposit account is held with a banking provider that has no deposit simulator. Fund a different currency, or make a real test transfer into the account.
403FORBIDDENThe API key lacks merchant:sender:write, or the call was made against production, where the endpoint is disabled.
404ENTITY_NOT_FOUNDNo sender with that ID exists under your merchant account.
429REQUEST_THROTTLEDRate limit exhausted. See section 4.

6. Permissions

The API key must carry merchant:sender:write. A wildcard merchant:*:* key also matches. Without it, every call returns 403 FORBIDDEN.

Scoping is implicit: you can only fund senders that belong to your own merchant account. A sender ID belonging to another merchant resolves as 404, not 403.


7. Funding stablecoin senders

This endpoint funds fiat deposit accounts. If you are testing a stablecoin-funded order instead, you do not need it — send test USDC or USDT to the sender's deposit wallet address from a testnet faucet. See Getting Test Tokens for faucet links and network details.


Did this page help you?