Cover Page
The formal front matter for this Developer Guide, provided for enterprise procurement, audit, and archival purposes. This section does not affect the technical content below — skip to Introduction to start integrating.
| Product name | FT AML Platform |
| Document title | FT AML Platform — Developer Guide |
| Document version | TODO — Information Required (to be provided by Product Team) |
| Product / platform version | TODO — Information Required (to be provided by Product Team) |
| Release date | TODO — Information Required (to be provided by Product Team) |
| Prepared by | Fyscaltech — Developer Experience & Documentation |
| Confidentiality | Confidential — for the intended customer, partner, or implementation team only. Not for public redistribution. |
This is a living, web-based Developer Guide rather than a fixed PDF release — the version and release date above should be read as "as of the last confirmed update" rather than a frozen snapshot. Ask your Fyscaltech integration contact for a dated export if you need a fixed-point-in-time copy for audit purposes.
Document Control
Version history, review, and approval tracking for this guide. Populated as the guide moves through formal review cycles.
Version history
| Version | Date | Author | Summary of changes |
|---|---|---|---|
| TODO | TODO | TODO | Information Required — to be provided by Product Team |
Reviewers & approvers
| Role | Name | Date reviewed / approved |
|---|---|---|
| Technical reviewer | TODO | TODO |
| Product owner | TODO | TODO |
| Documentation approver | TODO | TODO |
Change log
A running log of substantive content changes to this guide (distinct from the API/product changelog, which tracks changes to the platform itself).
A formal change log for this document will be maintained here once the guide moves into a versioned release cycle.
Table of Contents
A linear index of every section in this guide, generated from the sidebar navigation on the left. Use the sidebar for day-to-day navigation — this section exists for printed/exported copies where the sidebar isn't available.
Generating…
Introduction
This Developer Portal is the integration reference for the FT AML Platform. It's written for three audiences: customers connecting their own core banking or onboarding systems to FT AML, partners building on top of the platform on a customer's behalf, and Fyscaltech implementation teams delivering a go-live. Wherever a detail depends on your specific deployment — credentials, exact payload schemas, rate limits — this guide says so explicitly rather than guessing, and points you to the Fyscaltech integration team who confirms it during onboarding.
What FT AML does
FT AML is an Anti-Money Laundering (AML) platform that helps financial institutions detect suspicious activity, screen customers against regulatory watchlists, monitor transactions, manage investigations, and comply with AML/CTF regulations. The Developer Portal covers the integration surface of that platform — getting your data in, and getting screening results and alerts back out — rather than the compliance-analyst console itself.
There are three ways data moves between your systems and FT AML
- Bulk CSV via S3 — for loading or refreshing large volumes of Customer, Customer Account, and Customer Transaction records.
- Customer Ingestion API — for pushing or updating individual customer records from your own systems as they change.
- Screening API — for screening a specific customer record on demand, by full name.
The CSV file format for Customer and Account records, and the Customer Ingestion API and Screening API request/response reference, are now fully documented in Integration Methods. Still pending: webhook payload format and signature verification guidelines, a Postman collection, and an OpenAPI specification — will be published soon once received from technical team.
Who does what
Customers
Own the source data (customers, accounts, transactions) and decide which integration method(s) fit their volume and architecture.
Partners
Build and operate an integration on a customer's behalf, typically under the same credentials and onboarding process as a direct customer.
Implementation teams
Fyscaltech's own team, engaged during onboarding to provision credentials, confirm schemas, and support go-live.
This portal
The shared reference all three groups work from — one source of truth for how integration works, updated as details are confirmed.
System Requirements
FT AML is delivered as a hosted (SaaS) platform — Fyscaltech operates the servers, databases, and runtime. Most items in a typical "system requirements" section therefore apply to Fyscaltech's infrastructure rather than yours. What follows separates what you, as an integrating developer, actually need to have ready, from platform-side detail that is not applicable to a hosted deployment.
What you need on your side
| Outbound network access | HTTPS (443) outbound to the FT AML API endpoints and, if applicable, the S3 bucket region used for Bulk CSV — see Network & DNS |
| TLS support | TLS 1.2 or higher on any client making API calls or S3 uploads |
| Supported browsers (console access only) | TODO — Information Required (to be provided by Product Team) — expected to be current Chrome, Edge, Firefox, Safari, consistent with the FT AML User Guide, but not yet confirmed for this document |
| Runtime / language version (your integration code) | No constraint imposed by FT AML — the APIs are plain HTTPS + JSON, callable from any language with an HTTP client. If you use the AWS CLI or an S3 SDK for Bulk CSV, follow that SDK's own supported-runtime guidance. |
| Local disk space | Not applicable for API integration. If staging bulk CSV export files locally before upload, size to your own file volumes. |
Platform-side (Fyscaltech-operated)
Provided for completeness and audit purposes — you do not need to provision or manage any of the following:
| Hosting | TODO — Information Required (to be provided by Product Team) |
| Compute (CPU / RAM per service) | TODO — Information Required (to be provided by Product Team) |
| Database engines | PostgreSQL, MongoDB, ClickHouse, and Redis are confirmed as in use by specific services — see Software Architecture. Version numbers: TODO — Information Required |
| Java version | TODO — Information Required (to be provided by Product Team) |
| Python version | Screening service (be-aml-name-screening) is confirmed as Python/FastAPI — exact version: TODO — Information Required |
| Node.js version | TODO — Information Required (to be provided by Product Team) |
| Go version | Ingestion service (datahub) is confirmed as Go/Gin — exact version: TODO — Information Required |
Firewall & SSL requirements
- Allow outbound HTTPS (443) from your integration servers to the FT AML API host(s) — exact hostnames/IP ranges: TODO — Information Required (to be provided by Product Team)
- If using Bulk CSV via S3, allow outbound HTTPS to the AWS S3 endpoint for the bucket's region
- FT AML's public endpoints are expected to present a valid, trusted TLS certificate; certificate pinning is not documented as required or supported
A definitive list of hostnames/IP ranges to allowlist, and confirmed minimum TLS cipher requirements, will be added here once provided.
Prerequisites
Everything you should have in place — or in progress with your Fyscaltech contact — before you start building against any of the three integration methods.
Accounts & access
- Onboarding relationship with Fyscaltech — API access is provisioned during onboarding, not self-service sign-up. Start with your Fyscaltech integration contact (see Support).
- Organization Admin on the FT AML console side, for anyone who needs to manage API-key-adjacent permissions or view ingestion/screening results in the console (Alert Manager, Name Screening, Data Ingestion).
- AWS IAM identity (if using Bulk CSV) — either a human AWS Console sign-in, or an access key/secret key pair for automation. See Bulk data ingestion (CSV via S3).
Certificates, tokens & API keys
| Credential | Applies to | Status |
|---|---|---|
| S3 bucket name + client id | Bulk CSV via S3 | Confirmed — issued during onboarding |
| AWS access key / secret key | Bulk CSV via S3 (automation path) | Confirmed — issued during onboarding |
| API key / bearer token / signed-request credential | Customer Ingestion API, Screening API | TODO — Information Required — see Authentication |
| Webhook signing secret | Webhook delivery (ingestion-triggered screening) | TODO — Information Required — see Webhooks & Events |
| TLS client certificate | Not currently required | Not applicable — confirm with Fyscaltech if your environment mandates mutual TLS |
Network & DNS
- No DNS records need to be created on your side to call FT AML — you resolve and connect to Fyscaltech-provided hostnames using standard public DNS.
- If you plan to receive webhooks (see Webhooks & Events), you will need a publicly reachable HTTPS endpoint with a valid DNS name and TLS certificate of your own.
- Confirm outbound firewall rules per System Requirements.
Database
No database provisioning is required on your side for any of the three integration methods — all persistence (Postgres, MongoDB, ClickHouse, Redis) is operated by Fyscaltech. See Database Configuration for what is documented about platform-side storage.
SMTP / notifications
Whether FT AML sends any email notifications that require an SMTP relay or sender-domain configuration on your side hasn't been confirmed. Today, results are retrieved via API response or the console — not email.
Third-party software
- AWS CLI or an S3-compatible SDK — only if you choose the automation path for Bulk CSV (see Bulk data ingestion (CSV via S3))
- An HTTP client capable of TLS 1.2+ — for the Customer Ingestion API and Screening API. No proprietary client library is required; both are plain JSON over HTTPS.
- Postman (optional) — useful for manual testing once a collection is published; see Resources & Changelog.
Quick Start
If you're an external developer integrating FT AML into your own systems for the first time, this is the one section to read start to finish — everything else in this portal is reference material you'll come back to as you go.
The fastest path from zero to a working integration follows the same six steps regardless of which integration method you end up using day to day.
- Request API credentials — contact the Fyscaltech integration team (see Support) to start onboarding. They'll confirm which integration method(s) fit your use case.
- Receive sandbox access — where a sandbox/test environment applies to your chosen method, credentials and connection details are issued as part of onboarding (see Testing & Sandbox).
- Upload a sample customer — load a small test file via Bulk CSV (50–100 rows is plenty), or a single record via the Customer Ingestion API, to confirm your data format is accepted.
- Call the Screening API — submit a customer's full name to
/screenand confirm a result comes back in the response. - Check the delivery mechanism for ingestion-triggered screening — if you plan to rely on
name_screening_enabledduring ingestion instead of calling the Screening API directly, confirm with Fyscaltech how that result reaches you before building against it. - View the screening result — check the FT AML console (Alert Manager, or Name Screening) to see the same result reflected on the platform side.
If you're not sure which integration method fits your volume and timeline, read Integration Methods and the "Which one should I use?" table first — then bring that shortlist to the Fyscaltech integration team.
Platform & Architecture
FT AML sits alongside your core banking and customer-facing systems, receiving data through the integration methods in this portal and returning screening results and alerts. This section documents what is confirmed about the platform's internal architecture from the services already described in Integration Methods — it is not a full architecture specification.
Components & services
Two backend services are confirmed by name, language, and framework so far:
| Service | Stack | Responsibility |
|---|---|---|
datahub | Go / Gin | Customer Ingestion API — accepts and validates ingestion requests, publishes events; also underlies the Bulk CSV pipeline |
be-aml-name-screening | Python / FastAPI | Screening API — matches submitted records against watchlist data and returns scored results |
Additional services (Case Manager, Alert Manager, Transaction Monitoring, STR Listing, and others visible in the FT AML console) are not yet documented at the integration/API level — see Module-wise Integration Guide for what's tracked per module.
Data flow
Confirmed data flow, end to end, for each integration method:
Database & storage
Four data stores are confirmed as in active use across the two documented services — see Database Configuration for what's documented about each:
- PostgreSQL — the screening ledger (every screening run), written synchronously by
/screen - MongoDB — watchlist/reference data matched against during screening
- ClickHouse — analytical store, upserted by the ingestion consumer alongside Postgres
- Redis — configuration cache, loaded on each screening request
Messaging & workflow orchestration
- SNS/SQS — the Customer Ingestion API publishes an ingestion event here rather than writing synchronously; a background consumer performs the actual persistence
- Temporal — orchestrates the Bulk CSV workflow/queue pipeline (file detection, validation, row-level processing, error reporting)
External integrations
- Amazon S3 — the transport mechanism for Bulk CSV (see Bulk data ingestion (CSV via S3))
- Watchlist data provider — sanctions/PEP/adverse-media source data used by the Screening API. Provider name and refresh cadence: TODO — Information Required (to be provided by Product Team)
Deployment architecture
Network topology, container/orchestration platform, region(s), and high-availability/DR posture haven't been confirmed for publication yet. FT AML is operated by Fyscaltech as a hosted service — see Deployment Guide for what that means for you as an integrating developer.
Communication flow summary
At a glance: your systems talk to FT AML over HTTPS (API calls) or S3 (bulk file transport) only — you never call the internal services (datahub, be-aml-name-screening) or data stores (Postgres, MongoDB, ClickHouse, Redis) directly. Those are internal implementation detail, documented here only so you understand what's happening after your request leaves your system.
Installation Guide
FT AML is a hosted (SaaS) platform — there is no server software for you to download and install. This section documents the closest equivalent for each integration method: the one-time setup that gets your side ready to send its first request.
If you were expecting an on-premise or self-hosted installer, confirm your deployment model with your Fyscaltech contact — as documented today, FT AML is Fyscaltech-hosted only.
Step 1 — Request access
Objective: obtain the credentials needed for your chosen integration method(s).
- Contact the Fyscaltech integration team (see Support).
- Confirm which of the three Integration Methods apply to your use case.
- Receive credentials — S3 bucket name + client id (Bulk CSV), and/or API access detail once confirmed for the Ingestion/Screening APIs.
Expected output: a bucket name, client id, and/or API access confirmation from Fyscaltech.
Validation: you can name the exact <client-id> folder path you were given, per Bulk data ingestion (CSV via S3).
Step 2 — Set up the AWS CLI (Bulk CSV path only)
Objective: get a working, authenticated AWS CLI (or S3 SDK) able to write to your inbox path.
Commands:
aws configure # one-time setup, using the access key and secret key we send you
Expected output: the CLI stores your credentials locally; no error is printed.
Validation:
aws s3 ls s3://<bucket>/<client-id>/
A successful listing (even if empty) confirms your credentials are valid and scoped correctly.
Access Denied on this command almost always means the client id in the path doesn't match the one issued to you, or the credentials belong to a different environment (sandbox vs. production) — confirm both with Fyscaltech before troubleshooting further.Step 3 — Confirm API reachability (Customer Ingestion / Screening APIs)
Objective: confirm your network can reach the API host over HTTPS before writing integration code.
curl -i -X POST https://<host>/riskradar/core/api/v1/bo/screen \
-H "Content-Type: application/json" \
-d '{"customer_name": "Test User"}'
Expected output: an HTTP response with a JSON body shaped like { "code": "00000", "message": "Success", "data": {...} } — see Screening API for the full response shape. Use the read-only /bo/screen endpoint for this check so no alert is created by a connectivity test.
Troubleshooting: a connection timeout suggests a firewall/network issue (see System Requirements); a 4xx/5xx with a JSON body means you reached the service — check the error code against Business error codes.
Step 4 — Verification checklist
- AWS CLI (or SDK) authenticates and can list your client-id path — Bulk CSV only
- A test HTTPS call to the Screening API's read-only endpoint returns a valid JSON envelope
- Your Fyscaltech contact has confirmed which environment (sandbox/production) the above credentials belong to
Continue to Configuration Guide once every applicable item above is checked off.
Configuration Guide
Configuration that is set on the platform side (via the FT AML console) but directly affects how your integration behaves. There are no client-side configuration files to edit — FT AML has no local install — so this section documents the console-side settings you'll want your team to be aware of.
Bulk CSV ingestion schedule
Purpose: controls when the platform checks your S3 inbox for new files. Location: FT AML console → Data Ingestion. Properties:
| Property | Description | Default | Recommended |
|---|---|---|---|
| Frequency | Every day, or every N days | TODO | Every day, for active integrations |
| Run times | One or more times of day the inbox is checked (e.g. 02:00, 14:00) | TODO | Comfortably after your own export job finishes — see the best-practice note under Bulk CSV |
| Paused | Temporarily stops the schedule without deleting it | Off | Enable while making changes to your export pipeline |
CSV file format rules
Full column-level reference lives under Bulk data ingestion (CSV via S3); the cross-cutting rules that apply to both the Customer and Account files are summarized there under "File format rules (both files)."
Screening control on ingestion
Purpose: the name_screening_enabled field on the Customer Ingestion API payload controls whether ingesting a customer also triggers a screening run as a side effect. Default value: true when omitted. Recommended value: leave at the default unless you are deliberately deferring screening to a separate, explicit Screening API call (Flow A) — see Integration Workflows for the two supported patterns.
Environment variables
Not applicable on the platform side (no client-installed component). On your own side, the values you'll typically hold as environment/secret configuration are the S3 credentials and, once confirmed, the API credential for the Ingestion/Screening APIs — see Security Best Practices → Secrets management.
Database Configuration
FT AML's databases are fully managed by Fyscaltech — you never connect to them directly, provision schemas, or run migrations yourself. This section documents what is confirmed about platform-side storage, for architectural awareness only.
Confirmed data stores
| Store | Used by | Purpose |
|---|---|---|
| PostgreSQL | Screening API (/screen) | Screening ledger — one entry per screening run, written synchronously |
| PostgreSQL + ClickHouse | Customer Ingestion API (async consumer) | Customer record persistence — upserted after the ingestion event is consumed |
| MongoDB | Screening API | Watchlist/reference data matched against during screening |
| Redis | Screening API | Configuration cache, loaded per screening request |
Schema & tables
Table/collection-level schema detail is internal to Fyscaltech's services and not part of the public integration surface. The field-level shape of data you send and receive is documented under Data models and Integration Methods instead.
Connection, migration, backup & restore
Not applicable to you as an integrating developer — these are operated internally by Fyscaltech. If you require attestation of backup/restore or disaster-recovery practices for a vendor security review, request this directly from your Fyscaltech contact; it is not published in this guide.
Performance & indexes
Index strategy and query performance are internal implementation detail. If you experience elevated latency on the Screening or Customer Ingestion APIs, report it via Support with the details listed there — Fyscaltech will investigate on the platform side.
Core Concepts & Data Models
A few ideas come up across all three integration methods. Understanding these up front makes the rest of this portal easier to follow.
Customer Record
The core profile of an individual or organization — the same record whether it arrives via bulk CSV or the Customer Ingestion API.
Customer Account Record
An account belonging to a customer, linked back to its Customer Record.
Customer Transaction Record
A transaction on a customer account, used by Transaction Monitoring once it's in the platform.
Ingestion
The general term for getting any of the three record types into the platform — either as a bulk CSV upload, or one at a time via the Customer Ingestion API.
Screening
Checking a customer against watchlists. Today this is done by full name, via the Screening API or triggered as part of ingestion.
Webhook
An endpoint you host, which the platform calls to deliver a screening result — only relevant if you're using the Customer Ingestion API to trigger screening rather than calling the Screening API directly.
Data models
Confirmed field names below come directly from the Customer Ingestion API and CSV bulk-upload formats — where a model isn't backed by data received from the technical team yet, that's noted rather than guessed at.
Customer
customer_id,customer_name— the only two required fields on ingestioncustomer_type—IndividualorCorporate(API) /INDIVIDUAL,CORPORATE,BUSINESS(CSV)risk_level,risk_score,pep_flag,sanctions_status— KYC/risk fields set on ingestiondate_of_birth_or_incorporation,citizenship_country,street/city— optional, improve screening match accuracy
Account
ACCOUNT_NUMBER— unique across all your accounts, not just per-customerCUSTOMER_ID— links back to the owning Customer; unmatched accounts are skippedACCOUNT_TYPE—SAVINGS,CURRENT,WALLET,FIXED_DEPOSIT,LOANACCOUNT_HOLDING_TYPE—SOLE,JOINT,TRUST,CUSTODIAL
Transaction
Alert
Case
Integration Methods
The three ways data moves between your systems and the FT AML Platform, in detail.
Which one should I use?
| Method | Best for |
|---|---|
| Bulk CSV via S3 | Initial data loads, and large-volume periodic refreshes of your customer and account population |
| Customer Ingestion API | Keeping individual customer records in sync as they're created or changed in your own system |
| Screening API | Checking one specific customer by full name at a specific moment — e.g. during onboarding |
Bulk data ingestion (CSV via S3)
For loading or refreshing data in volume, the platform reads CSV files you upload to a dedicated Amazon S3 location. Fyscaltech provisions this bucket for you during onboarding — you'll receive the bucket name and a client id (a short code, e.g. acme-bank) that scopes every path below to your own data.
Getting access
Two access options — tell your Fyscaltech contact which fits your team:
- Browser (AWS Console) — best if a person uploads files manually, a few times a month. No setup beyond a sign-in.
- Command line / automation — an access key and secret key for the AWS CLI or any S3 library, best if a scheduled job on your side produces the files without a person involved.
aws configure # one-time setup, using the access key and secret key we send you
aws s3 cp customers_20260729.csv s3://<bucket>/<client-id>/inbox/customer/
Your credentials only ever grant access to your own <client-id> folder within the shared bucket — not the whole bucket. Send data files only to the paths below; never by email or shared drive, since they contain personal data.
Where to upload
| What you're sending | Upload to |
|---|---|
| Customers | <client-id>/inbox/customer/ |
| Accounts | <client-id>/inbox/account/ |
- Name files with a sortable date —
customers_20260729.csv, not29-07-2026— since if more than one file is waiting, the platform processes whichever name sorts first, and only one file per run. - Upload customers before accounts. An account belongs to a customer, so if you're sending both at once, the customer file needs to land first — accounts referencing a customer we haven't seen yet are skipped and reported back to you.
Once a file is read, it's moved out of the inbox — an empty inbox means processing is done, not that something went wrong:
| Folder | What's in it |
|---|---|
processed/customer/, processed/account/ | Files accepted and read |
rejected/customer/, rejected/account/ | Files that couldn't be read at all — almost always a wrong or missing header row |
jobs/<run>/errors/ | Individual rows that couldn't be accepted, with the line number, column, and reason for each |
Choosing your ingestion schedule
You control when the platform looks for your files, from the back-office application — no ticket or code change needed. Set a Frequency (every day, or every N days) and one or more Run times (e.g. 02:00 and 14:00); at each of those times the inbox is checked, and an empty inbox simply means nothing runs until the next check. The schedule can also be paused while you're making changes.
Set the run time comfortably after your own export job finishes — if a nightly export finishes around 01:30, schedule 02:30 rather than 01:45.
File format rules (both files)
- CSV, UTF-8 encoded, with a header row first
- The header row must match exactly — same column names, spelling, order, all capitals. This is the one thing that gets the whole file rejected rather than individual rows.
- Every row must have the same number of columns as the header, even when values are empty (
A,,C) - Leave optional columns blank rather than writing
NULL,N/A, or-— those are treated as real values and usually rejected - Wrap a value in double quotes if it contains a comma:
"Smith, John" - Dates:
2026-07-29,2026/07/29,29-07-2026,29/07/2026, or20260729— pick one form and stay consistent - Timestamps (date + time columns):
2026-07-29T14:30:00Zis recommended (UTC) - Yes/no columns accept
true/false/1/0/Y/N/yes/no, any case - Country and currency columns use short codes (
IN,SG,AE;INR,USD) — some columns are too narrow for full names
Customer file — 52 columns
Copy this header line exactly:
CUSTOMER_ID,CUSTOMER_TYPE,CUSTOMER_NAME,STATUS_CODE,CUSTOMER_SEGMENT_CODE,CUSTOMER_SEGMENT_NAME,RISK_LEVEL,RISK_SCORE,KYC_LEVEL,KYC_LEVEL_DESCRIPTION,PEP_FLAG,SANCTIONS_STATUS,SOURCE_OF_FUNDS,KYC_AUTHORIZED_SIGNATORY_NAME,ONBOARDING_DATE,ONBOARDING_CHANNEL,STREET,CITY,PROVINCE_REGION,ADDRESS_COUNTRY,POSTAL_CODE,CITIZENSHIP_COUNTRY,RESIDENCE_OPERATION_COUNTRY,BIRTH_INCORPORATION_COUNTRY,CUSTOMER_CONTACT_NO,ACCOUNT_TYPE,ACCOUNT_OPEN_DATE,ACCOUNT_AGE_DAYS,EXPECTED_MONTHLY_SPEND,EXPECTED_MONTHLY_SPEND_CURRENCY,EXPECTED_TXN_FREQUENCY,PURPOSE_OF_ACCOUNT,FIRST_NAME,MIDDLE_NAME,LAST_NAME,GENDER,DATE_OF_BIRTH_OR_INCORPORATION,CUSTOMER_AGE,CUSTOMER_ALIASES,CUSTOMER_ID_NO,CUSTOMER_ID_TYPE,CUSTOMER_ID_EXPIRY_DATE,CUSTOMER_ID_ISSUE_DATE,CUSTOMER_ID_COUNTRY,DESIGNATION,EMPLOYER_NAME,DECLARED_INCOME,INCOME_CURRENCY,NATURE_OF_BUSINESS,COUNTRY_OF_OPERATIONS,CREATED_AT,UPDATED_AT
These six must always have a value — a row missing any of them is rejected:
| Column | What it is |
|---|---|
CUSTOMER_ID | Your own identifier, unique in the file and stable across files for the same customer (max 64 chars) — this is how an update is recognized rather than a new customer |
CUSTOMER_TYPE | One of INDIVIDUAL, CORPORATE, BUSINESS |
STATUS_CODE | Your own status, e.g. ACTIVE, DORMANT, SUSPENDED |
ONBOARDING_DATE | Date the customer was onboarded |
ONBOARDING_CHANNEL | e.g. BRANCH, MOBILE_APP, ONLINE, AGENT |
UPDATED_AT | Timestamp. Used to decide which version is newer — a record with an older UPDATED_AT will not overwrite a newer one already held |
Fixed-value columns (anything else is rejected): CUSTOMER_TYPE (INDIVIDUAL/CORPORATE/BUSINESS), RISK_LEVEL (LOW/MEDIUM/HIGH), GENDER (MALE/FEMALE/OTHER).
Four cross-field rules worth knowing, since these catch inconsistent records: an INDIVIDUAL requires FIRST_NAME and DATE_OF_BIRTH_OR_INCORPORATION; a CORPORATE requires NATURE_OF_BUSINESS; if DECLARED_INCOME is set, INCOME_CURRENCY must be too; and if both CUSTOMER_AGE and a date of birth are given, they must agree within one year.
Account file — 13 columns
ACCOUNT_NUMBER,CUSTOMER_ID,ACCOUNT_TYPE,ACCOUNT_NAME,ACCOUNT_CURRENCY_CODE,ACCOUNT_BANK_NAME,ACCOUNT_BANK_COUNTRY,ACCOUNT_STATUS,ACCOUNT_HOLDING_TYPE,SIGNATORY_CUSTOMER_ID,SIGNATORY_NAME,CREATED_AT,UPDATED_AT
Seven required: ACCOUNT_NUMBER (unique across all your accounts, not just per-customer, max 128 chars), CUSTOMER_ID (must match a customer already received, or the account is skipped), ACCOUNT_TYPE (SAVINGS/CURRENT/WALLET/FIXED_DEPOSIT/LOAN), ACCOUNT_STATUS (ACTIVE/INACTIVE/CLOSED/FROZEN), ACCOUNT_HOLDING_TYPE (SOLE/JOINT/TRUST/CUSTODIAL), CREATED_AT, and UPDATED_AT timestamps.
If ACCOUNT_HOLDING_TYPE is JOINT, TRUST, or CUSTODIAL, SIGNATORY_CUSTOMER_ID becomes required too — a shared account needs a second party. UPDATED_AT can never be earlier than CREATED_AT.
The remaining six columns are optional: ACCOUNT_NAME and ACCOUNT_BANK_NAME (free text, max 255 chars), ACCOUNT_CURRENCY_CODE and ACCOUNT_BANK_COUNTRY (short codes only — max 16 characters, so a full name like "United Arab Emirates" won't fit and is rejected; use AE instead), and SIGNATORY_CUSTOMER_ID/SIGNATORY_NAME for an additional signatory.
Common problems
| What you see | Cause | Fix |
|---|---|---|
File in rejected/, nothing loaded | Header row doesn't match exactly | Copy the header from this page exactly — check spelling, order, extra spaces, case |
Rows rejected: REQUIRED | A mandatory column is blank | Fill every required column listed above |
Rows rejected: INVALID_ENUM | A fixed-value column has something else in it | Use only the allowed values |
Rows rejected: INVALID_DATE | Date/timestamp in an unsupported form | Use one of the accepted forms; watch for DD/MM vs MM/DD mix-ups |
Rows rejected: DUPLICATE | Same CUSTOMER_ID/ACCOUNT_NUMBER twice in one file | Send each record once per file — the first occurrence is kept |
Rows rejected: MAX_LENGTH_EXCEEDED | A value is longer than the column allows | Usually a full country name in a code column, or an over-long id — see the character limits below |
Rows rejected: COLUMN_COUNT_MISMATCH | The row has more or fewer commas than the header | Usually an unquoted comma inside a value — wrap that value in double quotes |
| Accounts silently not loaded | Their customer hasn't reached us yet | Upload the customer file first; confirm that customer row wasn't itself rejected |
Customer Ingestion API
Service: datahub (Go / Gin)
Ingests or updates a single customer's information from your own system — the API equivalent of a bulk Customer Record upload, but for one record at a time and in near real time as your data changes. Ingestion is asynchronous: the endpoint validates the payload and publishes an event, then returns immediately — persistence happens moments later via a background consumer, not within the request itself.
| Method / Path | POST /datahub/ingestion/v1/customer |
| Success status | 202 Accepted |
| Headers | Content-Type: application/json |
Request payload
All fields are flat — no nesting. Only customer_id and customer_name are required; every other field is optional (omit it and it's treated as null). The field set mirrors the CSV Customer Record columns above, just in snake_case JSON:
{
"customer_id": "CUST-1001", // REQUIRED, string
"customer_name": "Jane Doe", // REQUIRED, string
"customer_type": "Individual", // "Individual" | "Corporate"; blank defaults to "Individual"
// KYC / status
"status_code": "ACTIVE",
"customer_segment_code": "RETAIL",
"risk_level": "LOW",
"risk_score": 12.5, // float
"pep_flag": false, // bool
"sanctions_status": "CLEAR",
// Onboarding
"onboarding_date": "2025-01-15", // YYYY-MM-DD or RFC3339
"onboarding_channel": "BRANCH",
// Address
"street": "...", "city": "...", "address_country": "AE",
// Personal
"first_name": "Jane", "last_name": "Doe",
"gender": "F",
"date_of_birth_or_incorporation": "1990-05-01",
// Identity document
"customer_id_no": "...", "customer_id_type": "PASSPORT",
// Screening control — omitted defaults to true
"name_screening_enabled": true // bool
}
customer_type is the only accepted enum-ish field, with no strict validation — anything other than the two accepted values is simply not recognized, blank defaults to Individual. Date fields accept YYYY-MM-DD or RFC3339; anything unparseable or empty is stored as null. name_screening_enabled omitted is treated as true — a new customer is screened by default unless you explicitly opt out.
Response
{ "code": "00000", "message": "success" }
Returned with 202 Accepted. There's no result field — nothing is persisted synchronously, so there's nothing to hand back yet.
Validation rules
- Request body is required and must be valid JSON
customer_idandcustomer_name— trimmed, must be non-emptycustomer_type— blank defaults toIndividual; any other value is accepted as-is- No format, length, or enum checks are enforced on the remaining fields
Error responses
Shape: { "code": "<code>", "message": "<message>" }
| Trigger | Code | HTTP | Message |
|---|---|---|---|
| Malformed JSON body | BR001 | 400 | invalid request payload |
| Empty body | BR001 | 400 | request body is required |
Missing customer_id | BR001 | 400 | customer_id is required |
Missing customer_name | BR001 | 400 | customer_name is required |
| Internal queue/publish failure | SWW01 | 500 | something went wrong |
Flow
POST /customer → controller (bind → validate → map) → PublishCustomerIngestionEvent publishes to SNS/SQS → returns 202. Consumers later upsert the record into Postgres and ClickHouse — neither database is written to synchronously within the request.
There is no batch HTTP ingestion endpoint. CSV/batch ingestion runs on a Temporal workflow/queue pipeline (see Bulk CSV via S3), not this API — don't loop this endpoint per record for a bulk load.
Screening API
Service: be-aml-name-screening (Python / FastAPI)
Screens a customer against watchlists and returns matches, synchronously — the result comes back in the same response. Two endpoints exist:
| Main | Back-office | |
|---|---|---|
| Method / Path | POST /riskradar/core/api/v1/screen | POST /riskradar/core/api/v1/bo/screen |
| Side effects | Creates alerts, publishes events, writes a screening ledger entry | Read-only — no alert, no publish |
| Success status | 200 | 200 |
| Headers | Content-Type: application/json | |
Use the main /screen endpoint for real onboarding/monitoring checks that should raise alerts when warranted. Use /bo/screen when you want to see what a screening result would look like — e.g. previewing a match — without it creating an alert.
A scope framework (an x-scope bitmask header) exists in the service, but is not wired to either of these two routes — sending it currently has no effect.
Request payload
/screen accepts a free-form JSON object — extra fields are allowed and preserved. customer_name is required; customer_type must be "Individual" or "Entity" (defaults to Individual); everything else is optional. The field set mirrors the Customer Ingestion API payload — status_code, risk_level, risk_score, pep_flag, address fields, personal/identity/employment fields, and so on — so a record you've already ingested can largely be re-sent as-is to screen it. Only a subset actually drives matching: customer_name, date_of_birth_or_incorporation, street, city, province_region, citizenship_country, customer_type, gender. If customer_id is omitted, a temporary TMP<uuid> is generated for that request.
{
"customer_name": "Jane Doe", // REQUIRED
"customer_id": "CUST-1001",
"customer_type": "Individual",
"gender": "F",
"date_of_birth_or_incorporation": "1990-05-01",
"citizenship_country": "IN",
"street": "...", "city": "...", "address_country": "AE"
}
/bo/screen takes the same shape, but only customer_name is accepted/required — everything else is ignored for matching purposes on this read-only endpoint.
Response envelope
{ "code": "00000", "message": "Success", "data": { /* result */ } }
Exactly three fields — code, message, data. There's no result or pagination field. Success code is 00000.
/screen result — trimmed, public
{
"data": {
"meta": { "entity_key": "...", "screening_id": "...", "timestamp": "..." },
"screening_result": { "alert_score": 87.5, "alert_category": "HIGH" }, // score 0–100
"alert_details": { "alert_code": "...", "alert_status": "..." },
"watchlist_records_matched": [ // top 10, or null
{ "UID": 12345, "full_name": "Jane Doe", "match_score": 91.2 }
]
}
}
/bo/screen result — richer, raw
Same meta/score/category fields, but alert_code and alert_status are always null (no alerting on this endpoint), plus a full raw_matches array (up to 50) with per-attribute detail — each matched attribute (name, country, date of birth, entity type, address) carries its own weight and contribution score, so you can see exactly why a match scored the way it did rather than just the final number.
Each entry in raw_matches also carries record-level detail beyond the scored attributes: match_id, watchlist_mongo_id (the underlying watchlist record's own id), risk_level, record_version, updated_date, and a soft-delete pair — is_deleted / deleted_at — showing whether the matched watchlist record has since been retired at the source.
Validation rules
/screen—customer_namerequired,customer_typemust beIndividual/Entity, numeric fields are coerced, unknown fields are allowed and preserved/bo/screen— additionally rejects an emptycustomer_namewithentity name required
Error responses
Shape: { "code": "<code>", "message": "<message>", "data": <optional> }
| Trigger | Code | HTTP | Message |
|---|---|---|---|
Bad/missing customer_name, invalid customer_type | VALIDATION_ERROR | 400 | Invalid request payload |
Empty customer_name on /bo/screen | VALIDATION_ERROR | 400 | entity name required |
| Duplicate record | CONFLICT | 409 | Duplicate record |
| Redis config-load connection failure | REDIS_CONNECTION_ERROR | 503 | as raised |
| Redis config-load operation failure | REDIS_OPERATION_ERROR | 500 | as raised |
Postgres ledger write fails (/screen only) | DATABASE_QUERY_FAILED | 500 | as raised |
| Any unmapped error | INTERNAL_SERVER_ERROR | 500 | underlying error message (str(exc)) |
Flow
POST /screen → handler validates → service loads config from Redis/Mongo → FuzzySearchEngine.screen_user matches against sanctions/watchlist data → maps to response. On /screen it also records the screening run in Postgres and, when the result scores as an alert, creates alerts and publishes events. /bo/screen skips all of that alerting — it's read-only end to end.
Authentication
Access is confirmed for one of the three integration methods so far:
- Bulk CSV via S3 — Fyscaltech provisions the S3 bucket location your files are uploaded to, along with the AWS access credentials needed to write to it. Keep these credentials on your backend or automation only, never in client-side code, and store them in a secrets manager rather than source control.
Credential/access-control setup for the Customer Ingestion API, Screening API, and any webhook delivery hasn't been confirmed yet.
Application-level request authentication (e.g. a bearer token or signed-request scheme) for the Customer Ingestion and Screening APIs is still being finalized. Until it's in place, do not assume these endpoints enforce caller identity on their own — confirm the current access-control setup for your environment (network restriction, IP allowlisting, etc.) with your Fyscaltech integration contact before relying on them being reachable only by authorized callers. This page will be updated once the mechanism is finalized.
Module-wise Integration Guide
FT AML's console has many modules (Case Manager, Alert Manager, Name Screening, Transaction Monitoring, STR Listing, and more — see the FT AML User Guide). This section tracks which of them currently have a documented integration surface (an API or file-based method you can call from your own systems), versus modules that are today accessed only through the console UI.
Module: Bulk Data Ingestion
| Purpose | Load or refresh Customer and Account records in volume |
| Integration surface | CSV file upload to a dedicated S3 path — see Bulk data ingestion (CSV via S3) |
| Required permissions | AWS IAM identity scoped to your <client-id> folder |
| Database touched | PostgreSQL, ClickHouse (via the ingestion pipeline) |
| Validation | File moves from inbox/ to processed/; check Data Ingestion job status in the console |
Module: Customer Ingestion (API)
| Purpose | Push or update a single customer record in near real time |
| Integration surface | POST /datahub/ingestion/v1/customer — see Customer Ingestion API |
| Required permissions | TODO — Information Required — see Authentication |
| Database touched | PostgreSQL, ClickHouse (async, via SNS/SQS consumer) |
| Validation | 202 Accepted response; confirm the record appears in the console shortly after |
Module: Name Screening (API)
| Purpose | Check a customer's full name against watchlists on demand |
| Integration surface | POST /riskradar/core/api/v1/screen (creates alerts) and /bo/screen (read-only) — see Screening API |
| Required permissions | TODO — Information Required — see Authentication |
| Database touched | PostgreSQL (ledger), MongoDB (watchlist match), Redis (config cache) |
| Validation | 200 with a populated screening_result; cross-check against Alert Manager / Name Screening in the console |
Console-only modules (no documented integration surface yet)
The following FT AML modules are used through the console UI only, as of this guide. If your use case requires programmatic access to any of them, raise it with your Fyscaltech contact — this table will be updated as new integration surfaces are confirmed.
| Module | What it does (console) | Integration surface |
|---|---|---|
| Case Manager | Investigation and disposition of cases raised from alerts | Not yet available |
| Alert Manager | Triage and management of alerts across modules | Not yet available |
| Transaction Monitoring | Rule-based monitoring of customer transactions | Not yet available — Customer Transaction records can be loaded via Bulk CSV, but no monitoring-specific API is documented |
| STR Listing | Suspicious Transaction Report filing and register | Not yet available |
| AI Agent Manager | AI-assisted workflows within the console | Not yet available |
Integration Workflows
There are two distinct request patterns depending on which APIs you use — a synchronous flow where the screening result comes back in the same response, and an asynchronous flow where it's delivered later to your webhook.
Flow A — synchronous (Screening API called directly)
(already ingested)
(full name)
in the response
Flow B — asynchronous (ingestion-triggered screening)
The Customer Ingestion API accepts a name_screening_enabled field (defaulting to true when omitted), so ingesting a customer can trigger screening as a side effect rather than requiring a separate call to the Screening API. What isn't yet confirmed in this documentation is the exact delivery mechanism for that result back to your system — likely a webhook, but confirm the specifics with your Fyscaltech integration contact before building against it.
(name_screening_enabled: true)
as a side effect
— confirm with Fyscaltech
Bulk CSV — batch (sits outside both flows)
Bulk CSV uploads are for getting Customer, Customer Account, and Customer Transaction data into the platform in volume, rather than triggering an immediate screening result back to your system. Screening or monitoring against that data happens on the platform's own schedule (see Name Screening's Batch and Delta Screening, and Transaction Monitoring's execution intervals) rather than as a direct response to the upload.
Choosing sync vs. async
| Pattern | Use it when |
|---|---|
| Synchronous (Flow A) | You need the result immediately in your own onboarding flow — e.g. blocking account opening until screening completes |
| Asynchronous (Flow B) | You're already pushing customer records via the Ingestion API and prefer not to poll — results land on your webhook as they complete |
| Batch (Bulk CSV) | You're loading or refreshing large populations, and don't need a per-record result back in real time |
Full request/response detail for both APIs is now documented under Integration Methods. Visual sequence-timing diagrams aren't available yet, but the endpoint paths, payload shapes, and response envelopes above are enough to build against.
Webhooks & Events
A webhook would only be relevant if you're using the Customer Ingestion API's name_screening_enabled flag to trigger screening as part of ingesting a customer record, rather than calling the Screening API directly. Whether delivery actually happens via webhook — versus some other mechanism — isn't confirmed yet; the pattern below is the expected shape, not a confirmed spec.
How it works (expected pattern, not yet confirmed)
- Unlike Bulk CSV, a webhook endpoint would be hosted and owned by you, not Fyscaltech
- Fyscaltech would provide the request format and signature-verification guidelines once finalized
Confirmed event names and payload structures for webhook deliveries haven't been provided yet. What is confirmed: ingestion accepts a name_screening_enabled flag (see Customer Ingestion API), so screening can run as a side effect of ingestion — the exact event/delivery format for that result is what's pending here.
This webhook is only needed for the ingest-then-screen flow through the Customer Ingestion API. If you only use bulk CSV ingestion, or call the Screening API directly for each check, you don't need to set up a webhook at all.
Errors, Limits & Best Practices
Both the Customer Ingestion API and Screening API return the business error codes below alongside their HTTP status.
Business error codes
Business-level error codes sit alongside the HTTP status and identify the specific validation or business rule that failed. Confirmed codes so far, from Customer Ingestion API and Screening API:
| Code | API | HTTP | Meaning |
|---|---|---|---|
BR001 | Customer Ingestion | 400 | Malformed body, empty body, or a required field missing |
SWW01 | Customer Ingestion | 500 | Internal queue/publish failure |
VALIDATION_ERROR | Screening | 400 | Bad or missing customer_name, invalid customer_type, or wrong field types |
CONFLICT | Screening | 409 | Mongo duplicate key |
REDIS_CONNECTION_ERROR | Screening | 503 | Redis config-load connection failure |
REDIS_OPERATION_ERROR | Screening | 500 | Redis config-load operation failure |
DATABASE_QUERY_FAILED | Screening | 500 | Postgres ledger write fails (/screen only) |
INTERNAL_SERVER_ERROR | Screening | 500 | Any unmapped internal error — the underlying message is passed through |
Both APIs share a similar response envelope shape (code + message, with Screening additionally carrying a data field) — check code first for programmatic handling, and treat message as human-readable detail rather than something to match against in logic.
Best practices
Specific guidance (idempotency behavior, retry/backoff recommendations, rate limits) for the Customer Ingestion and Screening APIs hasn't been confirmed yet. The one thing already confirmed: for bulk CSV, check the FT AML console under Data Ingestion to confirm a file was picked up and processed successfully — a successful S3 upload only means the file arrived, not that every row passed validation.
Rate limit thresholds aren't documented yet — confirm current limits with your Fyscaltech integration contact before load-testing against these endpoints.
Deployment Guide
FT AML itself is deployed and operated entirely by Fyscaltech — you never deploy the platform. This section instead covers how your own integration typically progresses across environments, and what changes (or doesn't) between them.
Environments
| Environment | Purpose | Status |
|---|---|---|
| Development | Your own local/dev integration code, pointed at a test dataset | Your responsibility — no FT AML-specific setup beyond credentials |
| Sandbox / Test | A safe environment to validate your integration against FT AML without touching production data | TODO — Information Required — see Testing & Sandbox |
| QA / UAT | Formal pre-production sign-off, typically against the same environment as Sandbox/Test | TODO — Information Required |
| Production | Live customer/transaction data, real screening and alerting | Confirmed — reachable once onboarding is complete |
Because FT AML is hosted, "deploying" on your side means pointing your integration code at the correct credentials/endpoint for each environment above — not deploying any FT AML component. Confirm with Fyscaltech whether sandbox and production use different hostnames, different S3 buckets, or the same infrastructure with logically separated data.
Docker / Kubernetes / your own runtime
Not applicable to FT AML itself. If your own integration code runs in Docker, Kubernetes, or behind IIS/Nginx/Apache, there is nothing FT AML-specific required in that layer beyond outbound HTTPS access (see System Requirements) — treat calling FT AML the same as calling any other external HTTPS API from your existing deployment pipeline.
CI/CD
- Keep S3 credentials and any API credentials in your CI/CD secrets store, never committed to source control — see Security Best Practices → Secrets management
- Consider a CI smoke test that calls the read-only
/bo/screenendpoint on each deploy, to catch connectivity regressions before they reach production — see Testing Guide - If your pipeline generates and uploads CSV files, validate the header row programmatically before upload — a single malformed header rejects the whole file (see Bulk CSV)
Testing & Sandbox
How to validate your integration before it touches real customer data, and a starting set of test cases for each integration method.
Sandbox availability
For Bulk CSV, the same S3 location and console feedback (Data Ingestion job status) apply whether you're testing or in production — there is no separate sandbox bucket documented today, so start with a small file (50–100 rows) to confirm your CSV format is accepted before uploading your full population.
Whether a separate sandbox/test environment exists for the Customer Ingestion and Screening APIs, and what test data it ships with, hasn't been confirmed yet.
Unit & integration testing (your code)
- Unit tests — mock the three HTTPS/S3 calls in your own test suite; there is no FT AML-provided mock server yet, so assert against the request/response shapes documented under Integration Methods.
- Integration tests — run against real FT AML endpoints using the read-only
/bo/screenpath and a disposable test S3 prefix/file, so tests don't create alerts or pollute production-like data unnecessarily.
Smoke testing
A minimal smoke test that exercises all three integration methods end to end:
- Upload a small test CSV file and confirm it moves from
inbox/toprocessed/— see Bulk CSV. - Call
POST /datahub/ingestion/v1/customerwith a test record and confirm a202 Accepted. - Call
POST /riskradar/core/api/v1/bo/screenwith a known test name and confirm a scored result comes back.
API test cases
| # | Test case | Endpoint | Expected result |
|---|---|---|---|
| 1 | Valid customer, all required fields present | POST /customer | 202 Accepted, {"code":"00000","message":"success"} |
| 2 | Missing customer_id | POST /customer | 400, BR001, "customer_id is required" |
| 3 | Malformed JSON body | POST /customer | 400, BR001, "invalid request payload" |
| 4 | Known test name, expect a match | POST /bo/screen | 200, non-empty raw_matches |
| 5 | Empty customer_name | POST /bo/screen | 400, VALIDATION_ERROR, "entity name required" |
| 6 | Valid name, no expected match | POST /screen | 200, low/zero alert_score, no alert raised |
Regression testing
Re-run the API test cases above after any change to your own request-building code, and after Fyscaltech communicates an API change via Changelog & versioning. There is no automated regression suite published by Fyscaltech today — building your own from the test cases above is recommended.
Validation Checklist
After completing setup for any integration method, work through the relevant checks below before considering the integration production-ready.
General
- ✓ Services reachable — a test call to
/bo/screenreturns200with a valid JSON envelope - ✓ Database connected — not directly checkable by you; inferred from a successful
/screencall returning ascreening_id, which requires the Postgres ledger write to succeed - ✓ APIs working — see API test cases, all pass
- ✓ Authentication successful — TODO — Information Required until application-level auth is confirmed, see Authentication
- ✓ Console accessible — an Admin user can log in and see ingested/screened records reflected (Data Ingestion, Alert Manager, Name Screening)
- ✓ Logs generated — TODO — Information Required, see Logging
- ✓ Monitoring active — TODO — Information Required
Per integration method
| Method | Validation |
|---|---|
| Bulk CSV via S3 | File appears in processed/, not rejected/; Data Ingestion console shows the job as completed with an acceptable error-row count |
| Customer Ingestion API | 202 Accepted returned; record visible in the console shortly after (allow for asynchronous consumer lag) |
| Screening API | 200 returned with a populated screening_result; for /screen, a corresponding alert appears in Alert Manager when the score warrants one |
Logging
What's confirmed today about tracing and diagnosing a request, from your side as an external developer.
Request tracing
Responses include an X-Request-Id header — capture and log this on your side for every call. It's the fastest way for Fyscaltech support to locate your specific request in their own logs; see Support → What to include.
Log locations, levels & rotation (platform-side)
Platform-side log locations, retention/rotation policy, and log levels are internal to Fyscaltech's operations and not exposed to integrating developers directly. If you need log evidence for a specific incident, provide the X-Request-Id and timestamp to Fyscaltech support per the Support section.
What to log on your side
- Every request's
X-Request-Id, timestamp, endpoint, and HTTP status - The business error
code(not just HTTP status) from any error response — see Business error codes - For Bulk CSV, the filename and upload timestamp of every file you send, so you can correlate against the console's Data Ingestion job history
customer_id, screening_id) instead, and look records up server-side when you need full detail.Security Best Practices
Practices to follow on your side when integrating with FT AML. General security guidance below is presented as standard practice recommendations, not as a description of FT AML's own internal controls unless explicitly stated as confirmed.
Secrets management
- Store AWS access keys and any API credentials in a secrets manager (e.g. AWS Secrets Manager, HashiCorp Vault) rather than source control or environment files checked into a repository
- Keep credentials on your backend or automation only — never embed them in client-side/browser code, since Bulk CSV credentials and any future API keys are bearer-style secrets
- Rotate credentials periodically and immediately upon suspected exposure; contact Fyscaltech to reissue
Transport & certificates
- Use TLS 1.2 or higher for every call to FT AML endpoints and S3 — see System Requirements
- Validate the server certificate normally (don't disable certificate verification in your HTTP client, even for testing)
Data handling
- Treat customer records (names, addresses, identity numbers, financial data) as personal data throughout your own pipeline, not only within FT AML
- Never send data files by email or shared drive — use only the designated S3 paths (see Bulk CSV)
- Apply the logging guidance under Logging → What to log on your side to avoid persisting personal data in plaintext logs unnecessarily
Access control & least privilege
- Scope AWS IAM policies to the minimum required — your own
<client-id>prefix only, not the whole bucket (this is enforced by Fyscaltech-issued credentials by default) - Limit who on your team can manage API-key-adjacent permissions to your organization's Admins in the FT AML console
Vulnerability reporting
A dedicated security disclosure process/contact hasn't been published yet. Until then, report suspected security issues through the same Support channel, flagged clearly as a security concern.
Troubleshooting & FAQ
Common issues
| Problem | Possible cause | Resolution | Commands | Where to check |
|---|---|---|---|---|
| Bulk CSV file stuck in Processing | Encoding or column issue in the source file | Re-export as UTF-8 with the exact header; re-upload; escalate to Fyscaltech if it doesn't clear | aws s3 ls s3://<bucket>/<client-id>/jobs/ | Console → Data Ingestion |
| Whole CSV file rejected | Header row doesn't match exactly (spelling, order, case, extra spaces) | Copy the header line verbatim from Bulk CSV | — | rejected/customer/ or rejected/account/ in S3 |
| Individual CSV rows rejected | REQUIRED, INVALID_ENUM, INVALID_DATE, DUPLICATE, MAX_LENGTH_EXCEEDED, or COLUMN_COUNT_MISMATCH — see Common problems | Fix the specific rows named in the error report and re-upload only those rows in a new file | — | jobs/<run>/errors/ in S3 |
| Screening API returns no matches for a known name | Name submitted differs from the registered form, or no watchlist entry exists | Confirm exact spelling; remember matching is on full name only today — not date of birth, address, or citizenship | — | Re-run via /bo/screen to compare |
| Customer Ingestion call succeeds but no screening result appears | name_screening_enabled not set as expected, or delivery mechanism not yet wired on your side | Confirm the field was sent as intended (default is true); check Alert Manager directly — result-delivery mechanism isn't confirmed yet, see Webhooks & Events | — | Console → Alert Manager / Name Screening |
| Accounts silently not loaded | Their customer hasn't reached the platform yet, or was itself rejected | Upload the customer file first and confirm it wasn't rejected before uploading accounts | aws s3 ls s3://<bucket>/<client-id>/processed/customer/ | S3 processed/ vs rejected/ |
| Connection timeout calling any API | Outbound firewall rule missing — see System Requirements | Confirm HTTPS (443) outbound is allowed to the FT AML host | curl -v https://<host>/riskradar/core/api/v1/bo/screen | Your own network/firewall logs |
Frequently asked questions
Can we use more than one integration method at once?
Yes — most institutions use Bulk CSV for the initial customer population, then the Customer Ingestion API and/or Screening API for ongoing, real-time updates.
Do we need a webhook if we only use the Screening API?
No. Calling the Screening API directly returns the result in the same response — a webhook is only needed for the ingest-then-screen flow via the Customer Ingestion API.
Is there a sandbox we can test against before going live?
Not confirmed yet — see Testing & Sandbox.
Can the Screening API match on more than full name?
Not currently — it supports full name matching only. Additional matching fields (date of birth, address, citizenship) are available through Manual Screening in the console today.
Where do we find upcoming API changes before they land?
Keep a point of contact with the Fyscaltech integration team, and check Resources & Changelog once a public changelog is published.
What happens if I upload a Bulk CSV file with the wrong header?
The entire file is rejected and moved to rejected/customer/ or rejected/account/ — no rows are processed. Copy the header line exactly from Bulk data ingestion (CSV via S3) rather than retyping it.
Is the Customer Ingestion API synchronous or asynchronous?
Asynchronous. It returns 202 Accepted immediately after validating and publishing an event — the actual database write happens moments later via a background consumer, not within the request. See Customer Ingestion API.
Do I need to install anything to integrate with FT AML?
No. FT AML is a hosted platform — there's no server software to install on your side. See Installation Guide for the (lightweight) one-time setup that applies instead.
Glossary
Terms and field names used throughout this Developer Portal, defined for anyone integrating for the first time.
| Term | Meaning |
|---|---|
| AML / CTF | Anti-Money Laundering / Counter-Terrorist Financing |
| KYC | Know Your Customer — the due-diligence fields carried on a Customer Record (kyc_level, kyc_level_description, kyc_authorized_signatory_name) |
| PEP | Politically Exposed Person — surfaced on a Customer Record as pep_flag |
customer_type | Whether a record is Individual or Corporate (Customer Ingestion API) / Individual or Entity (Screening API) — the two APIs use slightly different values for this field |
risk_level / risk_score | The customer's assessed AML risk, as a category (LOW/MEDIUM/HIGH) and a numeric score |
sanctions_status | Whether a customer has a known sanctions hit on file, independent of a live Screening API call |
| Watchlist | The sanctions/PEP/adverse-media data source the Screening API matches against |
| Full name screening | Matching based on the customer's full name — currently the only field the Screening API supports |
alert_score / alert_category | The Screening API's match confidence (0–100) and its banded severity (e.g. HIGH) |
entity_key / screening_id | Identifiers in a Screening API response used to trace a specific screening run |
| Bulk ingestion | Loading data via CSV file upload to S3, as opposed to the record-by-record Customer Ingestion API |
| MLRO | Money Laundering Reporting Officer — approves SAR/STR filings |
| SAR / STR | Suspicious Activity / Transaction Report filed with regulators |
Additional terms will be added here as more of the platform's API surface is confirmed.
Developer Community
A space for developers integrating with FT AML to ask questions, share patterns, and hear from each other — not just from Fyscaltech directly.
This section is a placeholder — content, links, and setup for a developer community (forum, Slack/Discord, discussion board, or similar) will be added here once provided.
Resources & Changelog
Downloadable and reference materials to speed up integration work. Anything not yet available will be published soon once received from technical team.
Postman Collection
A ready-to-import collection covering the Customer Ingestion and Screening APIs. Will be published soon once received from technical team.
PendingOpenAPI Specification
Machine-readable spec for generating clients or importing into your own API tooling. Will be published soon once received from technical team.
PendingCSV Templates
The exact Customer and Account file headers are already documented in full under Bulk CSV via S3 — copy them directly from there.
AvailableRelease Notes
A running log of platform and API changes. Will be published soon once received from technical team.
PendingSDKs
Official client libraries for common languages, planned for a future release.
FutureFyscaltech Integration Team
The most reliable resource today — see Support for contact details.
Changelog & versioning
As the Customer Ingestion and Screening APIs move from onboarding-provided specifications toward a stable published reference, changes will be communicated directly by the Fyscaltech integration team. If you're integrated against either API, keeping a point of contact with the team (see Support) is the most reliable way to hear about upcoming changes before they land.
A formal versioning policy and public changelog will be published here once the API reference itself is finalized.
Support
- In-app: Homepage > Help & Support
- Email: hello@fyscaltech.com
- Phone: +65 8080 5424
- Headquarters: Singapore · 68 Circular Road
- Account-level issues (API key provisioning, permissions) — contact your organization's Admin
What to include when you contact us
To help us resolve integration issues quickly, please include: the environment (sandbox/production), the endpoint and HTTP method, the X-Request-Id from the response headers if available, and a timestamp of when the issue occurred.
Thank you for building on FT AML.
Appendix
Reference material collected in one place: acronyms, configuration templates, and sample payloads — each cross-referenced back to its full documentation elsewhere in this guide rather than duplicated in full.
Acronyms
| Acronym | Meaning |
|---|---|
| AML | Anti-Money Laundering |
| CTF | Counter-Terrorist Financing |
| KYC | Know Your Customer |
| PEP | Politically Exposed Person |
| MLRO | Money Laundering Reporting Officer |
| SAR / STR | Suspicious Activity / Transaction Report |
| API | Application Programming Interface |
| JSON | JavaScript Object Notation |
| CSV | Comma-Separated Values |
| S3 | Amazon Simple Storage Service |
| SNS / SQS | Amazon Simple Notification Service / Simple Queue Service |
| TLS | Transport Layer Security |
| IAM | Identity and Access Management (AWS) |
Glossary
The full term-by-term glossary lives in its own section — see Glossary for every field name and platform term used throughout this guide.
References & external links
- FT AML product page
- FT AML User Guide — the console/end-user reference, as distinct from this Developer Guide
- Fyscaltech integration team — see Support
Configuration templates
Copy-paste-ready header rows for Bulk CSV — full column-level reference is under Bulk data ingestion (CSV via S3).
Customer file header (52 columns):
CUSTOMER_ID,CUSTOMER_TYPE,CUSTOMER_NAME,STATUS_CODE,CUSTOMER_SEGMENT_CODE,CUSTOMER_SEGMENT_NAME,RISK_LEVEL,RISK_SCORE,KYC_LEVEL,KYC_LEVEL_DESCRIPTION,PEP_FLAG,SANCTIONS_STATUS,SOURCE_OF_FUNDS,KYC_AUTHORIZED_SIGNATORY_NAME,ONBOARDING_DATE,ONBOARDING_CHANNEL,STREET,CITY,PROVINCE_REGION,ADDRESS_COUNTRY,POSTAL_CODE,CITIZENSHIP_COUNTRY,RESIDENCE_OPERATION_COUNTRY,BIRTH_INCORPORATION_COUNTRY,CUSTOMER_CONTACT_NO,ACCOUNT_TYPE,ACCOUNT_OPEN_DATE,ACCOUNT_AGE_DAYS,EXPECTED_MONTHLY_SPEND,EXPECTED_MONTHLY_SPEND_CURRENCY,EXPECTED_TXN_FREQUENCY,PURPOSE_OF_ACCOUNT,FIRST_NAME,MIDDLE_NAME,LAST_NAME,GENDER,DATE_OF_BIRTH_OR_INCORPORATION,CUSTOMER_AGE,CUSTOMER_ALIASES,CUSTOMER_ID_NO,CUSTOMER_ID_TYPE,CUSTOMER_ID_EXPIRY_DATE,CUSTOMER_ID_ISSUE_DATE,CUSTOMER_ID_COUNTRY,DESIGNATION,EMPLOYER_NAME,DECLARED_INCOME,INCOME_CURRENCY,NATURE_OF_BUSINESS,COUNTRY_OF_OPERATIONS,CREATED_AT,UPDATED_AT
Account file header (13 columns):
ACCOUNT_NUMBER,CUSTOMER_ID,ACCOUNT_TYPE,ACCOUNT_NAME,ACCOUNT_CURRENCY_CODE,ACCOUNT_BANK_NAME,ACCOUNT_BANK_COUNTRY,ACCOUNT_STATUS,ACCOUNT_HOLDING_TYPE,SIGNATORY_CUSTOMER_ID,SIGNATORY_NAME,CREATED_AT,UPDATED_AT
Sample requests & responses
Customer Ingestion API — full reference at Customer Ingestion API:
POST /datahub/ingestion/v1/customer
Content-Type: application/json
{ "customer_id": "CUST-1001", "customer_name": "Jane Doe", "customer_type": "Individual" }
202 Accepted
{ "code": "00000", "message": "success" }
Screening API — full reference at Screening API:
POST /riskradar/core/api/v1/screen
Content-Type: application/json
{ "customer_name": "Jane Doe", "customer_type": "Individual" }
200 OK
{ "code": "00000", "message": "Success", "data": { "screening_result": { "alert_score": 87.5, "alert_category": "HIGH" } } }
Documentation standards used in this guide
- Confirmed technical detail is stated directly; anything not yet confirmed by the technical team is marked with a "Will be published soon" callout or a TODO — Information Required tag, rather than guessed at.
- Existing screenshots and diagrams from the original guide are preserved as-is; new diagrams use the same flow-box/flow-arrow visual pattern already established in Integration Workflows.
- Every numbered procedure includes an objective, the exact commands, expected output, and a validation step, consistent with Installation Guide.