
# Risk Intelligence quickstart

This is the shortest complete path from a Sandbox key to a useful transaction
decision. It runs on your backend with the official Node.js SDK.

Prefer a copy-ready HTTP example? Open **Fraud Monitoring → Integration guide** for
cURL, Node.js, Python, Go and Coding agent options, a live request receipt, and a signed
webhook verifier. See [Crypto operations](/docs/crypto-operations) for deposit feeds,
the Crypto Provider Directory and address-book integration. No SDK changes are required for HTTP.

To act on screening or device/face findings, subscribe to `screening.match`,
`risk.signal.created` and `alert.created`. Match the event's
`subject.externalUserId` to your customer, verify the signature and deduplicate by
event ID. Review findings in **Investigations → Review Queue** before deciding whether
to restrict access. Myaza does not directly block accounts in your application.
See [Risk Intelligence webhooks](/docs/webhook-risk-intelligence) for the contracts.

## 1. Create a secret Sandbox key

Open **Developers → API Keys**, select **Sandbox**, then create a **Secret** key.
Copy the full `sk_test_...` value when it appears. It is shown only once.

Store it in your shell or secrets manager:

```bash
export MYAZA_SECRET_KEY="sk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

Risk Intelligence is server-side. Do not put this key in browser or mobile code,
and do not use a publishable `pk_...` verification key.

## 2. Install the SDK

```bash
npm install @myazahq/trust-sdk
```

The package is ESM-only and requires Node.js 20 or newer.

## 3. Submit one transaction

Create `risk-demo.mjs`:

```js
import { Myaza } from '@myazahq/trust-sdk';

const myaza = new Myaza({
  apiKey: process.env.MYAZA_SECRET_KEY,
  environment: 'sandbox',
});

const runId = crypto.randomUUID();
const assessment = await myaza.transactions.create({
  externalActivityId: `demo-activity-${runId}`,
  subject: { type: 'individual', externalUserId: `demo-customer-${runId}` },
  occurredAt: new Date().toISOString(),
  transaction: {
    externalTransactionId: `demo-transfer-${runId}`,
    assetClass: 'fiat',
    direction: 'outbound',
    amount: '12500.00',
    currency: 'NGN',
    transactionType: 'bank_transfer',
  },
}, { idempotencyKey: `demo-transaction-${runId}` });

console.log({
  activityId: assessment.activityId,
  transactionId: assessment.transactionId,
  outcome: assessment.summary?.outcome,
  reason: assessment.summary?.reason,
  nextAction: assessment.summary?.nextAction,
});
```

Run it:

```bash
node risk-demo.mjs
```

## 4. Interpret the result

Read `summary` first:

| Outcome | What your backend should do |
|---|---|
| `allow` | Continue. No operator action is required. |
| `review` | Hold the action and send it to your review workflow. |
| `block` | Stop the action. Keep the decision and evidence for investigation. |

The reason, score and next action explain the current decision. Detailed matched
rules, screening evidence and billing remain available on the same response.

## 5. See it in the dashboard

Open **Risk Intelligence → Fraud Monitoring → Transactions** and search for the
`externalTransactionId` printed by the script. The dashboard and API show the
same decision and evidence.

## Optional: receive the decision by webhook

Create an endpoint under **Developers → Webhooks** and subscribe to
`fraud.transaction.assessed`. Verify the exact raw request body with the SDK
before parsing or applying side effects. See [Webhooks](https://trust.myaza.co/documentation/webhooks/markdown) for the receiver
example, retry model and replay protection.

## Assess or monitor an existing customer

Customer risk assessments and monitoring subscriptions use a Myaza Entity ID.
Upsert the customer once using your stable external reference, then use the
returned `entityId`. This is the supported bootstrap path for customers already
verified by your own KYC system.

```js
const customer = await myaza.entities.upsert({
  externalUserId: 'customer-123',
  type: 'INDIVIDUAL',
  // Assert this only after your own KYC has verified the customer.
  kycProvenance: 'EXTERNAL_VERIFIED',
  kycSource: 'your_kyc_system',
  profile: {
    fullName: 'Amina Bello',
    dateOfBirth: '1992-04-18',
    nationality: 'NG',
  },
}, { idempotencyKey: 'entity:customer-123:v1' });

const risk = await myaza.riskAssessments.create({
  subject: { type: 'individual', id: customer.entityId },
  checks: ['sanctions', 'pep', 'adverse_media'],
  sandboxScenario: 'SAFE',
}, { idempotencyKey: 'risk-assessment:customer-123:v1' });
```

Use `myaza.entities.get('customer-123')` to look the Entity up later. If the
customer is not verified yet, complete your normal verification flow before
asserting verified provenance. Transactions remain the simplest first call
because they accept `subject.externalUserId` directly.

Next, [keep the customer under continuous review](https://trust.myaza.co/documentation/monitoring-policies/markdown).

## Before your first Travel Rule transfer

Travel Rule evaluates crypto transfers against your organisation's active policy
version. Create that policy once in **Risk Intelligence → Rules & Policies →
Fraud rules → Travel Rule**: install a library rule or create one, save the
draft, then select **Publish draft**. Any authorised Travel Rule manager can publish their own draft directly. Later edits stay in draft until published and never
rewrite earlier transfer results.

After the policy is active, [send a crypto transfer through Travel Rule](https://trust.myaza.co/documentation/travel-rule/markdown).
For a deterministic first test, add the top-level field
`sandboxScenario: 'TRAVEL_RULE_MISSING_BENEFICIARY'` to the transaction request.
That explicit fixture is non-billable and Sandbox-only; remove it in Production.
An ordinary Sandbox crypto request uses configured pricing and is billable.
