4.0 API and Integration
GTRSafePro provides a RESTful API for seamless integration into existing compliance technology stacks. The platform
exposes two public integration surfaces, both served at https://openapi.gtrsafepro.com and authenticated with an API
key and an Ed25519 request signature:
- Address Screening (
/onchain-analysis/**) — synchronous address risk screening for programmatic, machine-to-machine callers. - Address Labeling (
/onchain-labeling/**) — lightweight entity attribution for addresses where a full risk score is not needed.
Address screening is synchronous: the response returns the completed screening result. Address labeling is served by a separate labeling service. Both services share the same authentication scheme (§4.1) and the same response envelope (§4.5).
4.1 Authentication
API Key and Ed25519 Signature
All public API endpoints authenticate machine callers with an API key and an Ed25519 signature over a canonical payload. The server stores only the 32-byte public key — never the decryptable secret.
| Header | Required | Description |
|---|---|---|
X-API-KEY | Yes | API key access key (the accessKey shown when the key is created in the web console). |
X-TIMESTAMP | Yes | Epoch milliseconds. Rejected when |now − timestamp| > recvWindow. |
X-SIGNATURE | Yes | base64url-no-pad Ed25519 signature of the canonical payload. |
X-RECV-WINDOW | No | Timestamp tolerance window in ms. Default 5000, maximum 60000. |
Canonical signing payload — the five lines below are concatenated with \n and signed with the Ed25519 private key.
All bytes are UTF-8.
timestamp
METHOD
path
sortedQuery
sha256_hex(body)
timestamp— the same epoch-millis value sent inX-TIMESTAMP.METHOD— uppercase HTTP method (POST,GET, ...).path— the full public URL path of the request, exactly as it appears after the hostname, with a single leading slash (e.g./onchain-analysis/v1/address/sync). Do not include the query string, and do not modify the path before signing.sortedQuery— URL-decodedkey=valuepairs sorted lexicographically by key, then value, joined by&. Empty string when there is no query string.body— raw request body bytes (SHA-256 hex). An empty body hashes the empty string.
API keys are created from the GTRSafePro web console (Account → API Keys). Creation returns the accessKey and the
PKCS#8 Ed25519 privateKey exactly once — store the private key securely; it cannot be retrieved again. Scope is
enforced per key: the key's apiType (Address / Transaction / Customer) must match the endpoint's required scope.
A smoke-test endpoint GET /onchain-analysis/v1/ping echoes the authenticated principal (accessKey, apiKeyId, apiType,
serverTimestamp) and is the recommended first call to verify a signing implementation.
4.2 Address Screening
Endpoints
Base path: https://openapi.gtrsafepro.com/onchain-analysis.
| Method | Endpoint | Description |
|---|---|---|
| POST | /onchain-analysis/v1/address/sync | Synchronous address screening — blocks until scoring completes. |
| GET | /onchain-analysis/v1/address/networks | Supported blockchain networks for address screening. |
Responses use the platform response envelope — see §4.5.
Request — AddressLookupRequestV3
| Field | Type | Description |
|---|---|---|
hash | String | The blockchain wallet address to screen (≤256 chars). |
network | String | The blockchain network code (e.g. BTC, ETH, BSC). Use GET /onchain-analysis/v1/address/networks for the supported list. |
Identifiers are validated by LookupInputValidator: non-blank, ≤256 chars, and must not contain any of
! @ # $ % ^ & * ( ).
Response — AddressLookupResult
| Field | Type | Description |
|---|---|---|
metaInfo | LookupMetaInfo | History id, analysedBy, analysedAt, lookupType. |
subjectInfo | Subject | The screened hash, network, subjectType (address). |
statusInfo | StatusInfo | processStatus, processStatusId, error. |
walletOverview | AddressOverview | Address-level risk, entity, categories, sources, balances. |
addressSummary | List<AddressSummary> | Per-token balance and in/out totals. |
counterpartySummary | CounterpartySummary | Direct exposure by category and by entity. |
tags | List<TagDetailV3> | Per-tag risk weight and confidence score with reasoning. |
alertSummary | AlertSummary | Open / closed / escalated alerts and address-level risk score. |
customer | Customer (nullable) | The caller's customer this address is linked to, if any. |
AddressOverview
| Field | Type | Description |
|---|---|---|
riskScore | BigDecimal | Address-level risk score (0–10). |
riskLevel | String | Risk level label (Critical / High / Medium / Low). |
entity | String | Attributed entity name. |
categoryId | Long | Primary entity category id. |
categories | String[] | Entity category labels. |
sourceId | Long | Primary attribution source id. |
sources | String[] | Attribution source labels. |
balances | List<Balance> | Per-asset balance and USD value. |
Balance
| Field | Type | Description |
|---|---|---|
asset | String | Asset ticker. |
icon | String | Asset icon URL. |
amount | BigDecimal | On-chain amount. |
usdValue | BigDecimal | USD value at the transaction date. |
AddressSummary
| Field | Type | Description |
|---|---|---|
token | String | Asset ticker. |
icon | String | Asset icon URL. |
balance | BigDecimal | Current balance. |
totalIncomingValue | BigDecimal | Lifetime incoming USD value. |
totalOutgoingValue | BigDecimal | Lifetime outgoing USD value. |
earliestTransaction | LocalDateTime | First seen transaction (yyyy-MM-dd HH:mm:ss). |
latestTransaction | LocalDateTime | Most recent transaction (yyyy-MM-dd HH:mm:ss). |
CounterpartySummary
| Field | Type | Description |
|---|---|---|
incomingExposureByCategory | List<Exposure> | Incoming direct exposure grouped by category. |
outgoingExposureByCategory | List<Exposure> | Outgoing direct exposure grouped by category. |
ExposureByEntity | List<ExposureByEntity> | Direct exposure grouped by counterparty entity. |
Exposure: categoryId, categories, totalValue, directExposure, directExposurePercentage.
ExposureByEntity: entityName, categoryId, categories, incomingDirectExposure, outgoingDirectExposure.
AlertSummary / Alert — AlertSummary carries the address-level riskScore plus openAlerts, closedAlerts,
escalatedAlerts lists. Each Alert includes id, queryKey, accountId, lookupType, hash, network,
ruleId, ruleName, ruleType, riskScore, lastestTxTime, alertDate, alertStatus, reviewedBy.
Customer — id (Long), name (String); null when the address is not linked to one of the caller's customers.
4.5 Response Envelope & Errors
Every public API response uses the platform response envelope:
| Field | Type | Description |
|---|---|---|
status | String | OK on success, ERROR on failure. |
type | String | Error class — GENERAL (business), SYS (system), or VALID (input). |
code | String | Business code. Success is 000000000. |
data | T | The response payload; shape depends on the endpoint. |
errorData | Object | Additional error context (present on failure). |
params | Object[] | Message interpolation parameters. |
subData | Object | Reserved. |
Branch on status == "OK" — do not inspect individual fields of an error response other than
code/errorData for diagnostics. Both the screening service (§4.2) and the labeling service (§4.8)
return this same envelope.
- Authentication failures — invalid or missing credentials return HTTP
401with{"code":401,"reason":"<rejection reason>"}(e.g.missing-auth-header,openapi-rejected). - Rate limiting — excessive request volume returns a too-many-requests response.
- Input validation — identifiers that are blank, >256 chars, or contain any of
! @ # $ % ^ & * ( )are rejected with aVALIDerror.
4.6 Integration Features
- API Key Management — generate, list, and revoke Ed25519 API keys from the GTRSafePro web console (Account → API Keys). The private key is returned once at creation.
- IP Allow-List — access to the public API is restricted to the IP allow-list registered for your account. To register or update your allow-list, send an IP allow-list request email to customerservice@globaltravelrule.com.
- Role-Based Access — Admin and Analyst roles with granular permissions (see §2.2 Roles and Permissions).
- Response times — sub-2-second response times for synchronous address screening, supporting real-time decisioning.
4.7 Caveats
- Network coverage — the networks supported for address screening are returned by
GET /onchain-analysis/v1/address/networks; screening a network outside that list is rejected. - Scope enforcement — the API key's
apiTypemust match the endpoint's required scope (§4.1). A key minted for one scope cannot call another scope's endpoints.
4.8 Address Labeling
Address Labeling provides access to the platform's attribution data — given an address and a network, it returns the attributed entity and its category without running a full risk screening. Use it for lightweight enrichment (labelling counterparties in a ledger, tagging withdrawal destinations) where a risk score is not needed.
These endpoints are served by the labeling service, a separate service from the screening service behind §4.2. They sit under a different base path and take an unwrapped request body; the response envelope is the same shape described in §4.5.
Endpoints
Base path: https://openapi.gtrsafepro.com/onchain-labeling.
| Method | Endpoint | Description |
|---|---|---|
| POST | /onchain-labeling/address/label/single | Resolve the entity and category for a single address. |
| POST | /onchain-labeling/address/label/batch | Resolve the entity and category for a list of addresses. |
Request — AddressEntitySingleRequest
| Field | Type | Description |
|---|---|---|
sceneCode | String | Required. The scene code provisioned for your account. |
address | String | Required. The blockchain address to resolve. |
network | String | Required. The blockchain network code the address belongs to (e.g. BTC, ETH). |
{
"sceneCode": "<your scene code>",
"address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
"network": "BTC"
}
Request — AddressEntityBatchRequest
| Field | Type | Description |
|---|---|---|
sceneCode | String | Required. The scene code provisioned for your account. |
addressList | String[] | Required. The blockchain addresses to resolve — maximum 100 per call. |
network | String | Required. The blockchain network code applied to every address in addressList. |
{
"sceneCode": "<your scene code>",
"addressList": [
"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
"3FZbgi29cpjq2GjdwV8eyHuJJnkLtktZc5"
],
"network": "BTC"
}
A batch call resolves one network at a time — to cover several networks, issue one call per network. Split lists longer than 100 addresses across multiple calls.
Response — AddressEntityResponse
/single returns one AddressEntityResponse in data; /batch returns a List<AddressEntityResponse>.
| Field | Type | Description |
|---|---|---|
address | String | The queried address, echoed back. |
network | String | The queried network, echoed back. |
entity | String | Attributed entity name — the exchange, service, or actor that controls the address. |
category | String | Entity category label. |
updateTime | String | When the attribution was last updated — yyyy-MM-dd HH:mm:ss.SSSSSS (microsecond precision), e.g. 2026-02-02 21:40:32.345000. |
Addresses with no attribution are skipped in the /batch response, so the returned list is often shorter
than addressList and its entries do not correspond positionally to the request. Match results back to your input by
the address field, and treat any address missing from the response as unlabelled.
Response envelope
The labeling service returns the platform response envelope described in §4.5 — branch on status == "OK". On
success, data carries one AddressEntityResponse (single) or a List<AddressEntityResponse> (batch). Note that
the OpenAPI spec marks no request field as required even though sceneCode, address / addressList, and
network are — a malformed request is rejected at runtime, not by spec-generated clients.