Reference
FAQ and troubleshooting
Answers to the problems partners hit most, grouped by symptom. Each answer ends with the page that has the fix.
Errors on any request
A request returns 401
With an API key: the mp-api-key header is missing or empty, the key is mistyped or cut short, it belongs to the other environment (production keys start with mgk_live_, sandbox keys with mgk_sandbox_), or it was revoked. The request also fails if it sends both mp-api-key and an Authorization header, or sends the key as Authorization: Bearer mgk_… instead of in mp-api-key. Every service except the user service also answers 401 when your business has an IP allow-list and the request comes from an address that isn't on it: if a key that works from one server gets 401 from another, check that server's address is on your allow-list. Retrying with the same key doesn't help: fix the key, then resend the same request. See When a request returns 401.
A payment or FX request returns 403 'Forbidden' or 'Unauthorized access'
Your API user lacks the permission for that action. Each endpoint's description in the API reference names the permission it needs. Check what your API user has with Get the current user (permissions[].), then ask your dashboard administrator or Multigate contact to add the missing one. On FX endpoints, 403 also means the entityId header isn't one of your businesses: set it to your client ID. See Errors.
A customer, account, beneficiary or receivable request returns 404 'Resource not found'
On the client service, a missing permission answers 404 "Resource not found", not 403. Check your API user's permissions with Get the current user and ask your administrator to add the one the endpoint names (for example view accounts). See Errors.
A request returns 404 for an ID I know exists
Check three things: the ID comes from the same environment (sandbox IDs don't exist in production), it's the right kind of ID (an accountId isn't an account number; a customer ID isn't your client ID), and it belongs to your business or one of your customers. See Acting for your customers.
List accounts or List beneficiaries returns 404
These two lists answer 404 ("account not found", "beneficiary not found") when nothing matches your filters, or when you ask for a page past the last one. Treat it as an empty list. See Pagination.
A request returns 409
Something already exists: a refund of this inflow ("Refund currently processing", "Refund completed already"), a lock of this quote ("Rate already locked"), an FX reference ("Duplicate reference"), a beneficiary ("beneficiaries already exist"), a customer email ("Sub-Client already exists"), an account in that foreign currency at every partner bank ("account already exist") or an open approval request. Don't send it again; look up the existing object. See Idempotency.
A 400 says 'failed_validation'
That's fixed text. The reasons are in the errors array: each entry names the field (fieldName) and the problem. See Error body shapes.
A field I sent was ignored, with no error
Fields an endpoint doesn't define are removed, not rejected, so a misspelled optional field is silently dropped. Compare your payload with the API reference. See Errors.
I got an HTML page, a 502 or a 504
The gateway couldn't reach the service or stopped waiting after 60 seconds. For a request that moves money, the outcome is unknown: look it up before you retry, and retry only with the same unique. See Unknown outcomes.
Authentication
A request returns 403 'This action is not allowed with an API key'
You tried to manage API keys or credentials as an API user: keys are managed by dashboard users only. To stop a key working, revoke it in the dashboard (Developer Tool › API Configuration › API keys). See Revoke an API key.
I can't generate another API key
Your business already has 2 active keys, the most allowed. Revoke the one you no longer use, then generate the new one. See Rotate an API key.
A request returns 403 'Unauthorized access'
Your business has an IP allow-list and the request came from another address. This 403 comes from the user service. With an API key, every other service refuses an unlisted address with 401 instead. Add your servers' public outbound IP addresses to the list, or ask Multigate to. The allow-list is enforced in the sandbox too, with its own list. See IP allow-list.
Payouts
I got a timeout when creating a transfer. Was it created?
Maybe. Look it up with Find transfers ?unique before doing anything else. Not found? Wait at least a minute, look again, then retry with the same unique. Never resend with a new one. See Idempotency.
'Unique request ID already exist'
That unique was used before, possibly by a request you thought had failed. Look up the existing transfer. If you find nothing, another Multigate business used the same ID: send your payout with a new, prefixed ID. See Idempotency.
My transfer is stuck in pending_approval
Your API user can't approve its own payments. An approver must approve it in the dashboard, or ask Multigate to give your API user the approve permission too. See Approvals.
My transfer has been processing for a long time
Bank payments can take time, especially SWIFT. In production, Multigate checks pending payouts with the bank for 24 hours. USD payouts are settled by Multigate's operations team, so they stay processing until the team completes them. For a linked account, check your bank balance and that credentials are uploaded. Still processing after 24 hours? Contact support with the transactionId. See Transfer statuses.
A transfer failed or was rejected, but no webhook came
Some failures and all rejections send no webhook. Poll any transfer that stays non-final in your system with Find transfers. See Outcomes without a webhook.
My NGN transfer was split into several
Amounts above the instant-transfer limit are sent as several payments. Each has your unique plus a suffix (-1, -2), its own transactionId and its own webhook. Look the parts up with ?unique. See Large NGN transfers are split.
Webhooks
No webhooks arrive
Check that your webhook URL is registered in this environment with Get client configurations, uses HTTPS with a valid certificate, doesn't redirect, and returns 2xx within 9 seconds. Events that happened before the URL was registered are never delivered, and an event that fails all 5 retries isn't sent again. Some outcomes never send a webhook at all. If you develop locally, check that your tunnel is running and that its current address is the registered one. See Webhooks overview and Outcomes without a webhook.
Signatures never match
Sign only the body part of the request, with the client secret (not the client key), using the raw bytes as received. If they stopped matching on a certain date, the client secret was rotated: update it in your webhook handler. Also check that no JSON body parser (for example app.) runs before your webhook route. See Verifying signatures and Build your receiver.
The hash or notification_type header is missing
Your proxy drops headers with underscores. Read header.hash and header. from the JSON body. See Verifying signatures.
I received the same event twice
Expected. De-duplicate by the Idempotency-Key header and by the object's ID and status. See Handle events safely.
Sandbox vs production
It worked in the sandbox but fails in production
A few checks are off in the sandbox. The usual causes: an FX lock without enough balance (402 in production), an NGN beneficiary with a wrong account number (400 "Invalid beneficiary account number"), or a disposable email domain such as yopmail.com ("Email domain is not allowed"). Also check that your production servers' IP addresses are on your production allow-list. See Sandbox vs production.
My sandbox payout has been processing for 15 minutes
Expected. The sandbox checks pending payouts with the bank every 15 minutes, and test banks can take longer or never finish. Production is much faster. See Payout results and timing.
The same sandbox payout completed once and failed the next time
Some simulated partners in the sandbox choose the outcome at random. Test that you handle each outcome, not that you get a particular one. See Payout results and timing.
My sandbox customer has been processing for days
Compliance results are collected far less often in the sandbox. Ask your Multigate contact to complete the review for your test customer. See Customers and compliance review.
Name enquiry in the sandbox returns a name that isn't the one I expected
Sandbox account checks are answered by test banks, which can return fixed test names. Production returns the real account holder's name. See Beneficiaries and name enquiry.
Simulate an inflow returns 200 in production but no money arrives
Expected: the endpoint only works in the sandbox. In production, money arrives only from real bank transfers to your virtual accounts. See Inflows and virtual accounts.
Customers
'Invalid sub onBehalfOf' right after a customer was approved
A customer becomes usable for payouts a few minutes after it turns active. Also check that none of your other customers has the same business name: a duplicate name stops the second customer from being usable. See Acting for your customers.
I can't open an account for a customer
The customer must be active. A customer still in draft or processing gets "Sub-Client not active". See Customer statuses.
Accounts and collections
My new account has no account number
The partner bank hasn't confirmed it yet (status: processing). Wait for account_, and poll Get an account by ID in case the webhook doesn't come. See When the account isn't active yet.
Simulate an inflow returned 200 but nothing happened
The account isn't active yet: the body says "account has not been approved". Wait for account_, then retry. See Simulate an inflow.
A linked account's balance shows 0
The bank couldn't be reached, or credentials aren't uploaded. Retry, and check the credentials list with List bank credential slots (isProfiled). See Using a linked account.
Trade finance
Every trade finance call returns 403 forbidden
Your API user lacks the trade finance permission the endpoint needs, or your business doesn't have the Trade Finance module. Check permissions with Get the current user and see Who can do what. The dashboard only accepts view; alerts and reports only accept manage.
403 when approving a request
You submitted it yourself. Another person with the approve permission must approve it.
404 for a letter of credit I can see in the list
Export and import LCs use different IDs: export LC endpoints take lcId, import LC endpoints take id. See Find your letters of credit.
A date was refused, or comes back a day late
Send dates as DD/MM/YYYY. Import LC and outward guarantee details return dates one day after the stored date; subtract one day. See Working with the API.
An approval timed out
Read the record before trying again: if its status moved (for example to applied), the instruction was sent to the bank. Approving again could send it twice.
No webhook arrives for letters of credit or guarantees
Trade finance sends emails, not webhooks. Poll the lists and details. See Notifications.
Still stuck?
Email your Multigate contact with the environment, endpoint, request time (UTC), unique or transactionId, and any reference ID from the error. Never send credentials or tokens.