Pre-screening
POST /pre_screening/ validates user data (IP, addresses, pair, amount) against risk and compliance rules before an order is created, so you can block ineligible flows early instead of hitting failures mid-order.
This endpoint requires a trusted x-referral-token and is only available to approved partners. Without a trusted token the endpoint behaves as if it does not exist (404) or returns unauthorized.
Request
curl -X POST "https://api.n.exchange/en/api/v2/pre_screening/" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "x-referral-token: YOUR_TRUSTED_REFERRAL_TOKEN" \
-d '{
"ip": "203.0.113.10",
"sender_address": "0x1234567890abcdef1234567890abcdef12345678",
"withdraw_address": "1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2",
"pair": "BTCUSDC",
"deposit_amount": "500.0"
}'
Headers: x-referral-token required; Authorization per Authentication.
Body fields — all optional; the more you provide, the fuller the screen:
| Field | Type | Required | Description |
|---|---|---|---|
ip | string | No | User's IPv4 address for geolocation/sanctions screening |
sender_address | string | No | Address the user will send funds from (must be valid for the deposit currency's chain) |
withdraw_address | string | No | User's destination address (must be valid for the withdrawal currency's chain) |
pair | string | No | Pair name, pattern ^[a-zA-Z0-9_-]+$ |
deposit_amount | string | No* | Deposit amount — cannot be combined with withdraw_amount |
withdraw_amount | string | No* | Withdraw amount — cannot be combined with deposit_amount |
* Provide at most one of the two amounts; sending both returns 400.
A partial payload (e.g. IP only) performs a partial screen and says so in the response message.
Response
Fields:
| Field | Type | Description |
|---|---|---|
status | string | success | failed | error | unauthorized |
message | string | Human-readable result detail |
Compliance rejection is not an HTTP error. A blocked user returns 200 with status: "failed" — branch on the status field, not the HTTP code.
Examples:
{
"status": "success",
"message": "Pre-screening passed."
}
{
"status": "success",
"message": "Partial pre-screening passed. Provide all details for full pre-screen validation."
}
{
"status": "failed",
"message": "The country of the user's IP is blocked."
}
Errors
| Status | Meaning | Body |
|---|---|---|
400 | Invalid input — e.g. both amounts supplied | {"status": "error", "message": "Only one of deposit_amount or withdraw_amount can be provided"} |
401 | Authenticated but referral code is not trusted for pre-screening | {"status": "unauthorized", "message": "Pre-screening not applicable."} — or DRF {"detail": "..."} when credentials are missing entirely |
403 | Pre-screening rejected at the access level | {"detail": "Pre-screening failed."} |
404 | Endpoint unavailable — missing referral token or partner not configured for pre-screening | {"detail": "Not found"} |
What is screened
- IP geolocation — blocked countries, sanctioned territories, high-risk jurisdictions
- Addresses — sanctions lists (OFAC, EU, UN), known-illicit clusters, mixers, darknet markets
- Transaction parameters — amount/velocity thresholds under the risk-based approach described in KYC/AML
Integration practice
- Pre-screen before showing the payment step, with as much data as you have.
- Branch on
status; show a clear, non-technical message onfailedand do not retry the same address/IP. - Pre-screening does not replace order-time checks — an order can still enter compliance review (see Order Lifecycle).
Migration from v1
| v1 | v2 |
|---|---|
amount_quote | deposit_amount |
amount_base | withdraw_amount |
{"detail": "..."} response | {"status": "...", "message": "..."} |