Core compliance decision engine for the JIL Sovereign settlement pipeline. Enforces KYC screening, transaction compliance checks, ATCE anti-dump rules, sanctions screening, and zone-based policy enforcement across 13 jurisdictions.
The Compliance API is the central compliance decision engine for the JIL Sovereign network. Every settlement, transfer, and bridge operation passes through this service before finalization. It enforces KYC screening, sanctions checking, ATCE anti-dump rules, velocity controls, and zone-specific policy - all in real time with sub-100ms decision latency.
https://jilsovereign.com/api/complianceapplication/jsonThe API authenticates via the x-api-key header. All endpoints except /health require a valid API key. Internal services use the JIL_ADMIN_KEY configured in the environment.
x-api-key: your_api_key_here
JIL Sovereign operates 13 compliance zones across different jurisdictions. Each zone runs its own validator node with configurable compliance policy. The compliance API evaluates transactions against the zone where the transaction originates, applying jurisdiction-specific rules on top of the global base compliance layer.
| Zone ID | Jurisdiction | Policy Focus |
|---|---|---|
US |
United States | OFAC SDN list, FinCEN AML requirements |
DE |
Germany | BaFin regulations, EU 6th AML Directive |
EU |
European Union | MiCA framework, AMLD6 compliance |
SG |
Singapore | MAS Payment Services Act guidelines |
CH |
Switzerland | FINMA crypto asset regulations |
JP |
Japan | JFSA compliance, travel rule enforcement |
GB |
United Kingdom | FCA crypto regulations, travel rule |
AE |
United Arab Emirates | VARA virtual asset framework |
BR |
Brazil | CVM crypto asset regulations |
GENESIS |
Global | Base compliance layer - applies to all zones |
Each zone can override the following parameters from the base layer:
zone_id is provided in a request, that zone's policy is applied. When omitted, the system resolves the zone from the originating validator's registration. Cross-zone transactions apply the stricter policy of both the source and destination zones.
The Compliance API exposes 9 endpoints organized into screening, enforcement, monitoring, and health categories.
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /v1/compliance/kyc/screen |
KYC identity screening |
| POST | /v1/compliance/tx/check |
Transaction compliance check |
| POST | /v1/compliance/address/screen |
Address sanctions screening |
| POST | /v1/compliance/atce/check |
ATCE anti-dump enforcement |
| GET | /v1/compliance/atce/status/:address |
ATCE enforcement status |
| POST | /v1/compliance/velocity/check |
Velocity limit check |
| GET | /v1/compliance/risk-score/:address |
Composite risk score |
| GET | /v1/compliance/zone/:zone_id/policy |
Zone policy configuration |
| GET | /health |
Health check (unauthenticated) |
POST /v1/compliance/kyc/screen
Screens an address and its associated identity data against KYC requirements. Returns a risk score and a decision indicating whether the identity passes, requires enhanced due diligence, or should be blocked.
{
"address": "jil1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"identity_data": {
"name": "Jane Smith",
"country": "US",
"dob": "1985-06-15" // optional
}
}
| Field | Type | Required | Description |
|---|---|---|---|
address | string | Yes | JIL address to screen |
identity_data.name | string | Yes | Full legal name of the individual or entity |
identity_data.country | string | Yes | ISO 3166-1 alpha-2 country code |
identity_data.dob | string | No | Date of birth in YYYY-MM-DD format |
{
"ok": true,
"address": "jil1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"risk_score": 22,
"decision": "PASS",
"reasons": [],
"screened_at": "2026-03-02T14:30:00.000Z"
}
The decision field returns one of three values:
POST /v1/compliance/tx/check
The primary endpoint for transaction compliance. Runs all compliance checks in parallel - sanctions, velocity, ATCE, and KYC verification - and returns a single decision. This is the endpoint called by the settlement pipeline before finalizing any transaction.
{
"tx_id": "tx_a1b2c3d4e5f6",
"from_address": "jil1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"to_address": "jil1grht8a0c3mwncqfsam9x2yda3xrhpgatmreuah",
"amount": "50000",
"asset": "JIL",
"zone_id": "US" // optional - resolved from validator if omitted
}
| Field | Type | Required | Description |
|---|---|---|---|
tx_id | string | Yes | Unique transaction identifier |
from_address | string | Yes | Sender address |
to_address | string | Yes | Recipient address |
amount | string | Yes | Transaction amount (string to avoid floating point) |
asset | string | Yes | Asset symbol (JIL, jBTC, jETH, jUSDC) |
zone_id | string | No | Compliance zone (US, DE, EU, SG, CH, JP, GB, AE, BR, GENESIS) |
{
"ok": true,
"tx_id": "tx_a1b2c3d4e5f6",
"decision": "APPROVED",
"risk_score": 18,
"checks": {
"sanctions": "clear",
"velocity": "pass",
"atce": "pass",
"kyc": "verified"
},
"reasons": [],
"zone_id": "US",
"checked_at": "2026-03-02T14:30:00.000Z"
}
The decision field returns one of three values:
The checks object shows the result of each individual compliance check. If any check fails, the reasons array describes why:
{
"ok": true,
"tx_id": "tx_x7y8z9",
"decision": "BLOCKED",
"risk_score": 95,
"checks": {
"sanctions": "match",
"velocity": "pass",
"atce": "pass",
"kyc": "verified"
},
"reasons": [
"Sender address matched OFAC SDN list entry",
"Risk score 95 exceeds block threshold of 90"
],
"zone_id": "US",
"checked_at": "2026-03-02T14:31:00.000Z"
}
POST /v1/compliance/address/screen
Screens a single address against sanctions and watchlist databases. Can be used standalone or as part of a broader compliance workflow. Returns whether the address appears on any sanctioned lists along with match details.
{
"address": "jil1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"lists": ["OFAC_SDN", "EU_SANCTIONS", "INTERNAL"] // optional - defaults to all
}
| Field | Type | Required | Description |
|---|---|---|---|
address | string | Yes | Address to screen (JIL, Ethereum, or Bitcoin format) |
lists | string[] | No | Specific lists to check. Defaults to all available lists. |
| List ID | Source | Update Frequency |
|---|---|---|
OFAC_SDN | US Treasury OFAC Specially Designated Nationals | Daily |
EU_SANCTIONS | European Union consolidated sanctions | Daily |
UN_SANCTIONS | United Nations Security Council sanctions | Daily |
UK_SANCTIONS | UK HM Treasury financial sanctions | Daily |
INTERNAL | JIL internal watchlist (fraud, abuse) | Real-time |
{
"ok": true,
"address": "jil1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"is_sanctioned": false,
"matches": [],
"risk_score": 5,
"screened_lists": ["OFAC_SDN", "EU_SANCTIONS", "INTERNAL"],
"timestamp": "2026-03-02T14:30:00.000Z"
}
When a match is found, the matches array contains details:
{
"ok": true,
"address": "0x1234...abcd",
"is_sanctioned": true,
"matches": [
{
"list": "OFAC_SDN",
"entry_id": "SDN-39218",
"match_type": "exact",
"confidence": 1.0
}
],
"risk_score": 100,
"screened_lists": ["OFAC_SDN", "EU_SANCTIONS", "INTERNAL"],
"timestamp": "2026-03-02T14:30:00.000Z"
}
POST /v1/compliance/atce/check
Checks whether a sell operation complies with ATCE (Anti-Token Concentration Exploitation) enforcement rules. ATCE limits token holders to selling no more than 10% of their vested balance per day for 30 days after a vesting unlock event. This prevents large holders from dumping tokens immediately after cliff vesting completes.
{
"address": "jil1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"sell_amount": "250000",
"asset": "JIL"
}
| Field | Type | Required | Description |
|---|---|---|---|
address | string | Yes | Seller address |
sell_amount | string | Yes | Amount the address wants to sell |
asset | string | Yes | Asset symbol (currently JIL only) |
{
"ok": true,
"address": "jil1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"decision": "APPROVED",
"daily_sold": "500000",
"daily_limit": "1000000",
"enforcement_day": 15,
"enforcement_end": "2026-04-01T00:00:00Z",
"remaining_allowance": "500000"
}
The decision field returns one of three values:
remaining_allowance){
"ok": true,
"address": "jil1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"decision": "BLOCKED",
"daily_sold": "1000000",
"daily_limit": "1000000",
"enforcement_day": 15,
"enforcement_end": "2026-04-01T00:00:00Z",
"remaining_allowance": "0",
"reason": "Daily ATCE limit reached. Resets at midnight UTC."
}
GET /v1/compliance/atce/status/:address
Returns the current ATCE enforcement status for an address, including active enforcement windows, how much has been sold today, and how much remains before the daily limit is reached.
| Parameter | Type | Description |
|---|---|---|
address | string | JIL address to check |
{
"ok": true,
"address": "jil1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"enforced": true,
"windows": [
{
"unlock_event": "cliff_base_90d",
"started": "2026-03-01T00:00:00Z",
"ends": "2026-03-31T00:00:00Z",
"day": 2,
"daily_limit": "1000000",
"daily_sold": "300000",
"remaining_today": "700000"
}
],
"total_vested": "10000000",
"total_sold_lifetime": "1300000"
}
{
"ok": true,
"address": "jil1grht8a0c3mwncqfsam9x2yda3xrhpgatmreuah",
"enforced": false,
"windows": [],
"total_vested": "0",
"total_sold_lifetime": "0"
}
POST /v1/compliance/velocity/check
Checks whether a proposed transaction would exceed the velocity limits for the address. Velocity limits use Redis-backed sliding window counters that track both the number of transactions per hour and the total volume per hour. Limits are configurable per zone.
{
"address": "jil1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"amount": "50000",
"asset": "JIL",
"direction": "send"
}
| Field | Type | Required | Description |
|---|---|---|---|
address | string | Yes | Address to check velocity for |
amount | string | Yes | Transaction amount |
asset | string | Yes | Asset symbol |
direction | string | Yes | send or receive |
{
"ok": true,
"address": "jil1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"within_limits": true,
"hourly_count": 5,
"hourly_limit": 50,
"hourly_volume": "25000",
"volume_limit": "1000000",
"window_resets": "2026-03-02T15:00:00.000Z"
}
hourly_count and hourly_volume reflect transactions in the last 60 minutes. Counters are keyed by address:asset:direction and expire automatically after the window period.
GET /v1/compliance/risk-score/:address
Returns the composite risk score for an address. The score is calculated from multiple risk factors including transaction patterns, counterparty risk, geographic risk, sanctions proximity, and historical behavior.
| Parameter | Type | Description |
|---|---|---|
address | string | JIL address to score |
{
"ok": true,
"address": "jil1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"risk_score": 32,
"risk_level": "low",
"factors": {
"transaction_pattern": 10,
"counterparty_risk": 5,
"geographic_risk": 8,
"sanctions_proximity": 0,
"historical_behavior": 4,
"kyc_completeness": 5
},
"last_updated": "2026-03-02T14:00:00.000Z",
"tx_count_30d": 47
}
The factors object breaks down the composite score into individual risk categories. Each factor contributes a weighted score to the total. The risk_level field maps the numeric score to a human-readable level: low (0-69), medium (70-89), or high (90-100).
GET /v1/compliance/zone/:zone_id/policy
Returns the current compliance policy configuration for a specific zone. Useful for clients to understand what thresholds and limits apply in a given jurisdiction before submitting transactions.
| Parameter | Type | Description |
|---|---|---|
zone_id | string | Zone identifier (US, DE, EU, SG, CH, JP, GB, AE, BR, GENESIS) |
{
"ok": true,
"zone_id": "US",
"jurisdiction": "United States",
"policy": {
"review_threshold": 70,
"block_threshold": 90,
"allowed_assets": ["JIL", "jBTC", "jETH", "jUSDC"],
"velocity_limits": {
"hourly_tx_count": 50,
"hourly_volume": "1000000"
},
"sanctions_lists": ["OFAC_SDN", "UN_SANCTIONS", "INTERNAL"],
"kyc_required": true,
"min_kyc_tier": 2,
"atce_enabled": true,
"atce_daily_sell_pct": 10,
"atce_window_days": 30
},
"last_updated": "2026-03-01T00:00:00Z"
}
GET /health
Unauthenticated health check endpoint. Returns service status including database and Redis connectivity. Used by Docker health checks and load balancers.
{
"status": "healthy",
"service": "compliance-api",
"version": "2026.02.25-410",
"uptime": 86400,
"dependencies": {
"postgres": "connected",
"redis": "connected",
"sanctions_db": "loaded"
}
}
The compliance engine calculates a composite risk score from 0 to 100 for every address and transaction. The score drives automated decisions throughout the settlement pipeline. Higher scores indicate greater risk.
| Score Range | Decision | Action |
|---|---|---|
| 0 - 69 | PASS | Transaction proceeds to settlement automatically |
| 70 - 89 | REVIEW | Enhanced due diligence required - transaction queued for manual review |
| 90 - 100 | BLOCK | Transaction blocked - compliance event emitted to audit log |
The composite score is calculated from six weighted risk factors:
| Factor | Weight | Description |
|---|---|---|
| Transaction Pattern | 25% | Unusual transaction sizes, frequency spikes, round-number patterns |
| Counterparty Risk | 20% | Risk scores of addresses the subject has transacted with |
| Geographic Risk | 20% | Jurisdiction risk based on FATF gray/black lists and local regulations |
| Sanctions Proximity | 15% | Degrees of separation from sanctioned addresses (direct = 100, 1 hop = 50, 2 hops = 25) |
| Historical Behavior | 10% | Past compliance flags, previous review outcomes, account age |
| KYC Completeness | 10% | Level of identity verification completed (tier 0-3) |
ATCE (Anti-Token Concentration Exploitation) is the protocol-level mechanism that prevents large token holders from dumping tokens immediately after vesting cliff completion. It protects the broader ecosystem from price manipulation by enforcing gradual sell-off limits during a 30-day enforcement window.
Vested tokens are released in three tiers based on the cliff schedule:
| Tier | Release | Timing | ATCE Window |
|---|---|---|---|
| Tier 1 (Base) | 33% of base amount | After 90-day cliff | 30 days at 10%/day |
| Tier 2 (Base) | 33% of base amount | Daily release after cliff (for pre-Nov 1 purchases) | 30 days at 10%/day |
| Tier 3 (Bonus) | 34% of base + 100% of bonus | After 180-day cliff | 30 days at 10%/day |
When an ATCE check is requested, the engine evaluates the following:
// Address vested 10,000,000 JIL on March 1
// Daily limit = 10% of 10,000,000 = 1,000,000 JIL/day
Day 1 (Mar 1): Sold 800,000 - APPROVED (200,000 remaining)
Day 2 (Mar 2): Sold 1,000,000 - APPROVED (0 remaining)
Day 2 (Mar 2): Sold 100,000 - BLOCKED (daily limit reached)
Day 3 (Mar 3): Sold 0 - 1,000,000 available (counter reset)
...
Day 30 (Mar 30): Last day of enforcement
Day 31 (Mar 31): No limits - sell freely
All error responses follow a consistent format with an HTTP status code, machine-readable error code, and human-readable message.
{
"ok": false,
"error": {
"code": "INVALID_ADDRESS",
"message": "The provided address is not a valid JIL, Ethereum, or Bitcoin address."
}
}
| HTTP Status | Error Code | Description |
|---|---|---|
| 400 | INVALID_ADDRESS |
Address format is invalid or unsupported |
| 400 | MISSING_FIELD |
A required field is missing from the request body |
| 400 | INVALID_ZONE |
The specified zone_id does not exist |
| 400 | INVALID_AMOUNT |
Amount is not a valid positive number string |
| 401 | UNAUTHORIZED |
Missing or invalid API key in x-api-key header |
| 403 | FORBIDDEN |
API key does not have permission for this endpoint |
| 404 | ADDRESS_NOT_FOUND |
No compliance record exists for the given address |
| 404 | ZONE_NOT_FOUND |
The specified zone does not exist in the network |
| 429 | RATE_LIMITED |
Too many requests - retry after the indicated delay |
| 500 | INTERNAL_ERROR |
Unexpected server error - transaction blocked by fail-closed policy |
| 503 | SERVICE_UNAVAILABLE |
Compliance service or a dependency is down - transactions queued |
The Compliance API is a mandatory checkpoint in the JIL Sovereign settlement pipeline. Every transaction passes through compliance before finalization - there is no bypass path.
// Settlement pipeline integration
Transaction Submitted
|
v
[Ledger Router :8000]
|
v
[Settlement Consumer :8051]
|
v
[Compliance API :8100] <-- All checks run here
|
+---+---+
| |
APPROVED BLOCKED
| |
v v
[Ledger [COMPLIANCE_BLOCKED
Service event emitted to
:8001] Kafka audit topic]
|
v
Settlement Finalized
The compliance-checker service (port 8055) consumes settlement events from the settlement.pending Kafka topic and calls the Compliance API for each transaction. Results are published to two topics:
| Topic | Event | Description |
|---|---|---|
settlement.approved |
COMPLIANCE_APPROVED |
Transaction passed all compliance checks - proceeds to ledger |
settlement.blocked |
COMPLIANCE_BLOCKED |
Transaction failed compliance - blocked with reasons logged |
compliance.audit |
COMPLIANCE_DECISION |
Every decision (pass, review, block) logged for audit trail |
The settlement pipeline enforces a strict fail-closed policy:
settlement.pending topiccompliance.audit Kafka topic and persisted to PostgreSQL. Decisions are immutable and include the full request, response, risk score breakdown, and timestamp. Audit records are retained for 7 years per regulatory requirements.
| Service | Port | Role |
|---|---|---|
| compliance-api | 8100 | Core decision engine (this service) |
| compliance-checker | 8055 | Kafka consumer that calls compliance-api for each settlement |
| settlement-consumer | 8051 | Produces settlement events to Kafka for compliance checking |
| ledger-service | 8001 | Receives approved transactions for finalization |
| PostgreSQL | 5432 | Stores compliance decisions, risk scores, sanctions data |
| Redis | 6379 | Velocity counters, ATCE daily tracking, sanctions cache |
| Kafka (RedPanda) | 9092 | Settlement event streaming and audit logging |